Реализация стека


44

Я не могу поверить, что у нас этого еще нет ... Это одна из самых важных структур данных в программировании, но все же достаточно простая, чтобы реализовать ее в :

Вызов

Ваша задача состоит в том, чтобы реализовать стек, который позволяет вставлять и выталкивать числа, тестировать вашу реализацию и упрощать ввод / вывод, мы будем использовать следующую настройку:

  • На входе будет список неотрицательных целых чисел

Каждое положительное целое число обозначает а каждое обозначает - отбрасывает верхний элемент.push ( n ) 0 pop ()npush(n)0pop()

  • На выходе будет получен стек

пример

Например, если нам дано :[12,3,0,101,11,1,0,0,14,0,28]

12[12]3[3,12]0[12]101[101,12]11[11,101,12]1[1,11,101,12]0[11,101,12]0[101,12]14[14,101,12]0[101,12]28[28,101,12]

Вывод будет:[28,101,12]

правила

  • Ввод будет список неотрицательных целых чисел в любом формате ввода / вывода по умолчанию
    • вы можете использовать отрицательное целое число, чтобы обозначить конец потока целых чисел
  • Результатом будет список / матрица / .. результирующего стека
    • на ваш выбор, где будет верхний элемент (в начале или в конце), вывод просто должен быть последовательным
    • вывод является гибким (например, целые числа, разделенные новыми строками, будет в порядке), единственное, что имеет значение, это порядок
    • вы можете использовать отрицательное целое число для обозначения дна стека
  • Вы гарантированно, что никогда не будет когда стек пуст0

Примеры

[] -> []
[1] -> [1]
[1,0,2] -> [2]
[4,0,1,12] -> [12,1]
[8,3,1,2,3] -> [3,2,1,3,8]
[1,3,7,0,0,0] -> []
[13,0,13,10,1,0,1005,5,0,0,0] -> [13]
[12,3,0,101,11,1,0,0,14,0,28] -> [28,101,12]

12
Следует отметить, что, учитывая условия, фактически не нужно реализовывать стек.
Джефф Цейтлин

Если вы хотите, чтобы кто-то на самом деле реализовал стек, вам может понадобиться поместить что-то в Песочницу.
mbomb007

@ mbomb007: разрешен любой: «ваш выбор, где будет верхний элемент (в начале или в конце)»
ბიმო

@ mbomb007: Не было бы сложнее, если бы вам пришлось изменить ввод, не так ли? Кроме того, если вы рассматриваете установку как стек, который определяет, что сверху, а что снизу, и почему одно определение должно быть менее произвольным?
ბიმო

@ OMᗺ Потому что вход выглядит как стек / список / массив. Теперь вся задача состоит в том, чтобы удалить любое число, за которым следует ноль.
mbomb007

Ответы:


19

MATL , 6 байтов

"@?@}x

Ввод - это вектор строки чисел.

Последний стек показан вверх ногами, а самый последний элемент показан ниже.

Попробуйте онлайн! Или проверьте все тестовые случаи .

объяснение

"         % For each element in the input (implicit)
  @       %   Push current element
  ?       %   If non-zero (this consumes the current element)
    @     %     Push current element again
  }       %   Else
    x     %     Delete most recent element
          %   End (implicit)
          % End (implicit)
          % Display (implicit)

13

Java (JDK 10) , 42 байта

Так как «[the] output является гибким [...], единственное, что имеет значение, это порядок», это изменяет входной массив в 0-определенный массив. Пример: [1,0,2]вернет, [2,0,2]который должен интерпретироваться как = .[2,0,2][2]

a->{int s=0;for(int v:a)a[v>0?s++:--s]=v;}

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

Предыдущие версии:

Java (JDK 10) , 60 байт

l->{for(int i;(i=l.indexOf(0))>0;l.remove(i))l.remove(--i);}

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

Кредиты:

Если я могу завершить программу с ошибками: 55 байт

(хотя все правильно модифицировано)

l->{for(int i;;l.remove(--i))l.remove(i=l.indexOf(0));}

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


4
Это довольно впечатляет. Вы можете потерять 1 байт, используя, >0так как в начале списка никогда не будет нуля (что означало бы, что вершина стека была в -1).
OOBalance

@OOBalance Действительно, я не думал об этом. Спасибо!
Оливье Грегуар

12

Sed, 17 байт

:;s/[0-9]\+,0//;t

-3 байта благодаря @ OMᗺ, -1 благодаря @eggyal

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

Принимает ввод от стандартного ввода, вот так:

echo '[12,3,0,101,11,1,0,0,14,0,28]' | sed ':;s/[0-9]\+,0,//;t'

Выводит стек в обратном порядке:

[12,101,28]

Может быть меньше на два байта, если мои локальные по sedсвоей природе понятные классы символов, как \d, но это не по какой-то причине.


1
Добро пожаловать в PPCG! Хорошо, мой был длиннее (используя другой формат ввода) .. Кстати. Вы можете использовать пустую метку, так как вы используете только 1, а поскольку вы повторяете процесс, gэто избыточно - экономя 4 байта: попробуйте онлайн!
მოიმო

Г не является лишним! В худшем случае сложность во время выполнения зависит от глубины последовательных всплывающих окон, а не от количества всплывающих окон! Не то, чтобы эффективность
имела

1
Ваше последнее предложение отвечает на вопрос об избыточности: P Кстати. как ты считал байты? Я получаю 18, возможно, вы включили новую строку в конце или что-то.
მოიმო

Да, это был перевод строки.
Такрой

1
Если последний элемент ввода равен 0, то это не будет соответствовать вашему регулярному выражению.
eggyal

12

PowerShell , 46 41 40 байт

$args|%{$x,$a=&({1,$_+$a},{$a})[!$_]};$a

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

Принимает ввод через сплаттинг, например, $z=@(12,3,0,101,11,1,0,0,14,0,28); .\implement-stack.ps1 @zкоторый в TIO проявляется как отдельные аргументы.

$args|%{$x,$a=&({1,$_+$a},{$a})[!$_]};$a    # Full program
$args                                       # Take input via splatting
     |%{                            };      # Loop through each item
              &(              )[!$_]        # Pseudo-ternary, if input is 0 this is 1
        $x,$a=            {$a}              # ... which will pop the first item into $x
           $a=  { ,$_+$a}                   # Else, we append the first item
        $x   =   1                          # ... and drop a dummy value into $x
                                      $a    # Leave $a on pipeline; implicit output

-5 байт благодаря маззи.
Замена -1 байта $_на1


Сохраняет ли сплаттинг 3 байта $agrs? :)
Маззи

-2 байта $args|%{$x,$a=&({$_,$_+$a},{$a})[!$_]};$a?
Маззи

1
@mazzy Да, и мы только что говорили о брызгах! Я уже забыл! лол спасибо!
AdmBorkBork

Не было бы сплаттинга .\implement-stack.ps1 @z(не $z), иначе вы просто передаете массив в качестве первого / единственного аргумента
pinkfloydx33

@ pinkfloydx33 Да. Опечатка с моей стороны.
AdmBorkBork

11

C (gcc) , 62 60 56 55 байтов

-2 -6 байт благодаря l4m2

-1 байт благодаря потолку .

Использует разрешенное понятие -1 завершенных массивов. f()вызывает себя рекурсивно, пока полностью не обмотается, а затем возвращается назад по списку. rотслеживает, сколько чисел нужно отбросить, прежде чем что-то печатать. Увеличивается, если текущий предмет равен 0, иначе уменьшается. Если 0, нам не нужно сбрасывать, и мы можем напечатать число.

r;f(int*l){~*l?f(l+1),*l?r?r--:printf("%d ",*l):r++:0;}

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


f(l)int*l;=> f(int*l)?
l4m2

@ l4m2 Ах, ура! Вероятно, остаток от более ранних, более изменчивых дней.
Гастропнер

r=0кажется бесполезным
l4m2

@ l4m2 Да, хороший улов.
Гастропнер


10

R , 45 байт

o={};for(e in scan())o="if"(e,c(e,o),o[-1]);o

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

  • -4 байта благодаря @Giuseppe

1
48 байтов - злоупотребление Fтакже даст вам 48 байтов, но это чище, имхо
Джузеппе

Я не знаю, как я пропустил инверсию if-else: facepalm: ... спасибо!
digEmAll


1
А R+pryrи Reduceрешение составляет 44 байта
JayCe

@JayCe: если честно, я предпочитаю оставить это решение "base-R" ... но не стесняйтесь публиковать его как свой собственный ответ! ;)
digEmAll


9

Желе , 6 байт

ṣ0Ṗ;¥/

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

Как это работает

ṣ0Ṗ;¥/  Main link. Argument: A (array)

ṣ0      Split A at zeroes.
    ¥/  Left-reduce the resulting 2D array by this dyadic chain:
  Ṗ       Pop; discard the last element of the left argument.
   ;      Concatenate the result with the right argument.

Будет ли это эмулировать три всплывающих окна, если есть три последовательных нуля?
WGroleau

Да. [1,3,7,0,0,0]Например, разделяется на [[1,3,7],[],[],[]], и каждый шаг влево-уменьшение появляется на элементе левого массива.
Деннис

9

Brain-Flak , 40 36 байт

([]){{}{({}<>)<>}([]){{}<>}{}([])}<>

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

Спасибо @Nitrodon за -4 байта.

Поскольку Brain-Flak уже использует стеки, это хорошая головоломка для Brain-Flak.

([]){   while items on stack
    {}      pop stack count
    {       if top element is non-zero
        ({}<>)<> push it on the other stack
    }
    if we're here the stack is either empty or there's a 0 on the stack

    ([])    so, count the stack again
    {{}<>{}<>} if there are items left on the stack, pop the stack count and the last item of the other stack
    {} pop the zero or the stack count
    ([]) count the stack again for next round
}
<>  go to the output stack

2
В этом конкретном случае, {{}<>{}<>}может быть сокращено до {{}<>}.
Нитродон

@Nitrodon Спасибо. Можете ли вы объяснить, почему это все еще работает? Он не переключается обратно на входной стек в цикле.
Дориан

1
Вершина стека вывода гарантированно не равна нулю, поэтому укороченный цикл выполняется 0 или 2 раза.
Нитродон

8

Wolfram Language (Mathematica) , 28 байт

#//.{a___,b_,0,c___}:>{a,c}&

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


(это работает только потому, что «по умолчанию ранние шаблоны соответствуют самым коротким последовательностям» , поэтому нет необходимости гарантировать, что он не bравен нулю.)
user202729

@ user202729 Да. Сопоставление с образцом в Mathematica не является жадным, поэтому a___сначала оно пытается найти самое короткое из возможных . Это можно увидеть, попробовав ReplaceList[#, {a___, b_, 0, c___} :> {a, c}] &. На связанной ноте, StringReplaceна самом деле является жадным, так что это представление не будет работать StringReplace(с шаблоном, как a___~~b_~~"0"~~c___)
JungHwan Мин

8

Python 2 , 48 байт

s=[]
for x in input():s=([x]+s)[2*0**x:]
print s

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


Есть ли шанс, что вы можете объяснить, как это работает? Я пытался решить это в течение последних получаса! Конечно 2*0**x, всегда будет 0. Я явно что-то упускаю.
ElPedro

1
@ElPedro Это не ноль, когда x=0, в этом случае это 2.
xnor

Ах, я понимаю, что вы имеете в виду. Думаю, я искал слишком усердно и упускал очевидное! Спасибо и отличный ответ.
ElPedro

7

Пробел , 89 байт

[N
S S N
_Create_Label_LOOP_1][S S S N
_Push_0][S N
S _Duplicate_0][T   N
T   T   _Read_STDIN_as_integer][T   T   T   _Retrieve][S N
S _Duplicate_input][N
T   T   S 
_If_neg_Jump_to_Label_EXIT][S N
S _Duplicate_input][N
T   S T N
_If_0_Jump_to_Label_DROP][N
S N
N
_Jump_to_Label_LOOP_1][N
S S S N
_Create_Label_EXIT][S N
N
_Discard_top][N
S S S S N
_Create_Label_LOOP_2][T N
S T _Print_as_integer][S S S T  S T S N
_Push_10_newline][T N
S S _Print_as_character][N
S T S S N
_Jump_to_Label_LOOP_2][N
S S T   N
_Create_Label_DROP][S N
N
_Discard_top][S N
N
_Discard_top][N
S N
N
_Jump_to_Label_LOOP_1]

Буквы S(пробел), T(табуляция) и N(новая строка) добавляются только как подсветка.
[..._some_action]добавлено только в качестве объяснения.

Занимает новую строку входного списка, разделенную с, -1чтобы указать, что мы закончили с вводами.

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

Объяснение в псевдокоде:

Start LOOP_1:
  Integer i = STDIN as integer
  If(i is negative):
    Call function EXIT
  If(i is 0):
    Call function DROP
  Go to next iteration of LOOP_1

function EXIT:
  Start LOOP_2:
    Pop and print top as integer
    Print newline
    Go to next iteration of LOOP_2

function DROP:
  Drop the top of the stack
  Go to next iteration of LOOP_1


6

JavaScript, 40 байт

Выходы в обратном порядке.

a=>a.map(x=>x?o.push(x):o.pop(),o=[])&&o

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

1 байт сохранен благодаря Herman L .


a=>a.map(x=>x?o.push(x):o.pop(),o=[])&&oна один байт короче
Герман Л

@HermanL: D'oh! Конечно, это является! Спасибо. Использовал (un)shiftдо того, как я заметил выход может быть полностью изменен.
Лохматый

Это работает, потому что на oнего ссылаются в обратном вызове после того, как он определен во втором аргументе.
MattH

6

05AB1E , 9 байтов

vy>i¨ëy)˜

Попробуйте онлайн или проверьте все контрольные примеры .

Объяснение:

v        # For-each of the items in the input-list:
 y>i     #  If the current item is 0:
  ¨      #   Pop the top item of the list
 ë       #  Else:
  y      #   Push the current item to the stack
   )     #   Wrap the entire stack into a list
         #    i.e. 12 → [12]
         #    i.e. [12] and 3 → [[12], 3]
    ˜    #   Flatten the stack
         #    i.e. [[12], 3] → [12, 3]
         # (and output the list implicitly after the loop)

Альтернатива 9 байтов :

vy_i\ëy])

Попробуйте онлайн для проверки всех тестовых случаев .

Объяснение:

v        # For-each of the items in the input-list:
 y_i     #  If the current item is 0:
  \      #   Discard top item of the stack
 ë       #  Else:
  y      #   Push the current item to the stack
]        # Close both the if-else and for-each (short for `}}`)
 )       # Wrap the entire stack into a list (and output implicitly)

PS: Если выходные данные должны были быть обращены, чтобы соответствовать тестовым примерам в описании вызова, мы можем добавить трейлинг Rко второй версии (так, 10 байтов ), который переворачивает список. Попробуйте онлайн или проверьте все контрольные примеры .


5

Сетчатка 0.8.2 , 18 байт

^
,
+1`,\d+,0

^,

Попробуйте онлайн! Ссылка включает в себя тестовые случаи. Объяснение:

^
,

Префикс доп ,.

+1`,\d+,0

Обрабатывать все поп-операции.

^,

Удалить, ,если он все еще там.

Изменение чисел обойдется в дополнительные 8 байтов:

O^$`\d+

Который просто заменяет весь <number>, 0подсписок ничем.
user202729




5

V , 10 байт

ò/ 0⏎b2dw0

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

объяснение

ò           " run the following, until an error occurs
 / 0⏎       " | goto next zero with space in front (errors if none)
     b      " | jump one word back (to the beginning of element to pop)
      2     " | twice (element & zero itself)
       dw   " | | delete word
         0  " | goto beginning of line

Эквивалент в Vim , 16 байтов

qq/ 0⏎b2dw0@qq@q

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

объяснение

Практически то же самое, за исключением записи макроса qи рекурсивного вызова его:

qq                " record macro q
  / 0⏎b2dw0       " same as in V
           @q     " recursively call q (aborts on error)
             q    " quit recording
              @q  " execute the macro q

5

Java 10, 75 72 байта

n->{var s="";for(int i:n)s=(s+","+i).replaceAll(",\\d+,0","");return s;}

Выходы разделены запятой. Вершина стека является последней. Попробуйте это онлайн здесь .

Спасибо Оливье Грегуару за игру в гольф 2 байта.

Пожалуйста, ознакомьтесь с ответами Кевина Круйссена и Оливье Грегуара на Java. Вместо этого они используют подход, основанный на списках, причем последний опережает мой с опрятным запасом.

Ungolfed:

n -> { // lambda taking an integer array as argument and returning a String
    var s = ""; // we'll be using a String to implement and output the stack
    for(int i : n) // loop through the array
        s = (s + "," + i) // append the next number
               .replaceAll(",\\d+,0", ""); // remove any number followed by a zero
    return s; // output the resulting stack
}

Хороший подход со строками. Лучше, чем мой наивный подход с реальным Stack-объектом. +1 от меня.
Кевин Круйссен

1
n->{var s="";for(int i:n)s=(s+","+i).replaceAll(",\\d+,0$","");return s;}(73 байта), но ставит числа ,перед, а не после.
Оливье Грегуар,

1
n->{var s=""+n;for(int x:n)s=s.replaceFirst("\\d+, 0,? ?","");return s;}(72 байта), использует список, а не массив и портит выходные данные, потому что он может возвращать такие вещи, как "[, 2]"
Оливье Грегуар

@ OlivierGrégoire Ницца. Мы можем отбросить, $чтобы сохранить дополнительный байт, так как каждый 0добавленный нами удаляется сразу.
OOBalance

@ OlivierGrégoire Ваш второй подход также интересен, но я думаю, что несовместимый формат вывода может сделать решение недействительным.
OOBalance


5

Perl 5 -p , 17 байт

Спасибо @sundar и @DomHastings

s/\d+ 0 ?//&&redo

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


1
-2 байта (с немного более сложным выводом): попробуйте онлайн!
sundar - Восстановить Монику

В дополнение к комментарию @ sundar, еще одно небольшое упрощение: попробуйте онлайн!
Дом Гастингс

Разве это не сбой, если есть число, например, 0942?
Xcali

1
Вы можете с уверенностью предположить, что не будет никаких ведущих нулей.
OOBalance

5

> <> , 25 байт

i:?\~~
(0:/:^?
!?l:!<oan;

Попробуйте онлайн! (ввод должен быть написан в ascii. в противном случае используйте этот )

Как это работает

i:?\~~проверяет на 0, продолжает ~~удалять предыдущую запись. в противном случае перейдите к:

(0:/:^? который проверяет -1 (больше не вводит), затем завершает, чтобы удалить -1 и цикл:

!?l:!<oan; который выводит каждое число с новой строки, а затем заканчивается, когда стек очищается



5

Шелуха , 6 байт

Так как ответа Хаска уже нет, и это мой любимый гольф:

F`?:tø

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

объяснение

F`?:tø  --
F    ø  -- foldl (reduce) with [] as the initial accumulator
 `      -- | flip arguments of
  ?:    -- | | if truthy: apply cons (prepend) to it
    t   -- | | else: return tail
        -- | : returns a function, either prepending the element or dropping 1 element

Альтернативное решение, 6 байтов

Вместо переворачивания мы также можем просто перевернуть список и затем использовать правое сгибание: Ḟ?:tø↔


5

брейкфук , 214 150 байт

>>,[>++++++[-<-------->]+<[>+++++[-<++++++++>]]>[-<<<[[-]<],[-]>>>>-<<]>>+[<<+<,----------[++++++++++>-]>[->>-<]>[->+<]>]<<<,]<<[[<]++++++++++<]>>[.>]

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

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

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

Stack format:
0 (0 \d*)*


>>,[
    Setup digit == '0' conditional
    >++++++
    [-<-------->]
    +
    <[
        Read digit != '0'
        Restore the char code
        cond1 is already 1 at this stage
        >+++++
        [-<++++++++>]
    ]>[
        Read digit == '0'
        -
        Pop previous value
        <<<[
            [-]<
        ]
        Skip next input (assumed to be newline)
        ,[-]
        Skip following loop by unsetting loop flag
        >>>>-
        <<
    ]

    Move to next stack frame
    >
    Set loop flag
    >+[
        Set bit used for conditional
        <<+
        Read next character
        <,
        Compare with '\n'
        ----------[
            Not '\n': restore the char code
            ++++++++++

            >-
        ]>[
            -
            == '\n': Leave as 0
            Unset loop flag
            >>-
            <
        ]

        Copy loop flag along
        >
        [- > + <]

        Move to loop flag of next stack frame
        >
    ]

    <<<
,]


Fill in with newlines
<<[
    Skip to the cell before this value
    [<]
    Put a newline in there
    ++++++++++
    Move to next value
    <
]

Now the tape has the exact values we need to output
>>[.>]

5

Брахилог , 21 байт

~c₃Ckt[İ,0]≠∧C⟨hct⟩↰|

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

-1 байт, и что более важно, это выглядит как гораздо менее неуклюжий способ сделать это.

~c₃                     % Partition the input into 3 subarrays
   C                    % Call that array-of-arrays C
    kt[İ,0]             % Its second element should be of the form [Integer, 0]
           ≠            % And its elements shouldn't be equal (i.e. 
                        %   the Integer shouldn't be 0)
            ∧C⟨hct⟩     % Then, remove that [İ, 0] element from C
                   ↰    % And call this predicate recursively
                    |   % When the above fails (when it can't find a partition with 
                        %  [İ, 0] in it), then just output the input

Альтернатива 21 байт: ∋0∧ℕ₁;0;P↺c;Qc?∧P,Q↰| попробуйте онлайн!


Старый код:

22 байта

∋0&b,1;?z{=|¬∋0&}ˢtᵐ↰|

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

∋0           If input contains a 0, 
&b           Remove input's first element, getting list of "next" elements
,1           Append 1 to that to handle last element
;?z          Zip that with input
{      }ˢ    Select only zipped pairs where
 =|          both elements are equal (to keep 0s followed by 0s)
   ¬∋0&      or the pair doesn't contain a 0
             this removes both the (pairs containing the) value
              that is followed by a 0, and the 0 itself
tᵐ           Recover back the (filtered) input array elements from the zip
↰            Call this predicate recursively 
|            If input contains no 0s, input is the output 

5

Предупреждение: много строк. Вы были предупреждены.


CJam , 17 байт

Наиболее опасный код
(Предполагается, что элементы стека могут быть разделены только пробелами в выводе, и что входной массив может быть любой формы, которую мы хотим)

q~{X0={;}X?}fX]S*

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

объяснение

q                                    Reads input string
 ~                                   Instantly convert to array since the string is in the CJam format
  {        }fX                       For loop
   X0=                               If X (the array element currently being checked) is equal to 0
      {;}                            Pop the top element from the stack
         X                           Else push X onto the top of the stack
          ?                          If-Else flag
              ]                      Collate all stack elements into an array
               S*                    Put a space between each array element

Альтернативный код № 1, 27 байт
(предполагается, что элементы стека должны быть выведены в формате, показанном в вопросе, и что входной массив может иметь любую форму, какую мы пожелаем)

q~{X0={;}X?}fX]',S+*'[\+']+

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

объяснение

q                                    Reads input string
 ~                                   Instantly convert to array since the string is in the CJam format
  {        }fX                       For loop
   X0=                               If X (the array element currently being checked) is equal to 0
      {;}                            Pop the top element from the stack
         X                           Else push X onto the top of the stack
          ?                          If-Else flag
              ]                      Collate stack items into an array
               ',S+                  Add together a comma and a space to create a delimiter
                   *                 Apply the delimiter to the stack
                    '[\+             Append left bracket to the left of the stack text
                        ']+          Append right bracket to the right of the stack text

Альтернативный код # 2, 24 байта
(предполагается, что элементы стека могут быть сопоставлены в выходных данных и что входной массив должен быть в точном формате, указанном в вопросе)

q',/~]S*~{X0={;}X?}fX]S*

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

объяснение

q                        Read input string
 ',/                     Separate by commas (since commas are an invalid array delimiter in CJam)
    ~                    Turn string into an array of substrings that make up the array
     ]S*                 Add spaces in between input numbers to prevent collation in the array
        ~                Turn the string into a valid array representative of the original
         {        }fX    For loop
          X0=            If X (the array element currently being checked) is equal to 0
             {;}         Pop the top element from the stack
                X        Else push X onto the top of the stack
                 ?       If-Else flag
                     ]   Collate all stack elements into an array
                      S* Add a space between each element

Самый безопасный код для этого, 34 байта
(предполагается, что элементы стека должны быть выведены в формате, показанном в вопросе, и что входной массив должен быть в точном формате, показанном в вопросе)

q',/~]S*~{X0={;}X?}fX]',S+*'[\+']+

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

объяснение

q                                      Read input string
 ',/                                   Separate by commas (since commas are an invalid array delimiter in CJam)
    ~                                  Turn string into an array of substrings that make up the array
     ]S*                               Add spaces in between input numbers to prevent collation in the array
        ~                              Turn the string into a valid array representative of the original
         {        }fX                  For loop
          X0=                          If X (the array element currently being checked) is equal to 0
             {;}                       Pop the top element from the stack
                X                      Else push X onto the top of the stack
                 ?                     If-Else flag
                     ]                 Collate stack items into an array
                      ',S+             Add together a comma and a space to create a delimiter
                          *            Apply the delimiter to the stack
                           '[\+        Append left bracket to the left of the stack text
                               ']+     Append right bracket to the right of the stack text

Спасибо @Jo King за то, что он указал, что те, у которых есть сопоставленный результат, недействительны, поскольку такие вещи, как [12]и [1,2]будут неразличимы.

Также спасибо @Jo King, который предоставил очень подходящую альтернативу для сопоставленных выходных данных и обрезал 9 байтов!


1
Первый недействителен, так как вы не можете определить разницу между [12]и [1,2]. Тем не менее, 27-байтовая версия выглядит хорошо, хотя вы можете избавиться от пробелов и скобок для 18 байт
Джо Кинг,

о, конечно, я так глуп, большое спасибо
Хелен

Однако, вероятно, было бы более любопытно разделить числа пробелами, а не запятыми, так как пробелы используют ]S*(3), тогда как запятые используют ]',*(4)
Хелен

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