Um pouco de picles


19

O módulo pickle do Python é usado para serialização, permitindo despejar um objeto de uma maneira que possa ser reconstruído posteriormente. Para isso, pickle usa uma linguagem simples baseada em pilha.

Para simplificar, trataremos de um pequeno subconjunto desse idioma:

(              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

Sua tarefa é implementar esse subconjunto do idioma. Observe que aqui \né uma nova linha literal, e as novas linhas são realmente importantes para o idioma.

Para aqueles familiarizados com as linguagens do GolfScript ou do tipo CJam, (e l/topere da mesma forma [e ]respectivamente.

Entrada

Para manter as coisas simples, a entrada sempre será válida. Em particular, você pode assumir o seguinte sobre a entrada:

  • As strings consistem apenas em letras minúsculas e espaços [a-z ]e sempre usam aspas simples.
  • Não haverá caracteres estranhos, com todas as instruções especificadas acima. Por exemplo, isso significa que as novas linhas só ocorrerão após as seqüências de caracteres.
  • Cada l/tum tem uma correspondência (antes e cada (um tem uma correspondência l/tdepois. Também haverá pelo menos um (.
  • Haverá exatamente um ., e sempre será o personagem final.

Você pode receber informações via linha de comando, STDIN ou argumento de função. Você pode usar uma única cadeia de caracteres com escape de nova linha em vez de uma cadeia de linhas múltiplas, se desejar, mas especifique isso na sua resposta.

Resultado

A saída deve ser uma representação do objeto final, impressa em STDOUT ou retornada como uma string . Especificamente:

  • As strings são representadas pela abertura e fechamento de aspas simples com conteúdo no meio, por exemplo S'abc' -> 'abc'. Você não pode usar aspas duplas para esse desafio, mesmo que elas sejam permitidas no Python.

  • As listas são representadas por elementos separados por vírgula e cercados por []( por exemplo ['a','b','c']), enquanto as tuplas são representadas por elementos separados por vírgula e cercados por ()( por exemplo ('a','b','c')).

  • Os espaços não importam, por exemplo, ('a', 'b', 'c' )está tudo bem.
  • Você não pode ter uma vírgula antes do colchete de fechamento. Observe que isso é intencionalmente diferente das regras de sintaxe do Python para facilitar as coisas para a maioria das linguagens e também para tornar mais difícil simplesmente construir a lista / tupla no Python e depois produzi-la, devido à forma como a tupla de elemento único é representada (para isso desafio, precisamos ('a')em oposição a ('a',)).

Exemplos

O texto acima pode parecer assustador, mas os exemplos a seguir devem tornar as coisas um pouco mais claras.

(l.

Saída possível: []

(t.

Saída possível: ()

(S'hello world'
l.

Saída possível: ['hello world']

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

Saída possível: ('string one', 'string two', 'string three')

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

Saída possível: ('a',['b','c'])

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

Saída possível: [('a', 'b', [], 'c'), ('d')]

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

Saída possível: [('a',[('b'),['c'],'d',[([])],'e','f'],'g')]

Regras

  • Isso é , então o código com o menor número de bytes vence.
  • Não é permitida nenhuma funcionalidade projetada para funcionar com picles de Python.

Nota de segurança: no código real, apenas retire as fontes de sua confiança, ou você poderá receber uma cos\nsystem\n(S'rm -rf'\ntR.surpresa desagradável


Será que S'abc'\nempurrar abcou 'abc'?
CalculatorFeline

Respostas:


4

CJam, 63

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

Experimente online

Explicação:

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

Agora a cadeia longa com várias partes de código. Cada parte tem alguns caracteres para verificar e, em seguida, um bloco para lidar com cada um, e o caso padrão.

Primeira 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

Segunda 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 bytes

Tenho um mau pressentimento de que esta é uma tentativa ruim, mas aqui vai:

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

O script deve ser salvo em um arquivo e recebe informações do STDIN.

Explicação:

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

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


 ")("\

Diversão com saltos! Usa o fato de que os códigos ASCII para os 5 principais comandos envolvidos, mod 9, são:

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

Isso permite que cada operação seja manipulada em sua própria linha, a qual será saltada diretamente. Também usa a pilha de pilhas para construir cada sequência e lista / tupla aninhada separadamente antes de agrupá-las nos caracteres necessários.


Bom trabalho, mas infelizmente eu não parecem estar recebendo a saída certa para a maioria dos casos de teste (os suportes parecem ser o caminho errado ao redor, para uma coisa)
SP3000

0

JavaScript (ES6), 199 bytes

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

Executa várias substituições de regex na entrada para transformá-lo em código JS válido e, em seguida, analisa isso.

Snippet de teste

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

Com o meu último conjunto de revisões, não acho mais que uma solução julia pura seria mais curta.

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

Isso foi interessante. Eu acho que o código é bastante eloquente.

  • A formatação da saída é feita na geração
  • a l, i, t, E ssão basicamente CFG regras
  • f é a função que se chama reunir tudo.
  • o Drop(Equal("'\n"))é chato - que seria idealmente escrito como E"\n"mas oE macro de string não lida com seqüências de escape.
  • Curiosamente, isso pode ser convertido trivialmente para retornar estruturas de dados julia, é basicamente remover as transformações no RHS de |>s e adicionar tuplea tregra

Infelizmente, de acordo com as regras da nossa Central de Ajuda , o golfe é um requisito para publicar soluções para codificar os desafios do golfe.
Dennis

Eu não sou 100%, no entanto, posso fazer um mais curto. Isso é praticado até o ponto em que qualquer solução usando essa combinação de idioma / biblioteca "Julia + ParserCombinator.jl" pode ser praticada. Mas, por outro lado, há uma mudança sólida de que existe uma solução julia pura mais curta ... agora eu tenho que escrever.
Lyndon Branca

Você não precisa escrever uma solução totalmente diferente; tirar o máximo proveito da sua abordagem é suficiente. Pelo menos os comentários devem ser removidos.
Dennis

Não contei os comentários (ou linhas em branco) na contagem de bytes. Eu achei que era convenção, acho que achei errado
Lyndon White

Sim, o código é pontuado como publicado . Você sempre pode adicionar uma versão não-anotada / anotada.
Dennis
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.