Un peu de cornichon


19

Le module pickle de Python est utilisé pour la sérialisation, ce qui permet de vider un objet d'une manière telle qu'il puisse être reconstruit plus tard. Pour cela, pickle utilise un langage simple basé sur la pile.

Pour simplifier les choses, nous traiterons d'un petit sous-ensemble de ce langage:

(              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

Votre tâche consiste à implémenter ce sous-ensemble de la langue. Notez qu'il \ns'agit ici d'une nouvelle ligne littérale, et les nouvelles lignes sont en fait importantes pour la langue.

Pour ceux qui sont familiers avec les langages GolfScript ou CJam (et qui l/tfonctionnent de manière similaire [et ]respective.

Contribution

Pour simplifier les choses, l'entrée sera toujours valide. En particulier, vous pouvez supposer ce qui suit à propos de l'entrée:

  • Les chaînes ne seront composées que de lettres minuscules et d'espaces [a-z ]et utiliseront toujours des guillemets simples.
  • Il n'y aura pas de caractères étrangers, toutes les instructions étant celles spécifiées ci-dessus. Par exemple, cela signifie que les sauts de ligne ne se produiront qu'après les chaînes.
  • Chacun l/ta une correspondance (avant et chaque (a une correspondance l/taprès. Il y en aura également au moins un (.
  • Il y en aura exactement un .et ce sera toujours le dernier caractère.

Vous pouvez saisir des informations via la ligne de commande, STDIN ou l'argument de fonction. Vous pouvez utiliser une seule chaîne d'échappement de nouvelle ligne au lieu d'une chaîne multiligne si vous le souhaitez, mais veuillez le préciser dans votre réponse.

Production

La sortie doit être une représentation de l'objet final, imprimée sur STDOUT ou retournée sous forme de chaîne . Plus précisément:

  • Les chaînes sont représentées par l'ouverture et la fermeture de guillemets simples avec du contenu entre les deux, par exemple S'abc' -> 'abc'. Vous ne pouvez pas utiliser de guillemets doubles pour ce défi, même s'ils sont autorisés en Python.

  • Les listes sont représentées par des éléments séparés par des virgules entourés par []( par exemple ['a','b','c']), tandis que les tuples sont représentés par des éléments séparés par des virgules entourés par ()( par exemple ('a','b','c')).

  • Les espaces n'ont pas d'importance, par exemple, ('a', 'b', 'c' )ça va.
  • Vous ne pouvez pas avoir de virgule avant le crochet de fermeture. Notez que ceci est intentionnellement différent des règles de syntaxe Python pour rendre les choses plus faciles pour la plupart des langues, et aussi pour rendre plus difficile la construction simple de la liste / du tuple en Python, puis sa sortie, en raison de la façon dont le tuple à élément unique est représenté (pour cela défi, nous avons besoin ('a')par opposition à ('a',)).

Exemples

Le texte ci-dessus peut sembler intimidant, mais les exemples suivants devraient rendre les choses un peu plus claires.

(l.

Sortie possible: []

(t.

Sortie possible: ()

(S'hello world'
l.

Sortie possible: ['hello world']

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

Sortie possible: ('string one', 'string two', 'string three')

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

Sortie possible: ('a',['b','c'])

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

Sortie possible: [('a', 'b', [], 'c'), ('d')]

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

Sortie possible: [('a',[('b'),['c'],'d',[([])],'e','f'],'g')]

Règles

  • C'est du , donc le code dans le moins d'octets gagne.
  • Toute fonctionnalité conçue pour fonctionner avec des cornichons Python n'est pas autorisée.

Note de sécurité: en vrai code, ne décochez que les sources de confiance, sinon vous pourriez avoir une mauvaise cos\nsystem\n(S'rm -rf'\ntR.surprise


Ne S'abc'\npousser abcou 'abc'?
CalculatorFeline

Réponses:


4

CJam, 63

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

Essayez-le en ligne

Explication:

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

Maintenant, la longue chaîne avec divers morceaux de code. Chaque partie a quelques caractères à vérifier puis un bloc pour la gestion de chacun et le cas par défaut.

Première partie: 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

Deuxième partie: (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 octets

J'ai le mauvais pressentiment que c'est une mauvaise tentative, mais voici:

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

Le script doit être enregistré dans un fichier et il prend l'entrée de STDIN.

Explication:

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

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


 ")("\

Amusez-vous avec des sauts! Utilise le fait que les codes ASCII pour les 5 principales commandes impliquées, mod 9, sont:

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

Cela permet à chaque opération d'être gérée sur sa propre ligne, qui sera directement sautée. Utilise également la pile de piles pour construire séparément chaque chaîne et liste / tuple imbriqué avant de les encapsuler dans les caractères requis.


Beau travail, mais malheureusement, je ne semble pas obtenir la bonne sortie pour la plupart des cas de test (les crochets semblent être dans le mauvais sens, pour une chose)
Sp3000

0

JavaScript (ES6), 199 octets

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

Exécute plusieurs remplacements d'expressions régulières sur l'entrée pour la transformer en code JS valide, puis analyse cela.

Extrait de test

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

Avec ma dernière série de révisions, je ne pense plus qu'une solution pure julia serait plus courte.

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

C'était intéressant. Je pense que le codé est assez éloquent.

  • Le formatage de sortie est effectué lors de la génération
  • a l, i, tEt ssont essentiellement CFG règles
  • f est la fonction qui est appelée, elle rassemble tout cela.
  • l' Drop(Equal("'\n"))est ennuyeux - qui serait idéalement écrit , E"\n"mais la Emacro chaîne ne gère pas des séquences d'échappement.
  • Fait intéressant, cela peut être trivialement converti en retour de structures de données julia, il s'agit essentiellement de supprimer les transformations sur le RHS de |>s et d'ajouter tuplepour la trègle

Malheureusement, selon les règles de notre centre d'aide , le golf est une exigence pour publier des solutions pour coder les défis du golf.
Dennis

Je ne suis pas à 100%, je peux en faire un plus court, cependant. Cela se joue au point que toute solution utilisant cette combinaison langauge / bibliothèque "Julia + ParserCombinator.jl" peut être jouée. Mais d'un autre côté, il y a un changement solide qu'il y a une solution julia pure plus courte .... maintenant je dois l'écrire.
Lyndon White

Vous n'avez pas besoin d'écrire une solution entièrement différente; tirer le meilleur parti de votre approche suffit. Au moins, les commentaires devraient être supprimés.
Dennis

Je n'ai pas compté les commentaires (ou les lignes vides) dans le décompte d'octets. Je pensais que c'était la convention, je suppose que je me suis trompé
Lyndon White

Oui, le code est noté comme publié . Vous pouvez toujours ajouter une version non golfée / annotée.
Dennis
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.