少许泡菜


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

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

我不是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.