Một chút của dưa chua


19

Mô-đun dưa chua của Python được sử dụng để tuần tự hóa, cho phép người ta kết xuất một đối tượng theo cách mà sau đó nó có thể được xây dựng lại. Đối với điều này, dưa chua sử dụng một ngôn ngữ dựa trên ngăn xếp đơn giản.

Để đơn giản, chúng ta sẽ xử lý một tập hợp nhỏ của ngôn ngữ này:

(              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

Nhiệm vụ của bạn là thực hiện tập hợp con này của ngôn ngữ. Lưu ý rằng đó \nlà một dòng mới theo nghĩa đen ở đây và dòng mới thực sự quan trọng đối với ngôn ngữ.

Đối với những người quen thuộc với các ngôn ngữ giống GolfScript hoặc CJam, (l/thoạt động tương tự []tương ứng.

Đầu vào

Để giữ cho mọi thứ đơn giản, đầu vào sẽ luôn luôn hợp lệ. Cụ thể, bạn có thể giả sử như sau về đầu vào:

  • Chuỗi sẽ chỉ bao gồm các chữ cái thường và dấu cách [a-z ]và sẽ luôn sử dụng các dấu ngoặc đơn.
  • Sẽ không có ký tự không liên quan, với tất cả các hướng dẫn được chỉ định ở trên. Ví dụ, điều này có nghĩa là các dòng mới sẽ chỉ xảy ra sau chuỗi.
  • Mỗi cái l/tcó một cái khớp (trước nó và cái nào (cũng có cái khớp l/tsau nó. Cũng sẽ có ít nhất một (.
  • Sẽ có chính xác một ., và nó sẽ luôn là nhân vật cuối cùng.

Bạn có thể nhận đầu vào thông qua dòng lệnh, STDIN hoặc đối số hàm. Bạn có thể sử dụng một chuỗi thoát dòng mới thay vì chuỗi đa dòng nếu bạn muốn, nhưng vui lòng chỉ định điều này trong câu trả lời của bạn.

Đầu ra

Đầu ra phải là một đại diện của đối tượng cuối cùng, được in thành STDOUT hoặc được trả về dưới dạng chuỗi . Đặc biệt:

  • Chuỗi được thể hiện bằng cách mở và đóng dấu ngoặc đơn với nội dung ở giữa, ví dụ S'abc' -> 'abc'. Bạn không được sử dụng dấu ngoặc kép cho thử thách này, mặc dù chúng được cho phép trong Python.

  • Danh sách được biểu thị bằng các phần tử được phân tách bằng dấu phẩy được bao quanh bởi [](ví dụ ['a','b','c']), trong khi các bộ dữ liệu được lặp lại bởi các phần tử được phân tách bằng dấu phẩy được bao quanh bởi ()(ví dụ ('a','b','c')).

  • Không gian không quan trọng, ví dụ ('a', 'b', 'c' )là ổn.
  • Bạn không thể có dấu phẩy trước dấu ngoặc đóng. Lưu ý rằng điều này có chủ ý khác với quy tắc cú pháp của Python để làm cho mọi thứ dễ dàng hơn đối với hầu hết các ngôn ngữ và cũng khiến cho việc xây dựng danh sách / tuple trong Python trở nên khó khăn hơn, do cách trình bày bộ phần tử đơn lẻ (đối với điều này thách thức, chúng ta cần ('a')trái ngược với ('a',)).

Ví dụ

Các văn bản trên có vẻ khó xử, nhưng các ví dụ sau đây sẽ làm cho mọi thứ rõ ràng hơn một chút.

(l.

Sản lượng có thể: []

(t.

Sản lượng có thể: ()

(S'hello world'
l.

Sản lượng có thể: ['hello world']

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

Sản lượng có thể: ('string one', 'string two', 'string three')

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

Sản lượng có thể: ('a',['b','c'])

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

Sản lượng có thể: [('a', 'b', [], 'c'), ('d')]

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

Sản lượng có thể: [('a',[('b'),['c'],'d',[([])],'e','f'],'g')]

Quy tắc

  • Đây là , vì vậy mã trong ít byte nhất sẽ thắng.
  • Bất kỳ chức năng nào được thiết kế để hoạt động với dưa chua Python đều không được phép.

Lưu ý bảo mật: Trong mã thực, chỉ rút ra khỏi các nguồn bạn tin tưởng, nếu không bạn có thể nhận được một cos\nsystem\n(S'rm -rf'\ntR.bất ngờ khó chịu


S'abc'\nđẩy abchay 'abc'không?
Máy

Câu trả lời:


4

CJam, 63

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

Dùng thử trực tuyến

Giải trình:

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

Bây giờ chuỗi dài với các đoạn mã khác nhau. Mỗi phần có một vài ký tự để kiểm tra và sau đó là một khối để xử lý từng phần và trường hợp mặc định.

Phần đầu tiên: 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

Phần thứ hai: (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 byte

Tôi có một cảm giác tồi tệ rằng đây là một nỗ lực kém, nhưng ở đây đi:

$/=$,;$"=",";@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];

Kịch bản phải được lưu trong một tệp và nó lấy đầu vào từ STDIN.

Giải trình:

# 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 byte

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


 ")("\

Vui với nhảy! Sử dụng thực tế là mã ASCII cho 5 lệnh chính liên quan, mod 9, là:

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

Điều này cho phép mỗi hoạt động được xử lý trên dòng riêng của nó, sẽ được nhảy trực tiếp. Cũng sử dụng ngăn xếp ngăn xếp để xây dựng từng chuỗi và danh sách / tuple lồng nhau riêng biệt trước khi gói chúng trong các ký tự được yêu cầu.


Công việc tuyệt vời, nhưng thật không may, tôi dường như không nhận được đầu ra đúng cho hầu hết các trường hợp thử nghiệm (các dấu ngoặc dường như sai cách, vì một điều)
Sp3000

0

JavaScript (ES6), 199 byte

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))))

Chạy một số regex thay thế trên đầu vào để biến nó thành mã JS hợp lệ, sau đó phân tích cú pháp đó.

Kiểm tra đoạn trích

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

Julia + ParserCombinator.jl 306 240

Với bộ sửa đổi mới nhất của tôi, tôi không còn nghĩ rằng một giải pháp julia thuần túy sẽ ngắn hơn.

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

Điều đó thật thú vị. Tôi nghĩ rằng mã hóa là khá hùng hồn.

  • Định dạng đầu ra được thực hiện ở thế hệ
  • a l, i, t, Và svề cơ bản CFG quy tắc
  • f là chức năng được gọi là nó mang tất cả lại với nhau.
  • điều Drop(Equal("'\n"))này gây khó chịu - lý tưởng sẽ được viết là E"\n"nhưng Emacro chuỗi không xử lý các chuỗi thoát.
  • Điều thú vị này trivially có thể được chuyển đổi sang trả julia dữ liệu cấu trúc, nó về cơ bản là loại bỏ các biến đổi trên RHS của |>s và thêm tuplecho tquy tắc

Thật không may, theo các quy tắc trong trung tâm trợ giúp của chúng tôi , chơi golf là một yêu cầu để đăng các giải pháp để mã hóa các thách thức golf.
Dennis

Tôi không phải là 100%, tuy nhiên tôi có thể làm một cái ngắn hơn. Điều này được đánh giá là không có giải pháp nào sử dụng kết hợp thư viện / thư viện "Julia + ParserCombinator.jl" này. Nhưng mặt khác, có một sự thay đổi chắc chắn rằng có một giải pháp julia thuần túy ngắn hơn .... bây giờ tôi phải viết nó.
Lyndon White

Bạn không phải viết một giải pháp hoàn toàn khác; tận dụng tối đa phương pháp của bạn là đủ. Ít nhất các ý kiến ​​nên được loại bỏ mặc dù.
Dennis

Tôi đã không đếm các bình luận (hoặc các dòng trống) đối với số đếm byte. Tôi đoán đó là quy ước, tôi đoán tôi đã hiểu sai
Lyndon White

Có, mã được ghi như đã đăng . Bạn luôn có thể thêm một phiên bản chưa được chỉnh sửa / chú thích.
Dennis
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.