少许泡菜


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都有一个匹配项(,每个人之后(都有一个匹配项l/t。也将至少有一个(。
  • 将恰好有一个.,并且它将始终是最后一个字符。

您可以通过命令行,STDIN或函数参数进行输入。如果愿意,可以使用单个换行符转义的字符串,而不是多行字符串,但是请在答案中进行指定。

输出量

输出应该是最终对象的表示,打印到STDOUT或作为字符串返回。特别:

  • 字符串是通过用单引号引起来的,例如,S'abc' -> 'abc'。即使在Python中允许使用双引号,也不能对此挑战使用双引号。

  • 列表由[](例如['a','b','c'])包围的逗号分隔元素表示,而元组由()(例如('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'?
— CalculatorFeline

Answers:


4

果酱,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,2015年

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

通过最新的修订,我不再认为纯粹的julia解决方案会更短。

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 l,i,t,和s基本上CFG规则
  • f 就是所谓的功能,它将所有功能整合在一起。
  • 这Drop(Equal("'\n"))很烦人-理想情况下是这样写的,E"\n"但是E字符串宏不处理转义序列。
  • 有趣的是这可以平凡转换为返回朱莉娅数据结构,它基本上是去除上的RHS的变换|>S和添加tuple的t规则

不幸的是,根据我们帮助中心内的规则,打高尔夫球是发布解决方案以编写高尔夫挑战代码的要求。
— 丹尼斯,

我不是100%可以做的更短一点。这是一种高尔夫运动,使用该语言/库组合“ Julia + ParserCombinator.jl”的任何解决方案都可以高尔夫运动。但是另一方面,确实发生了变化,那就是有一个较短的纯朱丽亚解决方案……现在我必须写它。
— Lyndon White

您不必编写完全不同的解决方案。充分利用您的方法就足够了。至少应删除注释。
— 丹尼斯,

我没有将注释(或空白行)计入字节数。我认为这是惯例,我想我想错了
— Lyndon White

是的,代码被记为发布。不过,您始终可以添加一个取消注释的版本。
— 丹尼斯,
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.