Sedikit acar

19

Modul acar Python digunakan untuk serialisasi, yang memungkinkan seseorang untuk membuang objek sedemikian rupa sehingga dapat kemudian direkonstruksi. Untuk ini, acar menggunakan bahasa berbasis stack sederhana.

Untuk mempermudah, kami akan menangani sebagian kecil dari bahasa ini:

(              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

Tugas Anda adalah mengimplementasikan subset bahasa ini. Perhatikan bahwa \nini adalah baris baru literal di sini, dan baris baru sebenarnya penting untuk bahasa tersebut.

Bagi mereka yang terbiasa dengan GolfScript atau bahasa seperti CJam, (dan l/tberoperasi mirip dengan masing [- ]masing.

Memasukkan

Agar semuanya sederhana, input akan selalu valid. Secara khusus, Anda dapat mengasumsikan berikut tentang input:

  • String hanya akan terdiri dari huruf kecil dan spasi [a-z ], dan akan selalu menggunakan tanda kutip tunggal.
  • Tidak akan ada karakter asing, dengan semua instruksi seperti yang ditentukan di atas. Misalnya, ini berarti bahwa baris baru hanya akan pernah muncul setelah string.
  • Setiap orang l/tmemiliki pencocokan (sebelum dan setiap (pencocokan l/tsetelahnya. Setidaknya akan ada satu (.
  • Akan ada persis satu ., dan itu akan selalu menjadi karakter terakhir.

Anda dapat mengambil input melalui baris perintah, STDIN atau argumen fungsi. Anda dapat menggunakan string yang diloloskan baris baru alih-alih string multiline jika diinginkan, tetapi harap tentukan ini dalam jawaban Anda.

Keluaran

Output harus berupa representasi dari objek akhir, dicetak ke STDOUT atau dikembalikan sebagai string . Secara khusus:

  • String direpresentasikan dengan membuka dan menutup tanda kutip tunggal dengan konten di antaranya, mis S'abc' -> 'abc'. Anda tidak boleh menggunakan tanda kutip ganda untuk tantangan ini, meskipun mereka diizinkan dalam Python.

  • Daftar diwakili oleh elemen yang dipisahkan koma yang dikelilingi oleh [](misalnya ['a','b','c']), sedangkan tupel diwakili oleh elemen yang dipisahkan koma yang dikelilingi oleh ()(misalnya ('a','b','c')).

  • Spasi tidak penting, mis ('a', 'b', 'c' ). Tidak apa-apa.
  • Anda tidak dapat memiliki koma sebelum braket penutup. Perhatikan bahwa ini sengaja berbeda dari aturan sintaksis Python untuk membuat segalanya lebih mudah bagi sebagian besar bahasa, dan juga untuk membuatnya lebih sulit untuk hanya membangun daftar / tuple dengan Python kemudian mengeluarkannya, karena bagaimana tupel elemen tunggal direpresentasikan (untuk ini tantangan, kita perlu ('a')sebagai lawan ('a',)).

Contohnya

Teks di atas mungkin tampak menakutkan, tetapi contoh-contoh berikut seharusnya membuat segalanya lebih jelas.

(l.

Output yang mungkin: []

(t.

Output yang mungkin: ()

(S'hello world'
l.

Output yang mungkin: ['hello world']

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

Output yang mungkin: ('string one', 'string two', 'string three')

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

Output yang mungkin: ('a',['b','c'])

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

Output yang mungkin: [('a', 'b', [], 'c'), ('d')]

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

Output yang mungkin: [('a',[('b'),['c'],'d',[([])],'e','f'],'g')]

Aturan

  • Ini adalah , jadi kode dalam byte paling sedikit menang.
  • Fungsionalitas apa pun yang dirancang untuk bekerja dengan acar Python tidak diizinkan.

Catatan keamanan: Dalam kode sungguhan, hanya lepaskan dari sumber yang Anda percayai, atau Anda akan mendapat cos\nsystem\n(S'rm -rf'\ntR.kejutan yang tidak menyenangkan

Sp3000
sumber
Apakah S'abc'\nmendorong abcatau 'abc'?
CalculatorFeline

Jawaban:

4

CJam, 63

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

Cobalah online

Penjelasan:

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

Sekarang string panjang dengan berbagai potongan kode. Setiap bagian memiliki beberapa karakter untuk diperiksa dan kemudian blok untuk menangani masing-masing, dan kasus default.

Bagian pertama: 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

Bagian kedua: (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
aditsu
sumber
3

Perl, 149 byte

Saya mempunyai firasat buruk bahwa ini adalah upaya yang buruk, tetapi begini:

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

Script harus disimpan dalam file dan dibutuhkan input dari STDIN.

Penjelasan:

# 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];
svsd
sumber
0

> <>, 88 byte

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


 ")("\

Bersenang-senang dengan lompatan! Menggunakan fakta bahwa kode ASCII untuk 5 perintah utama yang terlibat, mod 9, adalah:

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

Ini memungkinkan setiap operasi ditangani pada jalurnya sendiri, yang akan dilompati secara langsung. Juga menggunakan tumpukan tumpukan untuk membangun setiap string dan membuat daftar / tuple secara terpisah sebelum membungkusnya dengan karakter yang diperlukan.

Sok
sumber
Kerja bagus, tapi sayangnya saya sepertinya tidak mendapatkan output yang tepat untuk sebagian besar kasus uji (kurung tampaknya salah jalan, untuk satu hal)
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))))

Menjalankan beberapa regex menggantikan input untuk mengubahnya menjadi kode JS yang valid, lalu mem-parsing itu.

Cuplikan Tes

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>

Justin Mariner
sumber
0

Julia + ParserCombinator.jl 306 240

Dengan set revisi terbaru saya, saya tidak lagi berpikir solusi julia murni akan lebih pendek.

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

Itu menarik. Saya pikir kode ini cukup fasih.

  • Pemformatan output dilakukan saat pembuatan
  • a l, i, t, Dan spada dasarnya CFG aturan
  • f adalah fungsi yang disebut menyatukan semuanya.
  • yang Drop(Equal("'\n"))menjengkelkan - yang akan idealnya ditulis sebagai E"\n"tetapi Emakro string tidak menangani escape sequence.
  • Menariknya ini dapat sepele dikonversi untuk kembali julia data struktur, pada dasarnya menghapus transformasi pada RHS dari |>s dan menambahkan tupleuntuk taturan
Lyndon White
sumber
Sayangnya, sesuai aturan di pusat bantuan kami , golf adalah persyaratan untuk memposting solusi untuk tantangan kode golf.
Dennis
Saya bukan 100% saya bisa melakukan yang lebih pendek. Ini di-golf ke exent bahwa solusi apa pun yang menggunakan kombinasi langauge / pustaka "Julia + ParserCombinator.jl" ini dapat di-golf. Tetapi di sisi lain, ada perubahan kuat bahwa ada solusi julia murni yang lebih pendek .... sekarang saya harus menulisnya.
Lyndon White
Anda tidak perlu menulis solusi yang sama sekali berbeda; mendapatkan hasil maksimal dari pendekatan Anda sudah cukup. Setidaknya komentar harus dihapus.
Dennis
Saya tidak menghitung komentar (atau baris kosong) menuju byte-count. Saya pikir itu adalah kebaktian, saya kira saya salah mengira
Lyndon White
Ya, kode diberi skor saat diposkan . Anda selalu dapat menambahkan versi yang ungolfed / annotated.
Dennis