Un po 'di sottaceti


19

Modulo pickle di Python viene utilizzato per la serializzazione, consentendo di scaricare un oggetto in modo tale da poterlo successivamente ricostruire. Per questo, pickle usa un semplice linguaggio basato su stack.

Per semplificare le cose, ci occuperemo di un piccolo sottoinsieme di questa lingua:

(              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

Il tuo compito è implementare questo sottoinsieme della lingua. Nota che\n è una newline letterale e le newline sono in realtà importanti per la lingua.

Per coloro che hanno familiarità con i linguaggi simili a GolfScript o CJam (e l/toperano in modo simile a [e ]rispettivamente.

Ingresso

Per semplificare le cose, l'input sarà sempre valido. In particolare, è possibile assumere quanto segue sull'input:

  • Le stringhe saranno composte solo da lettere minuscole e spazi [a-z ]e utilizzeranno sempre virgolette singole.
  • Non ci saranno caratteri estranei, con tutte le istruzioni come sopra specificato. Ad esempio, ciò significa che i newline si verificheranno solo dopo le stringhe.
  • Ognuno l/tha una corrispondenza (prima di esso e ognuno (ha una corrispondenza l/tdopo di esso. Ce ne sarà anche almeno uno( .
  • Ce ne sarà esattamente uno .e sarà sempre il personaggio finale.

È possibile accettare input tramite riga di comando, STDIN o argomento della funzione. Se lo desideri, puoi utilizzare una singola stringa con escape di nuova riga anziché una stringa su più righe, ma specifica questa nella tua risposta.

Produzione

L'output deve essere una rappresentazione dell'oggetto finale, stampato su STDOUT o restituito come stringa . In particolare:

  • Le stringhe sono rappresentate aprendo e chiudendo virgolette singole con contenuto in mezzo, ad es S'abc' -> 'abc'. Non puoi usare virgolette doppie per questa sfida, anche se sono consentite in Python.

  • Gli elenchi sono rappresentati da elementi separati da virgole racchiusi da [](ad esempio ['a','b','c']), mentre le tuple sono rappresentate da elementi separati da virgole racchiusi da ()(ad es.('a','b','c') ).

  • Gli spazi non contano, ad es ('a', 'b', 'c' ). Va bene.
  • Non è possibile avere una virgola prima della parentesi quadra di chiusura. Nota che questo è intenzionalmente diverso dalle regole di sintassi di Python per rendere le cose più facili per la maggior parte delle lingue, e anche per rendere più difficile semplicemente creare l'elenco / tupla in Python e poi emetterlo, a causa di come viene rappresentata la tupla a elemento singolo (per questo sfida, abbiamo bisogno ('a')invece di ('a',)).

Esempi

Il testo sopra potrebbe sembrare scoraggiante, ma i seguenti esempi dovrebbero rendere le cose un po 'più chiare.

(l.

Uscita possibile: []

(t.

Uscita possibile: ()

(S'hello world'
l.

Uscita possibile: ['hello world']

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

Uscita possibile: ('string one', 'string two', 'string three')

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

Uscita possibile: ('a',['b','c'])

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

Uscita possibile: [('a', 'b', [], 'c'), ('d')]

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

Uscita possibile: [('a',[('b'),['c'],'d',[([])],'e','f'],'g')]

Regole

  • Questo è , quindi vince il codice nel minor numero di byte.
  • Non è consentita alcuna funzionalità progettata per funzionare con i sottaceti Python.

Nota di sicurezza: nel codice reale, solo deselezionare da fonti di cui ti fidi, altrimenti potresti ricevere una brutta cos\nsystem\n(S'rm -rf'\ntR.sorpresa


Non S'abc'\nspingere abco 'abc'?
Calcolatrice

Risposte:


4

CJam, 63

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

Provalo online

Spiegazione:

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

Ora la lunga stringa con vari pezzi di codice. Ogni parte ha alcuni caratteri da controllare, quindi un blocco per la gestione di ciascuno e il caso predefinito.

Prima parte: 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

Seconda parte: (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

Ho la brutta sensazione che si tratti di uno scarso tentativo, ma ecco qui:

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

Lo script deve essere salvato in un file e richiede input da STDIN.

Spiegazione:

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


 ")("\

Divertimento con i salti! Utilizza il fatto che i codici ASCII per i 5 comandi principali coinvolti, mod 9, sono:

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

Ciò consente a ciascuna operazione di essere gestita sulla propria linea, a cui verrà eseguito il salto diretto. Utilizza anche la pila di pile per costruire ciascuna stringa e elenco / tupla nidificati separatamente prima di avvolgerli nei caratteri richiesti.


Bel lavoro, ma sfortunatamente non sembra che stia ottenendo il risultato giusto per la maggior parte dei casi di test (le parentesi sembrano essere nel modo sbagliato, per prima cosa)
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))))

Esegue diversi regex sostituisce l'input per trasformarlo in un codice JS valido, quindi analizza quello.

Test dello snippet

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

Con la mia ultima serie di revisioni non penso più che una soluzione julia pura sarebbe più breve.

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

È stato interessante Penso che il codice sia abbastanza eloquente.

  • La formattazione dell'output viene eseguita alla generazione
  • a l, i, t, E ssono fondamentalmente CFG regole
  • f è la funzione che si chiama, mette tutto insieme.
  • il Drop(Equal("'\n"))è fastidioso - che sarebbe idealmente essere scritto come E"\n", ma la Emacro stringa non gestisce le sequenze di escape.
  • È interessante notare che questo può essere banalmente convertito in strutture di dati julia di ritorno, sta sostanzialmente rimuovendo le trasformazioni su RHS di se |>aggiungendo tupleper la tregola

Sfortunatamente, secondo le regole del nostro centro assistenza , il golf è un requisito per pubblicare soluzioni per codificare le sfide del golf.
Dennis,

Non sono al 100%, tuttavia posso farne uno più corto. Questo è golfato al punto che qualsiasi soluzione che utilizza questa combinazione di lingua / libreria "Julia + ParserCombinator.jl" può essere giocata a golf. D'altra parte, c'è un solido cambiamento nel fatto che esiste una soluzione julia pura più corta .... ora devo scriverla.
Lyndon White,

Non devi scrivere una soluzione completamente diversa; ottenere il massimo dal tuo approccio è sufficiente. Almeno i commenti dovrebbero essere rimossi però.
Dennis,

Non ho contato i commenti (o le righe vuote) per il conteggio dei byte. Ho pensato che fosse una convenzione, immagino di aver capito male
Lyndon White,

Sì, il codice viene assegnato come pubblicato . Tuttavia, puoi sempre aggiungere una versione non annotata / annotata.
Dennis,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.