ピクルスのビット


19

Pythonのpickleモジュールはシリアル化に使用され、後で再構築できるようにオブジェクトをダンプできます。このため、pickleは単純なスタックベースの言語を使用します。

物事を単純にするために、この言語の小さなサブセットを扱います。

(              Push a mark to the stack
S'abc'\n       Push a string to the stack (here with contents 'abc')
l              Pop everything up to the last mark, wrapping all but the mark in a list
t              Pop everything up to the last mark, wrapping all but the mark in a tuple
.              Terminate the virtual machine

あなたの仕事は、言語のこのサブセットを実装することです。これ\nは文字通り改行であり、改行は実際に言語にとって重要であることに注意してください。

GolfScriptまたはCJam状の言語に精通した者のために、(そしてl/t同様に動作[し、]それぞれ。

入力

物事を単純にするために、入力は常に有効です。特に、入力について次のことを想定できます。

  • 文字列は小文字とスペースのみで構成され、[a-z ]常に一重引用符を使用します。
  • 余分な文字はなく、すべての指示は上記のとおりです。たとえば、これは、文字列の後にのみ改行が発生することを意味します。
  • すべての前にl/t一致があり、すべての後に一致があります。また、少なくとも1つあります。((l/t(
  • が1つだけあり.、常に最後の文字になります。

コマンドライン、STDIN、または関数引数を介して入力を取得できます。必要に応じて、複数行の文字列ではなく単一の改行エスケープ文字列を使用できますが、回答でこれを指定してください。

出力

出力は、最終オブジェクトの表現であり、STDOUTに出力されるか、stringとして返されます。具体的には:

  • 文字列は、コンテンツを挟む一重引用符の開閉によって表されS'abc' -> 'abc'ます。Pythonで許可されていても、このチャレンジに二重引用符を使用することはできません。

  • リストは、で囲まれたカンマ区切りの要素によって表されている[](例えば、['a','b','c']タプルはコンマで区切られた要素によってrepsentedている間に囲まれた、) ()(例えば、('a','b','c'))。

  • スペースは関係ありません('a', 'b', 'c' )。たとえば、大丈夫です。
  • 右大括弧の前にコンマを置くことはできません。これは、ほとんどの言語で物事を簡単にするためにPython構文規則と意図的に異なることに注意してください。また、単一要素のタプルがどのように表されるかにより、Python挑戦、我々は必要('a')とは反対に('a',))。

上記のテキストは手ごわいように思えるかもしれませんが、次の例で少しわかりやすくします。

(l.

可能な出力: []

(t.

可能な出力: ()

(S'hello world'
l.

可能な出力: ['hello world']

(S'string one'
S'string two'
S'string three'
t.

可能な出力: ('string one', 'string two', 'string three')

(S'a'
(S'b'
S'c'
lt.

可能な出力: ('a',['b','c'])

((S'a'
S'b'
(lS'c'
t(S'd'
tl.

可能な出力: [('a', 'b', [], 'c'), ('d')]

((S'a'
((S'b'
t(S'c'
lS'd'
(((ltlS'e'
S'f'
lS'g'
tl.

可能な出力: [('a',[('b'),['c'],'d',[([])],'e','f'],'g')]

ルール

  • これはであるため、最小バイトのコードが優先されます。
  • Pythonのピクルスで動作するように設計された機能は許可されていません。

セキュリティに関する注意:実際のコードでは、信頼できるソースからのみピクルスを外します。さもないと、cos\nsystem\n(S'rm -rf'\ntR.意外なサプライズが発生する可能性があります


S'abc'\nプッシュしますabc'abc'
電卓

回答:


4

CJam、63

q{"Slt 1:T;L ]',*'[\+']+ ]',*'(\+')+ [
 0:T; C+"35/T=S/(C#=~}fC

オンラインで試す

説明:

q        read the input
{…}fC    for each character C in the input
  "…"    push that long string, containing code to handle various cases
  35/    split it into (two) parts of length 35
  T=     get the T'th part; T is 1 when parsing a string and 0 otherwise
          (T is initially 0 by default)
  S/     split by space into an array of strings
  (      take out the first item (containing special characters to check)
  C#     find the index of C in that string
  =      get the corresponding string from the array
          (when C is not found, # returns -1 which gets the last array item)
  ~      execute that string

さまざまなコードの長い文字列。各パーツには、チェックする文字がいくつかあり、各文字を処理するブロックとデフォルトのケースがあります。

最初の部分: Slt 1:T;L ]',*'[\+']+ ]',*'(\+')+ [

Slt      special characters to check
######## first block, corresponding to character 'S'
1:T;     set T=1, causing the next characters to be processed with the 2nd part
L        push an empty string/array, which will be used to collect the string
######## second block, corresponding to character 'l'
]        end array
',*      join with commas
'[\+     prepend a '['
']+      append a ']'
######## third block, corresponding to character 't'
]        end array
',*      join with commas
'(\+     prepend a '('
')+      append a ')'
######## last block, corresponding to other characters (practically, '(' and '.')
[        start array

第二部: (newline) 0:T; C+

newline  special characters to check (only one)
######## first block, corresponding to newline
0:T;     set T=0, switching back to the first part
######## last block, corresponding to any other character (including apostrophe)
C+       append the character to the collecting string

3

Perl、149バイト

私はこれが悪い試みであるという悪い気持ちを持っていますが、ここに行きます:

$/=$,;$"=",";@s=[];/^\(/?$s[@s]=[]:{$p=/S(.*')/?$1:/l|t/?($l="@{pop@s}")|/l/?"[$l]":"($l)":0,push@{$s[-1]},$p}for<>=~/([(lt]|S.*?\n)/g;print$s[0][0];

スクリプトはファイルに保存する必要があり、STDINから入力を受け取ります。

説明:

# Set the input record separator to undef so that <> reads all lines at
# once
$/=$,;
# Ensure that elements of lists printed in quotes are separated by commas
$"=",";

# The stack. Initialise the bottom element with an empty array
@s=[];

# Tokens are extracted in the for loop a few lines below. Copied here for
# clarity: Read the entire input and iterate over all valid tokens of the
# pickle language
# for <>=~/([(lt]|S.*?\n)/g;
# the token is a mark - push an empty array to the stack
/^\(/ ? $s[@s]=[]
      # token is a string, push it inside the stack top
      : {$p=/S(.*')/ ? $1
                     # otherwise, remove the top and create list or tuple
                     # from it and push it inside the top element
                     : /l|t/ ? ($l="@{pop@s}") | /l/ ? "[$l]"
                                                     : "($l)"
                             : 0 # dummy value
                             # pushing of the string/list/tuple actually
                             # happens here
                             , push@{$s[-1]},$p} 
# read the entire input at once and iterate over all valid tokens
for <>=~/([(lt]|S.*?\n)/g;

# in the end, the bottom element of the stack will be an array with just one
# element which is the string representation of the object
print$s[0][0];

0

> <>、88バイト

^"][">}r]
~rl?!;o11.
^0\!\
 &</\?[1&~?=1l","
 1/\ii:"'"=?v44.
>i9%0$.     >r]i~


 ")("\

ジャンプで楽しい!関係する5つの主要なコマンド、mod 9のASCIIコードは次のとおりであるという事実を使用します。

S -> 2
l -> 0
t -> 8
( -> 4
. -> 1

これにより、各操作を独自の行で処理し、直接ジャンプすることができます。また、必要な文字でラップする前に、スタックのスタックを使用して、各文字列とネストされたリスト/タプルを個別に構築します。


うまくいきましたが、残念なことに、ほとんどのテストケースで正しい出力が得られないようです(ブラケットが間違った方法であるように思われます)
-Sp3000

0

JavaScript(ES6)、199バイト

s=>(q=x=>(o=[],x.slice(0,-1).map(v=>o=[...o,v.map?q(v):`'${v}'`]),x.pop()<"m"?`[${o}]`:`(${o})`),q(eval(s[r="replace"](/\(/g,"[")[r](/[tl](?![\w ]+'\n)/g,"'$&'],")[r](/S('.+')/g,"$1,").slice(0,-2))))

入力に対していくつかの正規表現置換を実行して有効なJSコードに変換し、それを解析します。

テストスニペット

f=
s=>(q=x=>(o=[],x.slice(0,-1).map(v=>o=[...o,v.map?q(v):`'${v}'`]),x.pop()<"m"?`[${o}]`:`(${o})`),q(eval(s[r="replace"](/\(/g,"[")[r](/[tl](?![\w ]*'\n)/g,"'$&'],")[r](/S('.+')/g,"$1,").slice(0,-2))))
<select oninput="I.value=this.selectedIndex?this.value.replace(/\\n/g,'\n'):'';O.innerHTML=this.selectedIndex?f(I.value):''"><option>---Tests---<option>(l.<option>(t.</option><option>(S'hello world'\nl.<option>(S'string one'\nS'string two'\nS'string three'\nt.<option>(S'a'\n(S'b'\nS'c'\nlt.<option>((S'a'\nS'b'\n(lS'c'\nt(S'd'\ntl.<option>((S'a'\n((S'b'\nt(S'c'\nlS'd'\n(((ltlS'e'\nS'f'\nlS'g'\ntl.</select><br>
<textarea rows=10 cols=20 id=I></textarea><br><button onclick="O.innerHTML=f(I.value)">Run</button><br><pre id=O></pre>


0

ジュリア+ ParserCombinator.jl 306 240

私の最新の改訂セットでは、純粋なジュリアのソリューションが短くなるとは考えていません。

using ParserCombinator
v=join
j(t)=v(t,",")
a=Delayed()
s=E"S'"+Star(p".")+Drop(Equal("'\n"))|>x->"'$(v(x))'"
i=Star(a)|E""
l=E"("+i+E"l"|>x->"[$(j(x))]"
t=E"("+i+E"t"|>x->"($(j(x)))"
a.matcher=s|l|t
f(x)=parse_one(x,a+E".")|>first

面白かった。コードはかなり雄弁だと思います。

  • 出力フォーマットは生成時に行われます
  • a lit、およびs基本的ルールをCFGています
  • f 呼び出される関数であり、すべてをまとめます。
  • これDrop(Equal("'\n"))は迷惑です-理想的には記述されますE"\n"が、E文字列マクロはエスケープシーケンスを処理しません。
  • 興味深いことに、これはjuliaデータ構造を返すように簡単に変換でき、基本的に|>s のRHSの変換を削除tupleし、tルールに追加しています

残念ながら、ヘルプセンターのルールに従って、ゴルフはゴルフの課題をコーディングするソリューションを投稿するための要件です。
デニス

私は100%ではありませんが、もっと短いことはできます。これは、この言語/ライブラリの組み合わせ「Julia + ParserCombinator.jl」を使用するソリューションをゴルフできるという程度までゴルフされます。しかし、一方で、より短い純粋なジュリアソリューションがあるという確かな変化があります....今、私はそれを書かなければなりません。
リンドンホワイト

まったく別のソリューションを作成する必要はありません。最も抜け出すあなたのアプローチだけでは十分です。ただし、少なくともコメントは削除する必要があります。
デニス

私はコメント(または空白行)をバイト数にカウントしませんでした。私はそれが慣習だと思った、私は間違って考えたと思う
リンドンホワイト

はい、コードは投稿されとおりにスコアリングされます。ただし、いつでも未登録/注釈付きバージョンを追加できます。
デニス
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.