Трохи соління


19

Модуль соління Python використовується для серіалізації, дозволяючи скинути об'єкт таким чином, щоб він був згодом реконструйований. Для цього підберезник використовує просту мову на основі стека.

Щоб все було просто, ми матимемо справу з невеликим підмножиною цієї мови:

(              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 основних включених команд mod 9 є:

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

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


Хороша робота, але, на жаль, я, здається, не отримую правильного результату для більшості тестових випадків (дужки, здається, неправильно, для одного)
Sp3000

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 з |>і додавання tupleдля tправила

На жаль, відповідно до правил у нашому довідковому центрі , гольф - це вимога для публікації рішень для кодування проблем із гольфом.
Денніс

Я не на 100%, проте можу зробити коротший. Це означає, що будь-яке рішення, що використовує цю комбінацію мов / бібліотек "Julia + ParserCombinator.jl", може бути гольф. Але з іншого боку, є суцільна зміна, що існує коротше чисте рішення Юлії .... тепер я мушу це написати.
Ліндон Уайт

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

Я не рахував коментарів (чи порожніх рядків) до підрахунку байтів. Я подумав, що це умова, я думаю, я зрозумів неправильно
Ліндон Уайт,

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