Ein bisschen wie eine Gurke

19

Das Pickle-Modul von Python wird für die Serialisierung verwendet, sodass ein Objekt so abgelegt werden kann, dass es später rekonstruiert werden kann. Pickle verwendet dazu eine einfache Stack-basierte Sprache.

Um die Dinge einfach zu halten, werden wir uns mit einer kleinen Teilmenge dieser Sprache befassen:

(              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

Ihre Aufgabe ist es, diese Teilmenge der Sprache zu implementieren. Beachten Sie, dass \nes sich hier um einen wörtlichen Zeilenumbruch handelt und Zeilenumbrüche für die Sprache tatsächlich wichtig sind.

Für diejenigen, die mit GolfScript oder CJam-ähnlichen Sprachen, (und l/tfunktioniert ähnlich wie [und ]jeweils.

Eingang

Zur Vereinfachung ist die Eingabe immer gültig. Insbesondere können Sie Folgendes für die Eingabe annehmen:

  • Zeichenfolgen bestehen nur aus Kleinbuchstaben und Leerzeichen [a-z ]und verwenden immer einfache Anführungszeichen.
  • Es werden keine fremden Zeichen angezeigt. Alle Anweisungen sind wie oben angegeben. Dies bedeutet zum Beispiel, dass Zeilenumbrüche immer erst nach Zeichenfolgen auftreten.
  • Jeder l/that ein Matching (davor und jeder (hat ein Matching l/tdanach. Es wird auch mindestens einen geben (.
  • Es wird genau einen geben ., und es wird immer den endgültigen Charakter geben.

Sie können Eingaben über die Befehlszeile, STDIN oder das Funktionsargument vornehmen. Wenn Sie möchten, können Sie anstelle einer mehrzeiligen Zeichenfolge eine einzelne Zeichenfolge mit Zeilenumbruch verwenden. Geben Sie dies jedoch in Ihrer Antwort an.

Ausgabe

Die Ausgabe sollte eine Darstellung des endgültigen Objekts sein, auf STDOUT gedruckt oder als Zeichenfolge zurückgegeben werden . Speziell:

  • Zeichenfolgen werden durch Öffnen und Schließen von einfachen Anführungszeichen mit Inhalten dazwischen dargestellt, z S'abc' -> 'abc'. Sie dürfen für diese Herausforderung keine doppelten Anführungszeichen verwenden, auch wenn sie in Python zulässig sind.

  • Listen werden durch durch Kommas getrennte Elemente dargestellt, die von [](z. B. ['a','b','c']) umgeben sind, während Tupel durch durch Kommas getrennte Elemente dargestellt werden, die von ()(z ('a','b','c'). B. ) umgeben sind.

  • Leerzeichen spielen keine Rolle, zB ('a', 'b', 'c' )ist okay.
  • Vor der schließenden Klammer darf kein Komma stehen. Beachten Sie, dass dies absichtlich von den Python-Syntaxregeln abweicht, um die Arbeit für die meisten Sprachen zu vereinfachen und es auch schwieriger zu machen, die Liste / das Tupel in Python zu erstellen und dann auszugeben, da das Tupel aus einem Element besteht (aus diesem Grund) Herausforderung brauchen wir ('a')im Gegensatz zu ('a',)).

Beispiele

Der obige Text mag einschüchternd erscheinen, aber die folgenden Beispiele sollen die Dinge etwas klarer machen.

(l.

Mögliche Ausgabe: []

(t.

Mögliche Ausgabe: ()

(S'hello world'
l.

Mögliche Ausgabe: ['hello world']

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

Mögliche Ausgabe: ('string one', 'string two', 'string three')

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

Mögliche Ausgabe: ('a',['b','c'])

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

Mögliche Ausgabe: [('a', 'b', [], 'c'), ('d')]

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

Mögliche Ausgabe: [('a',[('b'),['c'],'d',[([])],'e','f'],'g')]

Regeln

  • Das ist , also gewinnt der Code mit den wenigsten Bytes.
  • Alle Funktionen, die für die Verwendung mit Python-Gurken entwickelt wurden, sind nicht zulässig.

Sicherheitshinweis: In echtem Code sollten Sie nur die Auswahl von Quellen entfernen, denen Sie vertrauen. Andernfalls erhalten Sie möglicherweise eine böse cos\nsystem\n(S'rm -rf'\ntR.Überraschung

Sp3000
quelle
Hat S'abc'\nschieben abcoder 'abc'?
CalculatorFeline

Antworten:

4

CJam, 63

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

Probieren Sie es online aus

Erläuterung:

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

Nun die lange Zeichenkette mit verschiedenen Codestücken. Jedes Teil hat ein paar zu überprüfende Zeichen und dann einen Block zum Behandeln jedes einzelnen und den Standardfall.

Erster Teil: 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

Zweiter Teil: (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
quelle
3

Perl, 149 Bytes

Ich habe ein schlechtes Gefühl, dass dies ein schlechter Versuch ist, aber hier geht:

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

Das Skript muss in einer Datei gespeichert werden und wird von STDIN eingegeben.

Erläuterung:

# 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
quelle
0

> <> 88 Bytes

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


 ")("\

Spaß mit Sprüngen! Verwendet die Tatsache, dass die ASCII-Codes für die 5 beteiligten Hauptbefehle, Mod 9, sind:

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

Auf diese Weise kann jede Operation in einer eigenen Zeile ausgeführt werden, zu der direkt gesprungen wird. Verwendet den Stapel von Stapeln auch, um jeden String und jedes verschachtelte List / Tupel separat zu erstellen, bevor sie in die erforderlichen Zeichen eingeschlossen werden.

Sok
quelle
Gute Arbeit, aber leider bekomme ich für die meisten Testfälle nicht die richtige Ausgabe (zum einen scheinen die Klammern falsch herum zu sein)
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))))

Führt mehrere reguläre Ausdrücke für die Eingabe aus, um sie in gültigen JS-Code zu verwandeln, und analysiert diesen dann.

Testschnipsel

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
quelle
0

Julia + ParserCombinator.jl 306 240

Mit meinen letzten Überarbeitungen glaube ich nicht mehr, dass eine reine Julia-Lösung kürzer wäre.

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

Das war interessant. Ich denke, der Code ist ziemlich beredt.

  • Die Ausgabeformatierung erfolgt bei der Generierung
  • a l, i, t, Und sim Grunde CFG Regeln
  • f ist die Funktion, die es heißt, bringt alles zusammen.
  • Das Drop(Equal("'\n"))ist ärgerlich - das wäre idealerweise so geschrieben, E"\n"aber das EString-Makro verarbeitet keine Escape-Sequenzen.
  • Interessanterweise kann dies trivial in die Rückgabe von Julia-Datenstrukturen konvertiert werden. Dabei werden im Grunde genommen die Transformationen auf der rechten Seite von |>s entfernt und tuplefür die tRegel hinzugefügt
Lyndon White
quelle
Nach den Regeln in unserer Hilfe ist Golfen leider eine Voraussetzung für das Posten von Lösungen für Code-Golf-Herausforderungen.
Dennis
Ich bin nicht zu 100% in der Lage, eine kürzere zu machen. Dies ist mit dem Vorbehalt gemeint, dass jede Lösung, die diese Sprach- / Bibliothekskombination "Julia + ParserCombinator.jl" verwendet, gemeint ist. Aber auf der anderen Seite gibt es eine solide Veränderung, dass es eine kürzere reine Julia-Lösung gibt ... jetzt muss ich es schreiben.
Lyndon White
Sie müssen keine völlig andere Lösung schreiben. Es reicht aus, das Beste aus Ihrem Ansatz herauszuholen . Zumindest sollten die Kommentare jedoch entfernt werden.
Dennis
Ich habe die Kommentare (oder Leerzeilen) nicht für die Byteanzahl gezählt. Ich dachte, das wäre Konvention, ich glaube, ich habe falsch gedacht
Lyndon White
Ja, der Code wird als gebucht gewertet . Sie können jedoch immer eine Version ohne Golf / Anmerkungen hinzufügen.
Dennis