Немного рассола


19

Модуль Python Pickle используется для сериализации, позволяя создать объект таким образом, чтобы впоследствии его можно было восстановить. Для этого pickle использует простой язык на основе стека.

Для простоты мы будем иметь дело с небольшим подмножеством этого языка:

(              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

Ваша задача - реализовать это подмножество языка. Обратите внимание, что \nздесь буквальный перевод строки, и переводы строки действительно важны для языка.

Для тех, кто знаком с GolfScript или CJam-подобными языками, (и l/tработает аналогично [и ]соответственно.

вход

Для простоты ввод всегда будет действительным. В частности, вы можете предположить следующее относительно ввода:

  • Строки будут состоять только из строчных букв и пробелов [a-z ]и всегда будут использовать одинарные кавычки.
  • Не будет никаких посторонних символов, все инструкции будут такими, как указано выше. Например, это означает, что переводы строк будут происходить только после строк.
  • У каждого l/tесть соответствие (перед ним, и у каждого (есть соответствие l/tпосле него. Там также будет хотя бы один (.
  • Там будет ровно один ., и он всегда будет последним персонажем.

Вы можете получить ввод через командную строку, STDIN или аргумент функции. Вы можете использовать одну строку с новой строкой вместо многострочной, если хотите, но укажите это в своем ответе.

Выход

Выходными данными должно быть представление конечного объекта, напечатанное в STDOUT или возвращенное в виде строки . В частности:

  • Строки представлены открытием и закрытием одинарных кавычек с содержимым между ними, например S'abc' -> 'abc'. Вы не можете использовать двойные кавычки для этой задачи, даже если они разрешены в Python.

  • Списки представлены разделенными запятыми элементами, окруженными [](например ['a','b','c']), в то время как кортежи представлены разделенными запятыми элементами, окруженными ()(например,('a','b','c') ).

  • Пробелы не имеют значения, например, ('a', 'b', 'c' )все в порядке.
  • Вы не можете иметь запятую перед закрывающей скобкой. Обратите внимание, что это намеренно отличается от правил синтаксиса Python для упрощения работы большинства языков, а также для усложнения простого создания списка / кортежа в Python и его вывода из-за того, как представлен одноэлементный кортеж (для этого вызов, нам нужно ('a')в отличие от ('a',)).

Примеры

Приведенный выше текст может показаться пугающим, но следующие примеры должны прояснить ситуацию.

(l.

Возможный вывод: []

(t.

Возможный вывод: ()

(S'hello world'
l.

Возможный вывод: ['hello world']

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

Возможный вывод: ('string one', 'string two', 'string three')

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

Возможный вывод: ('a',['b','c'])

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

Возможный вывод: [('a', 'b', [], 'c'), ('d')]

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

Возможный вывод: [('a',[('b'),['c'],'d',[([])],'e','f'],'g')]

правила

  • Это , поэтому выигрывает код в наименьшем количестве байтов.
  • Любая функциональность, предназначенная для работы с солями Python, не допускается.

Примечание по безопасности: в реальном коде извлекайте информацию только из источников, которым вы доверяете, иначе вы можете получить неприятный cos\nsystem\n(S'rm -rf'\ntR.сюрприз


Есть ли S'abc'\nтолкать abcили 'abc'?
CalculatorFeline

Ответы:


4

CJam, 63

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

Попробуйте онлайн

Объяснение:

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

Теперь длинная строка с различными кусочками кода. Каждая часть имеет несколько символов для проверки, а затем блок для обработки каждого из них и регистр по умолчанию.

Первая часть: 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

Вторая часть: (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 байт

У меня плохое предчувствие, что это неудачная попытка, но здесь говорится:

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

Сценарий должен быть сохранен в файл, и он принимает входные данные из STDIN.

Объяснение:

# 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 байт

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


 ")("\

Веселье с прыжками! Использует тот факт, что коды ASCII для 5 основных команд, мод 9, являются:

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

Это позволяет обрабатывать каждую операцию в отдельной строке, к которой можно непосредственно перейти. Также использует стек стеков для конструирования каждой строки и вложенного списка / кортежа отдельно перед тем, как заключить их в необходимые символы.


Хорошая работа, но, к сожалению, я не получаю правильного вывода для большинства тестовых случаев (во-
первых,

0

JavaScript (ES6), 199 байт

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

Выполняет несколько замен регулярных выражений на входе, чтобы превратить его в действительный код JS, а затем анализирует его.

Тестовый фрагмент

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

С моим последним набором ревизий я больше не думаю, что чисто решение Джулии будет короче.

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

Это было интересно. Я думаю, что код достаточно красноречив.

  • Форматирование вывода производится при генерации
  • a l, i, t, И sв основном CFG правила
  • f это функция, которая называется это сводит все это вместе.
  • Drop(Equal("'\n"))раздражает - это было бы идеально быть записана в виде , E"\n"но Eстрока макроса не обрабатывает управляющие последовательности.
  • Интересно, что это можно легко преобразовать в возвращаемые структуры данных julia, это, в основном, удаление преобразований в RHS |>s и добавление tupleдля tправила

К сожалению, согласно правилам нашего справочного центра , игра в гольф является обязательным условием для публикации решений для кодирования проблем с гольфом.
Деннис

Я не на 100% могу сделать более короткий, однако. Это относится к тому, что любое решение, использующее эту комбинацию языка / библиотеки "Julia + ParserCombinator.jl", может быть применено. Но с другой стороны, есть серьезное изменение в том, что существует более короткое решение по чистой джулии ... теперь я должен написать это.
Линдон Уайт

Вам не нужно писать совершенно другое решение; достаточно получить максимальную отдачу от вашего подхода. По крайней мере, комментарии должны быть удалены, хотя.
Деннис

Я не посчитал комментарии (или пустые строки) в счетчик байтов. Я подумал, что это было соглашение, я думаю, я понял неправильно
Линдон Уайт

Да, код оценивается как опубликованный . Вы всегда можете добавить версию без аннотации / аннотации.
Деннис
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.