Implementing a stack

44

3

I can't believe we don't have this already.. It's one of the most important data-structures in programming, yet still simple enough to implement it in a :

Challenge

Your task is to implement a stack that allows pushing and popping numbers, to test your implementation and keep I/O simple we'll use the following setup:

  • Input will be a list of non-negative integers

Every positive integer \$n\$ indicates a \$\texttt{push(}n\texttt{)}\$ and every \$0\$ indicates a \$\texttt{pop()}\$ - discarding the top element.

  • Output will be the resulting stack

Example

For example if we're given \$[12,3,0,101,11,1,0,0,14,0,28]\$:

$$ \begin{aligned} & 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] \end{aligned} $$

Output will be: \$[28,101,12]\$

Rules

  • Input will be a list of non-negative integers in any default I/O format
    • you may use a negative integer to signify the end of a stream of integers
  • Output will be a list/matrix/.. of the resulting stack
    • your choice where the top element will be (at the beginning or end), the output just has to be consistent
    • output is flexible (eg. integers separated by new-lines would be fine), the only thing that matters is the order
    • you may use a negative integer to signify the bottom of the stack
  • You're guaranteed that there will never be a \$0\$ when the stack is empty

Examples

[] -> []
[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]

ბიმო

Posted 2018-07-27T11:27:25.810

Reputation: 15 345

12It should be noted that, given the conditions, one does not actually need to implement the stack. – Jeff Zeitlin – 2018-07-27T11:35:00.953

If you wanted someone to actually implement a stack, you might need to try putting something in the Sandbox. – mbomb007 – 2018-07-27T16:33:30.370

@mbomb007: Either is allowed: "your choice where the top element will be (at the beginning or end)" – ბიმო – 2018-07-27T16:49:32.337

@mbomb007: It wouldn't be any more difficult if you had to reverse the input, would it? Besides, if you consider the setup as a stack who defines what's the top and what's the bottom and why should one definition be less arbitrary? – ბიმო – 2018-07-27T16:57:45.767

@OMᗺ Because the input looks quite a bit like a stack/list/array. Now, the entire challenge is basically remove any number followed by a zero. – mbomb007 – 2018-07-27T18:10:38.220

@mbomb007: It's not though, what about [1,2,0,0]? – ბიმო – 2018-07-27T19:56:57.023

Look at my answer in Retina. In pseudo-code: Loop: remove the first #,0 and you're done. So you remove 2,0, then remove 1,0.

– mbomb007 – 2018-07-27T20:23:48.207

Let us continue this discussion in chat.

– ბიმო – 2018-07-27T20:25:49.363

Related – xnor – 2018-07-27T21:40:24.557

We don't usually like to make different rules for different languages. Your spec says "if your language doesn't […] support […] lists, …" – would you consider opening this option to all languages? As @Titus pointed out, Python has perfectly good support for lists, yet you seem OK with a Python answer using negatives. – O.O.Balance – 2018-07-28T16:08:38.667

@O.O.Balance: I completely forgot that I restricted it, sorry about that.. (updated) – ბიმო – 2018-07-28T16:11:27.640

Is a terminating character allowed for the output? For the given example, is [28, 101, 12, 0] allowed? – Jon Claus – 2018-07-31T20:39:57.590

@JonClaus: Why did you change your question after I allowed it (something else)? That's not cool! I'll allow a negative integer marking the bottom of the stack, as was originally asked for since it's also allowed to mark end of input. Also, welcome to PPCG! – ბიმო – 2018-07-31T20:59:04.283

@OMᗺ Sorry about the switch from -1 to 0. I figured both were equivalent for the purposes of an answer because neither is a possible value in the stack, which can only contain positive integers. – Jon Claus – 2018-07-31T21:03:14.377

Answers

19

MATL, 6 bytes

"@?@}x

Input is a row vector of numbers.

The final stack is shown upside down, with the most recent element below.

Try it online! Or verify all test cases.

Explanation

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

Luis Mendo

Posted 2018-07-27T11:27:25.810

Reputation: 87 464

13

Java (JDK 10), 42 bytes

Since "[the] output is flexible [...], the only thing that matters is the order", this changes the input array into a 0-terminated array. Example : [1,0,2] will return [2,0,2] which is to be interpreted as [2,0,2] = [2].

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

Try it online!

Previous versions:

Java (JDK 10), 60 bytes

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

Try it online!

Credits:

If I can end the program with errors: 55 bytes

(though everything is properly modified)

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

Try it online!

Olivier Grégoire

Posted 2018-07-27T11:27:25.810

Reputation: 10 647

4This is rather impressive. You can lose 1 byte by using >0 since there will never be a zero at the start of the list (that would imply the top of the stack was at -1). – O.O.Balance – 2018-07-28T01:07:47.433

@O.O.Balance Indeed, I hadn't thought about that., thanks! – Olivier Grégoire – 2018-07-28T07:31:16.583

12

PowerShell, 46 41 40 bytes

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

Try it online!

Takes input via splatting, e.g., $z=@(12,3,0,101,11,1,0,0,14,0,28); .\implement-stack.ps1 @z, which on TIO manifests as separate arguments.

$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 bytes thanks to mazzy.
-1 byte swapping $_ to 1

AdmBorkBork

Posted 2018-07-27T11:27:25.810

Reputation: 41 581

Does a splatting save 3 bytes on $agrs? :) – mazzy – 2018-07-27T17:21:16.473

-2 bytes $args|%{$x,$a=&({$_,$_+$a},{$a})[!$_]};$a? – mazzy – 2018-07-27T17:48:44.873

1@mazzy Yes, and we had just talked about splatting! I forgot already! lol Thanks! – AdmBorkBork – 2018-07-27T19:22:39.010

Wouldn't splatting be .\implement-stack.ps1 @z (not $z), otherwise you're just passing an array as the first/only argument – pinkfloydx33 – 2018-07-31T22:23:12.427

@pinkfloydx33 Yep. Typo on my part. – AdmBorkBork – 2018-08-01T12:27:42.267

12

Sed, 17 Bytes

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

-3 bytes thanks to @OMᗺ, -1 thanks to @eggyal

Because you're guaranteed to never pop an empty list, you don't need anything more than an iterated finite state machine. Regular expressions are a tool for building finite state machines, and sed can iterate. It's a match made in heaven.

Takes input from stdin, like so:

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

Outputs the stack in reverse:

[12,101,28]

Could be smaller by two bytes if my local sed inherently understood character classes like \d, but it doesn't for some reason.

Tacroy

Posted 2018-07-27T11:27:25.810

Reputation: 221

1

Welcome to PPCG! Nice, mine was longer (using different input format).. Btw. you can use an empty label since you only use 1 and since you iterate the process the g is redundant - saving you 4 bytes: Try it online!

– ბიმო – 2018-07-27T15:36:19.403

The g isn't redundant! It makes the worst case runtime complexity depend on the depth of sequential pops, instead of the number of pops! Not that efficiency matters in code golf :) – Tacroy – 2018-07-27T15:43:16.303

1Your last sentence answers the question about redundancy :P Btw. how did you count the bytes? I get 18, probably you included a new-line at the end or something. – ბიმო – 2018-07-27T16:06:01.033

Yup, it was a newline. – Tacroy – 2018-07-27T16:20:25.107

1If the final element of the input is a 0 then it won’t get matched by your regex. – eggyal – 2018-07-28T04:38:30.460

Similar to the Retina answer.

– user202729 – 2018-07-28T10:37:07.523

(as pointed out above) this fails for [1,0]. – user202729 – 2018-07-28T10:38:45.957

ya, I just hope nobody tries to use numbers in octal. – Tacroy – 2018-07-28T12:22:29.040

You can use \w instead of [0-9] and you may be able to cut down the \+ to * – user41805 – 2018-07-30T07:35:35.107

11

C (gcc), 62 60 56 55 bytes

-2 -6 bytes thanks to l4m2

-1 byte thanks to ceilingcat.

Uses the permitted notion of -1 terminated arrays. f() calls itself recursively, until fully wound, and then backtracks through the list. r keeps track of how many numbers to discard before printing something. Increases if current item is 0, decreases otherwise. If 0, we need not discard, and can print the number.

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

Try it online!

gastropner

Posted 2018-07-27T11:27:25.810

Reputation: 3 264

f(l)int*l; => f(int*l)? – l4m2 – 2018-07-28T12:39:55.467

@l4m2 Ah, cheers! Probably a remnant from earlier, more variable-laden days. – gastropner – 2018-07-28T13:10:05.897

the r=0 seems useless – l4m2 – 2018-07-28T15:52:26.940

@l4m2 Aye, good catch. – gastropner – 2018-07-28T16:11:58.230

10

R, 45 bytes

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

Try it online!

  • -4 byte thanks to @Giuseppe

digEmAll

Posted 2018-07-27T11:27:25.810

Reputation: 4 599

148 bytes -- abusing F will also get you to 48 bytes but this is cleaner imho – Giuseppe – 2018-07-27T14:33:15.007

I don't know how I missed the if-else inversion :facepalm: ... thanks ! – digEmAll – 2018-07-27T16:46:55.983

45 bytes – Giuseppe – 2018-08-01T14:55:16.250

1

A R+pryr and Reduce solution is 44 bytes

– JayCe – 2018-08-10T18:51:48.167

@JayCe: to be honest, I prefer to keep it a "base-R" solution... but feel free to post it as your own answer ! ;) – digEmAll – 2018-08-10T20:40:01.457

I totally understand... I don't post non-base R very often either... will do! – JayCe – 2018-08-11T02:03:17.177

10

Haskell, 28 bytes

foldl(#)[]
(_:s)#0=s
s#n=n:s

Try it online!

nimi

Posted 2018-07-27T11:27:25.810

Reputation: 34 639

How main function is named? I don't know, how to run it) – Евгений Новиков – 2018-08-11T17:12:56.733

@ЕвгенийНовиков: see the "try it online" link for an example of how to run the code. – nimi – 2018-08-11T23:26:42.490

9

Brain-Flak, 40 36 bytes

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

Try it online!

Thanks to @Nitrodon for -4 bytes.

Since Brain-Flak already uses stacks, this is a good puzzle for 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

Dorian

Posted 2018-07-27T11:27:25.810

Reputation: 1 521

2In this particular case, {{}<>{}<>} can be shortened to {{}<>}. – Nitrodon – 2018-07-27T19:46:21.543

@Nitrodon Thank you. Can you explain, why this still works? It doesn't switch back to the input stack in the loop. – Dorian – 2018-07-28T17:09:37.097

1The top of the output stack is guaranteed to be nonzero, so the shortened loop executes either 0 or 2 times. – Nitrodon – 2018-07-29T18:39:01.540

9

Python 2, 59 57 51 bytes

s=[]
for x in input():s=(s+[x],s[:-1])[x<1]
print s

Try it online!

ElPedro

Posted 2018-07-27T11:27:25.810

Reputation: 5 301

9

Jelly, 6 bytes

ṣ0Ṗ;¥/

Try it online!

How it works

ṣ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.

Dennis

Posted 2018-07-27T11:27:25.810

Reputation: 196 637

Will this emulate three pops if there are three consecutive zeros? – WGroleau – 2018-07-28T05:29:58.297

Yes. [1,3,7,0,0,0], e.g., gets split into [[1,3,7],[],[],[]], and each step of the left-reduce pops on element of the left array. – Dennis – 2018-07-28T15:44:17.053

8

Wolfram Language (Mathematica), 28 bytes

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

Try it online!

JungHwan Min

Posted 2018-07-27T11:27:25.810

Reputation: 13 290

(this only works because "The default is to have earlier patterns match shortest sequences", so there is no need to ensure that b is nonzero.)

– user202729 – 2018-07-27T13:23:32.257

@user202729 Yep. Mathematica's pattern-matching is non-greedy, so it tries to match the shortest possible a___ first. One can see that by trying ReplaceList[#, {a___, b_, 0, c___} :> {a, c}] &. On a related note, StringReplace is actually greedy, so this submission wouldn't work with StringReplace (with pattern like a___~~b_~~"0"~~c___) – JungHwan Min – 2018-07-27T13:26:38.140

8

Python 2, 48 bytes

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

Try it online!

xnor

Posted 2018-07-27T11:27:25.810

Reputation: 115 687

Any chance you can explain how this works? I have been trying to work it out for the last half hour! Surely 2*0**x is always going to be 0. I'm obviously missing something. – ElPedro – 2018-07-28T22:12:59.330

1@ElPedro It's not zero when x=0, in which case it's 2. – xnor – 2018-07-28T22:20:19.250

Ah, I see what you mean. Guess I was looking too hard and missing the obvious! Thanks and great answer. – ElPedro – 2018-07-28T22:25:36.303

7

Python 2, 60 59 57 56 bytes

l=input()
while 0in l:i=l.index(0);l[i-1:i+1]=[]
print l

Try it online!


Saved:

  • -1 byte, thanks to pushkin

TFeld

Posted 2018-07-27T11:27:25.810

Reputation: 19 246

You can save a byte by removing the space between 0 and in – pushkin – 2018-07-27T17:48:39.787

2Congrats on the 10K – ElPedro – 2018-07-28T09:10:02.923

7

Whitespace, 89 bytes

[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]

Letters S (space), T (tab), and N (new-line) added as highlighting only.
[..._some_action] added as explanation only.

Takes the input-list new-line separated with -1 to indicate we're done with the inputs.

Try it online.

Explanation in pseudo-code:

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

Kevin Cruijssen

Posted 2018-07-27T11:27:25.810

Reputation: 67 575

6

JavaScript, 40 bytes

Outputs in reverse order.

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

Try it online

1 byte saved thanks to Herman L.

Shaggy

Posted 2018-07-27T11:27:25.810

Reputation: 24 623

a=>a.map(x=>x?o.push(x):o.pop(),o=[])&&o is one byte shorter – Herman L – 2018-07-27T12:27:09.610

@HermanL: D'oh! Of course it is! Thanks. Was using (un)shift before I spotted output could be reversed. – Shaggy – 2018-07-27T12:40:16.160

This works because o is referenced in the callback after it's defined in the second argument. – MattH – 2018-07-27T13:48:37.337

6

05AB1E, 9 bytes

vy>i¨ëy)˜

Try it online or verify all test cases.

Explanation:

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 bytes alternative:

vy_i\ëy])

Try it online of verify all test cases.

Explanation:

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: If the output should have been reversed to match the test cases in the challenge description, we can add a trailing R to the second version (so 10 bytes), which reverses the list. Try it online or verify all test cases.

Kevin Cruijssen

Posted 2018-07-27T11:27:25.810

Reputation: 67 575

5

Retina 0.8.2, 18 bytes

^
,
+1`,\d+,0

^,

Try it online! Link includes test cases. Explanation:

^
,

Prefix an extra ,.

+1`,\d+,0

Process all pop operations.

^,

Remove the , if it's still there.

Reversing the numbers would cost an extra 8 bytes:

O^$`\d+

Neil

Posted 2018-07-27T11:27:25.810

Reputation: 95 035

Which simply replaces all <number>, 0 sublist by nothing. – user202729 – 2018-07-27T12:53:21.913

5

Java 10, 75 72 bytes

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

Outputs separated by a comma. Top of the stack is last. Try it online here.

Thanks to Olivier Grégoire for golfing 2 bytes.

Please check out Kevin Cruijssen's and Olivier Grégoire's Java answers as well. They take a list-based approach instead, with the latter beating mine by a tidy margin.

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
}

O.O.Balance

Posted 2018-07-27T11:27:25.810

Reputation: 1 499

Nice approach with Strings. Better than my naive approach with an actual Stack-object. +1 from me. – Kevin Cruijssen – 2018-07-27T13:20:02.683

1n->{var s="";for(int i:n)s=(s+","+i).replaceAll(",\\d+,0$","");return s;} (73 bytes), but puts the , before numbers, not after. – Olivier Grégoire – 2018-07-28T00:19:09.080

1n->{var s=""+n;for(int x:n)s=s.replaceFirst("\\d+, 0,? ?","");return s;} (72 bytes), uses a list rather than an array and messes with the output because it can return things like "[, 2]" – Olivier Grégoire – 2018-07-28T00:35:25.493

@OlivierGrégoire Nice. We can drop the $ to save an additional byte, since each 0 we add is removed right away. – O.O.Balance – 2018-07-28T00:41:25.060

@OlivierGrégoire Your second approach is interesting as well, but I think the inconsistent output format may invalidate the solution. – O.O.Balance – 2018-07-28T01:00:43.957

5

Ruby, 36 bytes

->a{b=[];a.map{|x|x>0?b<<x:b.pop};b}

Try it online!

Anonymous lambda. Outputs in reverse order.

Kirill L.

Posted 2018-07-27T11:27:25.810

Reputation: 6 693

5

Brain-Flak, 36 bytes

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

Try it online!

#Let's call the two stacks in and out

([]){{}                      ([])}    # while not in.empty()
       {        (  )}{}               # if in.peek() != 0
        (({}<>)) <>                   # a = in.pop; out.push(a); out.push(a)
                       <>{}<>         # out.pop()
                                  <>  # switch to out to be printed

Riley

Posted 2018-07-27T11:27:25.810

Reputation: 11 345

5

Brain-Flak, 32 bytes

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

Try it online!

Uses -1 to signify the end of the array (but any number will do really).

Jo King

Posted 2018-07-27T11:27:25.810

Reputation: 38 234

5

Brachylog, 21 bytes

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

Try it online!

-1 byte, and more importantly this feels like a much less clunky way of doing this.

~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

Alternate 21 byter: ∋0∧ℕ₁;0;P↺c;Qc?∧P,Q↰| Try it online!


Older code:

22 bytes

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

Try it online!

∋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 

sundar - Reinstate Monica

Posted 2018-07-27T11:27:25.810

Reputation: 5 296

5

Perl 5 -p, 17 bytes

Thanks @sundar and @DomHastings

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

Try it online!

Xcali

Posted 2018-07-27T11:27:25.810

Reputation: 7 671

1

-2 bytes (with slightly mankier output): Try it online!

– sundar - Reinstate Monica – 2018-07-27T22:29:21.893

Further to @sundar's comment, another slight simplification: Try it online!

– Dom Hastings – 2018-07-28T07:08:25.553

Doesn't that fail if there's a number like 0942 input? – Xcali – 2018-07-29T03:28:37.450

1You can safely assume there will not be any leading zeros. – O.O.Balance – 2018-07-29T09:11:16.750

5

V, 10 bytes

ò/ 0⏎b2dw0

Try it online!

Explanation

ò           " 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

Equivalent in Vim, 16 bytes

qq/ 0⏎b2dw0@qq@q

Try it online!

Explanation

Pretty much the same, except recording a macro q and recursively call it:

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

ბიმო

Posted 2018-07-27T11:27:25.810

Reputation: 15 345

5

GolfScript, 14 12 bytes

~{.{;}if}/]`

Try it online!

~{.{;}if}/]` Full program, implicit input
~            Eval input
 {      }/   Foreach:
      if       If the value is truthy (!= 0):
  .              Push itself
   {;}         Else: pop the top value
          ]` Push as array representation
             Implicit output

wastl

Posted 2018-07-27T11:27:25.810

Reputation: 3 089

5

><>, 25 bytes

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

Try it online! (input must be written in ascii. otherwise use this one)

How it works

i:?\~~ checks for 0, continues to ~~ to delete previous entry. otherwise go down to:

(0:/:^? which checks for -1 (no more input), then wrap up to delete -1 and loop:

!?l:!<oan; which outputs each number with a newline, then ends when stack emptied

torcado

Posted 2018-07-27T11:27:25.810

Reputation: 550

22 bytes – Jo King – 2018-08-01T00:35:06.197

5

Husk, 6 bytes

Since there's no Husk answer already and it's my favourite golfing-lang:

F`?:tø

Try it online!

Explanation

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

Alternative solution, 6 bytes

Instead of flipping, we can also just reverse the list and then use a right-fold: Ḟ?:tø↔

ბიმო

Posted 2018-07-27T11:27:25.810

Reputation: 15 345

5

brainfuck, 214 150 bytes

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

Reads input as numbers separated by newlines. This must include a single trailing newline. Also expects no leading zeros on each number. Output as a similar newline separated list

Try it online!

Explanation that isn't really an explanation but is actually just the version I was working on with the comments and stuff which may or may not actually be useful to anyone

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
>>[.>]

Sasha

Posted 2018-07-27T11:27:25.810

Reputation: 431

5

Warning: Lots of lines ensue. You have been warned.


CJam, 17 bytes

Most dangerous code
(Assumes the stack elements can be separated by only spaces in the output and that the input array can be whatever form we wish)

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

Try it online!

Explanation

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

Alternate Code #1, 27 bytes
(Assumes stack elements have to be output in the format shown in the question and that the input array can be whatever form we wish)

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

Try it online!

Explanation

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

Alternate Code #2, 24 bytes
(Assumes the stack elements can be collated in the output and that the input array has to be in the exact format shown in the question)

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

Try it online!

Explanation

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

Safest code for this, 34 bytes
(Assumes stack elements have to be output in the format shown in the question and that the input array has to be in the exact format shown in the question)

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

Try it online!

Explanation

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

Thanks to @Jo King for pointing out that the ones with the collated output are invalid since things like [12] and [1,2] would be indistinguishable.

Thanks also to @Jo King providing a very suitable alternative for the collated outputs and cutting off 9 bytes!

Helen

Posted 2018-07-27T11:27:25.810

Reputation: 125

1

The first one isn't valid since you can't tell the difference between [12] and [1,2]. However, the 27 byte version seems alright, though you can get rid of the whitespace and brackets for 18 bytes

– Jo King – 2018-11-18T23:08:51.970

oh of course I'm so dumb many thanks – Helen – 2018-11-19T20:29:10.760

However it would probably be more golfy to separate numbers by spaces rather than commas since spaces uses ]S* (3) whereas commas use ]',* (4) – Helen – 2018-11-19T20:33:13.440

4

Red, 64 bytes

func[b][a: copy[]foreach n b[either n > 0[insert a n][take a]]a]

Try it online!

Galen Ivanov

Posted 2018-07-27T11:27:25.810

Reputation: 13 815

4

Java 10, 83 76 75 74 bytes

a->{for(int i=0;i<a.size();)if(a.get(i++)<1){a.remove(i-=2);a.remove(i);}}

-7 bytes thanks to @O.O.Balance.
-1 byte thanks to @OlivierGrégoire.

Modifies the input-List instead of returning a new one to save bytes.

Try it online.

Explanation:

a->{                        // Method with List parameter and no return-type
  for(int i=0;i<a.size();)  //  Loop `i` in the range [0, size)
    if(a.get(i++)<1){       //   If the current item is 0:
      a.remove(i-=2);       //    Remove the previous item
      a.remove(i);}}        //    As well as the current 0

Kevin Cruijssen

Posted 2018-07-27T11:27:25.810

Reputation: 67 575

1

76 bytes using your suggestion of taking a List and modifying it: https://bit.ly/2AeKMTb

– O.O.Balance – 2018-07-27T13:43:57.763

@O.O.Balance Thanks. Been able to golf one more byte by changing the position of the i++. – Kevin Cruijssen – 2018-07-27T13:57:09.493

1My answer is similar to this one, but 61 bytes only. – Olivier Grégoire – 2018-07-27T23:52:32.533

2a->{for(int i=0;i<a.size();)if(a.get(i++)<1){a.remove(i-=2);a.remove(i);}} (74 bytes) – Olivier Grégoire – 2018-07-28T00:05:52.473

4

Attache, 35 bytes

{y.=[]_:>{If[_>0,Push&_!y,Pop!y]}y}

Try it online!

Actually implements a stack! For the most part.

54 bytes for a "stackless" approach: Fixpoint!{Flat!{#_=1or _@1>0}\Chop[_,1+Rotate[_=0,1]]}. Didn't spend much time golfing it tho.

Explanation

y.=[] defines an array and _:>{...} iterates over the input array. For each element, we either push it if its > 0 or pop the last element. We return y at the end.

Conor O'Brien

Posted 2018-07-27T11:27:25.810

Reputation: 36 228

4

Lua, 141 124 bytes

loadstring'p=loadstring("return "..(...))()r={}t=table for i=1,#p do (0<p[i]and t.insert or t.remove)(r,1,p[i])end return r'

Try it online!


Explanation

p=loadstring("return "..(...))() -- deserializes the input ('{1, 2, 3}' becomes a table with 3 elements)
r={} -- initializes the result table
t=table -- just to decrease the number of bytes used
for i=1,#p do -- for each element on the input list (table)
  (0<p[i] and t.insert or t.remove)(r, 1, p[i])
   0<p[i] and t.insert   -- if the element (p[i]) is greater than 0 then 'y' is going to be the function table.insert
                       or t.remove -- else it's going to be the remove function
  (                               ) -- this defines which function will be called (insert or remove)

                                   (          ) -- these are the arguments
                                    r, 1, p[i] -- 'r' is the table, 1 is the position, p[i] is the element
                                    -- the insert function receives 3 arguments, the table which to insert, the position and the value
                                    -- the remove function only receives 2, the table and the position
                                    -- There's no problem with that because the third argument will be ignored
end
return r -- returns the 'r' table

This is an anonymous function.

I hope I did a decent job of explaining how it works hahah

Visckmart

Posted 2018-07-27T11:27:25.810

Reputation: 151

4

Japt, 14 bytes

;NË¥0?Ao:ApDÃA

Try it online!

Actual TIO doesn't work for some reason (it exits with an error, see here) so I've given a page to the ETHproductions' online Japt interpreter.

Amphibological

Posted 2018-07-27T11:27:25.810

Reputation: 1 394

11 bytes and in the right order. – Shaggy – 2018-07-29T07:25:46.250

@Shaggy are you planning to post it as your own answer? – Amphibological – 2018-07-29T14:25:34.230

TIO is fixed now :-) – ETHproductions – 2018-07-31T19:07:19.947

4

MarioLANG, 51 47 bytes

> ;+[!>(
"====#"
 (![-<:[
 =#=="!<
!)<   #=
#="

Try it online!

Uses -1 as mark for EOF. Explanation follows:

> ;+[!>     Mario walks to the left, reads an integer, adds 1 and checks if it's 0.
"====#"     If the value is not 0 Mario takes the elevator and starts walking to the left.
 (![-<      Mario takes 1 from the value and checks again if it's 0.
 =#=="      If so Mario skips the elevator and moves the pointer to the left, otherwise he
!)<         takes the elevator down and moves the pointer to the right. Either case
#="         Mario ends up taking the elevator to the start of the level.

>(    This is a loop to print what's left in the data values. Mario walks
"     to the right and falls, moving the pointer to the left and checking
:[    if the value pointed is 0. If it is, Mario skips the command to walk to the left and
!<    falls to end the level. Otherwise he walks to the left and takes the elevator,
#=    printing the value pointed as integer and continuing the loop.

Charlie

Posted 2018-07-27T11:27:25.810

Reputation: 11 448

3

C, 138 bytes

int main(int _,char**v){int n=0,*s=0,i;for(;*++v;){i=atoi(*v);if(i){s=realloc(s,n*4+4);s[n++]=i;}else n--;}while(n--)printf("%i ",s[n]);}

Taking advantage of implicit definitions for printf, atoi, etc, and saving an 'int' by declaring i with the other variables.

202 bytes

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int _,char**v){int n=0,*s=NULL;for(;*++v;){int i=atoi(*v);if(i){s=realloc(s,n*4+4);s[n++]=i;}else n--;}while(n--)printf("%i ",s[n]);}

Takes input as command line args, outputs to stdout.

Paul Belanger

Posted 2018-07-27T11:27:25.810

Reputation: 189

123 bytes: https://bit.ly/2LEvBXR

– O.O.Balance – 2018-07-27T12:47:23.623

Why are include guards not included in your total? – Paul Belanger – 2018-07-27T12:55:08.893

Because gcc does not require them for this program. If you want to keep them, you can still remove the spaces. But here on PPCG we define a language by its implementation; my golf would thus be C (gcc). – O.O.Balance – 2018-07-27T12:58:31.643

Save 1 more byte by replacing else n--; with else--n; – O.O.Balance – 2018-07-27T13:11:35.430

Submissions don't necessarily need to be full programs, a function saves you some bytes: Try it online!

– ბიმო – 2018-07-27T13:34:48.833

Save a byte by swapping the variable declarations to int*s=0,n=0,i;, and since this is C89, save a further 4 bytes by not specifying main()'s return type, defaulting to int. – ElementW – 2018-07-29T14:13:45.417

3

TIS, 75 bytes

Code:

@0
MOV UP ACC
JGZ U
JLZ Q
ADD ANY
JRO -4
Q:MOV ANY DOWN
JMP Q
U:MOV ACC ANY

Layout:

1 2 CS
I0 NUMERIC -
O0 NUMERIC - 32

Try it online!

This implementation requires negative numbers for termination, and all values to be delimited by whitespace. Output is delimited by whitespace as well.

Explanation:

I have one regular computation node. Numeric input comes from above, and numeric output is sent below. To the right, there is a stack node.

Here's the code, with more verbose (and additional) labels:

@0
START: MOV UP ACC     # Get input
       JGZ PUSH       # If input is positive, jump to PUSH
       JLZ STOP       # If input is negative, jump to STOP
                      # Else input is zero, continue at POP
POP:   ADD ANY        # Consume one value from the stack, by adding it to the accumulator
       JRO -4         # Jump back up to the top (new input will overwrite the accumulator)
STOP:  MOV ANY DOWN   # Move one value from the stack to output
       JMP STOP       # Just loop this bit forever
PUSH:  MOV ACC ANY    # Push the value we just read onto the stack
                      # Implicitly jump back to the top

You may have noticed that we use ANY to access the stack instead of RIGHT. We can depend on this to go to the correct place because of a quirk in the implementation of both the original game, and this emulator. Replacing all the ANYs by explicit RIGHTs will give the same solution.

I go into more detail about this behavior in note 2 of this other answer.

Limitations:

TIS has some inherent limitations, which limit the abilities of this implementation quite directly.

First, the numeric datatype only accepts values from -999 to 999. Any values outside this range will be clamped to either -999 or 999.

Additionally, TIS stack nodes only allow a maximum depth of 15 items. Some implementations may deadlock when hitting that limit. Others, like this one, will behave in perhaps-unexpected ways. This specific implementation will just dump any overflow values to the output. (Changing the last line to U:MOV ACC RIGHT will make it do the deadlock thing instead).

Phlarx

Posted 2018-07-27T11:27:25.810

Reputation: 1 366

3

Haskell, 51 43 bytes

run s function Try it online

(#)[]
(_:r)#(0:s)=r#s
r#(x:s)=(x:r)#s
r#_=r

Евгений Новиков

Posted 2018-07-27T11:27:25.810

Reputation: 987

2

C, 86 Bytes

c;f(a,n)int*a;{if(!n)c=0;else{f(a+1, n-1);!c&&*a&&printf("%d ",*a)||(c+=2*!*a-1,0);};}

Solution based on recursion. Simply load whole array on a system stack and count number of zeroes from the end and either skip current number (if count is positive) or print it. The resulting stack is printed from left to right, ie. head is on the beggining of the line.

Ungolfed version:

int counter;    
void goo(int * a, int n){
        if (!n) {     // end of the array
            counter = 0;
            return;
        }
        goo(a+1, n-1); // try next number
        if (!*a) { cnt++; return;} //increase number of zeroes;
        if (cnt) { cnt--; return;} //skip current number
        printf("%d ", *a); //print it otherwise
    }

Try it on Ideone!

Jasmes

Posted 2018-07-27T11:27:25.810

Reputation: 131

This is nice! You can save 3 bytes: https://bit.ly/2NQUCMZ

– O.O.Balance – 2018-07-27T15:27:38.123

73 bytes – ceilingcat – 2018-07-28T03:33:19.323

2

Stax, 8 bytes

âΦε∙GφN²

Run and debug it

wastl

Posted 2018-07-27T11:27:25.810

Reputation: 3 089

2

Befunge-93, 37 bytes

v<
 |   :<
 $
 $
>>&:1+|
>:v :$<
^._@

Try it online!

My first answer in Befunge!

Uses -1 as EOF. As Befunge already uses a stack internally, I just need to do the push and pop operations given the values at the input.

Charlie

Posted 2018-07-27T11:27:25.810

Reputation: 11 448

1

Befunge can be a lot more compact then that. 17 bytes

– Jo King – 2018-08-01T00:39:02.397

@JoKing I've been trying to understand your code all day... now I think I did at last. – Charlie – 2018-08-01T12:49:16.307

2

Chip -o, 53 bytes

)))))))}v9
ABCDEFGH`~8
0123456`v~S
)))))))~]T
abcdefg

Try it online!

For the TIO here, I use a Bash wrapper to allow "easier" number inputs. Numbers are given as values like \x3f, so that printf can do the conversion to the actual byte values for us. However, this is only a wrapper, or test harness, or whatever, and as such it is technically unnecessary.

This treats each byte of input as a 'signed byte', meaning that it will accept values 0 (0x00) through 127 (0x7f) as input, and anything else is a terminator (by virtue of being negative).

However, thanks to the -o flag, we don't need to provide an explicit terminator, since the interpreter will provide an infinite series of -1 (0xff) values upon exhaustion of STDIN.

Explanation:

Chip is a 2D language, so the various elements seen generally interact with their four neighbors. Here's the highlights of the structure:

)))))))}v9      This chunk will, given a positive value, push it onto the stack,
ABCDEFGH`~8     and given zero, pop a value off the stack. Only the low 7 bits are
0123456         stored, since we never need to push/pop negatives.

The stack push control (9) is set from the result of ORing ()) the low 7 bits of the input together (A - G), and XORing (}) the result with the high bit of the input (H). The stack pop control (8) is set by that same calculation, but inverted (~).

The end result is that 1 - 127 cause a push, and -128 - 0 cause a pop.

The stack bits (0-6) push/pop based on what the control values resolve to. If pushing, they will read from the corresponding input bits (A - G).

       H
0123456`v~S   This chunk will pop values to the output (or to the void if we
)))))))~]T    had a zero), and terminate the program if the stack is empty.
abcdefg

When the stack (0 - 6) is popped, we want to send that data to the output bits (a - g). Actually, we always send a value to the output, because in Chip you are either peeking or popping, and difference is only whether the value is kept for the future.

If the input was non-negative, due to the high bit (H) being unset, we want to suppress the output (S), preventing anything from being written to STDOUT.

On the way to the output, we also OR all the bits together again ()) to see if the stack has been emptied. If all bits are zero, it's empty, so we terminate (T). To prevent premature termination (since on the first cycle the stack is empty, and we always either peek or pop), we also use an AND (]) to ensure that we have a negative input value.

Phlarx

Posted 2018-07-27T11:27:25.810

Reputation: 1 366

2

Kotlin, 90 bytes

{l:List<Int>->var c=0
l.reversed().filter{if(it<1){c++
0>1}else if(c>0){c--
0>1}else 1>0}}

Try it online!

JohnWells

Posted 2018-07-27T11:27:25.810

Reputation: 611

2

Japt -g, 9 bytes

;®?AiZ:Av

Try it online!

Oliver

Posted 2018-07-27T11:27:25.810

Reputation: 7 160

2

R+pryr, 44 bytes

Reduce(pryr::f("if"(b,c(b,a),a[-1])),scan())

Try it online!

Heavily inspired by digEmAll's answer.

JayCe

Posted 2018-07-27T11:27:25.810

Reputation: 2 655

2

ReRegex, 19 bytes

[^0,]\d*,0,//#input

Very simple solution, Looks for a non-zero number, followed by a zero, and removes both of them.

Takes input in the form of ,1,2,3,

Try it online!

Test Battery

ATaco

Posted 2018-07-27T11:27:25.810

Reputation: 7 898

2

MathGolf, 7 bytes

Æ_╜Å;;]

Try it online!

Explanation

I wish I could do something clever to save a byte, it seems as if it should be possible.

Æ        For-each over the input with the next 5 operators
 _       Duplicate TOS
  ╜      Else without if, executes the next block if TOS is false
   Å;;   Discard two elements
      ]  Wrap everything in array

This answer has the opposite order compared to the examples in the challenge.

maxb

Posted 2018-07-27T11:27:25.810

Reputation: 5 754

I don't know MathGolf, but I don't think that ] is necessary. Relevant.

– ბიმო – 2018-11-20T16:27:32.077

@BMO I'm always unsure on how to interpret that, since MathGolf implicitly joins the stack into a single string. Thus, a stack consisting of [123, 456] would be printed as 123456, which has been used in this answer. I'll ask in the chatroom and try to get some consensus.

– maxb – 2018-11-21T06:38:17.100

Yeah, I'm not sure about it either. But I would argue that as a function in MathGolf it would be fine (which is most of the time - as here too - fine), however as a full program it's not since it outputs a joined string. – ბიმო – 2018-11-21T06:57:17.030

@BMO MathGolf doesn't really have "functions" as of now. I don't know if I'll implement it later. However, the general consensus seems to be that the ] should be included in the byte count, with the reasoning that "The principle that languages are defined by their implementations overrides most others". – maxb – 2018-11-21T10:01:08.073

1

Charcoal, 12 bytes

FA¿ι⊞υι¬⊟υIυ

Try it online! Link is to verbose version of code. Explanation:

FA

Loop over the input list.

¿ι

Test for zero.

⊞υι

If non-zero, push to the predefined empty list.

¬⊟υ

Otherwise pop the value, and ignore it by taking the logical negation which is always zero and therefore prints an empty line.

Iυ

Print each element of the list on its own line.

Neil

Posted 2018-07-27T11:27:25.810

Reputation: 95 035

1

Small Basic, 218 bytes

A Script that takes input as a series of integers and outputs to the TextWindow object.

Note, terminal "s are not required for code to function and do not contribute to the bytecount.

n=" "
x=""
While n<>""
If n=0Then 
k=Stack.PopValue(x)
Else 
Stack.PushValue(x,n)
EndIf
n=TextWindow.Read()
EndWhile
o=Stack.PopValue(x)
k=Stack.GetCount(x)
For i=2To k
o=o+","+Stack.PopValue(x)
EndFor
TextWindow.Write(o)

Try it at SmallBasic.com! Requires IE/Silverlight

-8 bytes thanks to @OMᗺ for removing [ and ]

Input / Output

I/O

Taylor Scott

Posted 2018-07-27T11:27:25.810

Reputation: 6 709

1

Ruby, 53 bytes

l=[];gets.split.map{|s|a=s.to_i;a>0?l<<a:l.pop};$><<l

The input needs to be separated by spaces. I'm working on a solution with gsub, but it does not re-run matching when it gets to the end. I would be happy if someone could help me fix this:

gets.gsub(/\d+ 0\s*/,'')

Peter Lenkefi

Posted 2018-07-27T11:27:25.810

Reputation: 1 577

I can't get it to work with empty input, how does it work?

– ბიმო – 2018-07-27T13:30:45.513

@OMᗺ I think this should work on empty input and TIO normalizes it to nil for some reason. If you enter a whitespace, it still works. Running in command line should not yield an error I think (I'll check that later). – Peter Lenkefi – 2018-07-27T13:36:56.830

@PeterLenkefi You might be able to implement a loop with gsub!, which returns the string if modifications were made and nil otherwise. – benj2240 – 2018-07-30T21:58:01.720

1

Retina, 13 bytes

Takes the input list separated by newlines.

+0`\b\d+¶0¶?

Try it online!

Repeatedly remove the first occurrence of a number followed by a zero. Stack is returned upside-down.

Reversing the order of the lines is 4 more bytes (add to end of program). To avoid a possible leading newline, surround the input with newlines, similar to how the input in the examples uses brackets.


G^`

mbomb007

Posted 2018-07-27T11:27:25.810

Reputation: 21 944

1

Rust, 66 bytes

Takes a vector and returns a vector. The head of the stack comes last in the output.

|l|{let mut r=vec!();for&e in&l{if e>0{r.push(e)}else{r.pop();}}r}

Try It Online

Jakob

Posted 2018-07-27T11:27:25.810

Reputation: 2 428

1

Octave, 56 bytes

s=[];for i=input(''),if i,s=[i s];else s(1)=[];end,end,s

Try it online!

Implementation is simple. Create an empty stack / array s, then declare a list of values (i.e. [12, 3, 0, 101, 11, 1, 0, 0, 14, 0, 28]), iterate through each element and if the element is non-zero, simply place the element at the front. Otherwise, remove the first value inside the stack. Once we're done, show the result to the screen.

rayryeng - Reinstate Monica

Posted 2018-07-27T11:27:25.810

Reputation: 1 521

1

PHP (>=5.4), 68 66 bytes

(-2 bytes by fixing a condition, thanks to Titus)

<?for(;null!=$n=$argv[++$i];)$n?$a[]=$n:array_pop($a);print_r($a);

To run it:

php -n <filename> <int_1> <int_2> ... <int_n>

Example:

php -n stack.php 12 3 0 101 11 1 0 0 14 0 28

Or Try it online!

Using r option per Titus's suggestion, this can be counted as 64 bytes:

Example:

php -nr "for(;null!=$n=$argv[++$i];)$n?$a[]=$n:array_pop($a);print_r($a);" 12 3 0 101 11 1 0 0 14 0 28

Night2

Posted 2018-07-27T11:27:25.810

Reputation: 5 484

Anything positive is truthy and there is no negative input -> no need for >0. And you can also run it with php -nr '<code>' <int_1> <int_2> ... <int_n> - without the <? tag. – Titus – 2018-07-28T15:31:01.450

But you need NULL!== or it will take zero as end of input. (see your TiO) – Titus – 2018-07-28T15:35:28.797

@Titus: Thanks for the tips! Do you have any link to show confirmation that an option like -r <code> can be valid? I'm new to PPCG and am not sure what options and methods I can use for PHP golfing! – Night2 – 2018-07-28T15:46:15.893

-r is free; see this thread in meta. You still have to fix the NULL condition. – Titus – 2018-07-28T15:55:23.083

The inputs are in string form and '0' is not equal to null as a string. Please see this: Try it online! Not sure why I should use strict comparison in that case.

– Night2 – 2018-07-28T17:18:50.570

Oh right. I misread the TiO output. – Titus – 2018-07-29T11:54:44.873

1

Bash, 81 , 50 bytes

for i;{ ((i))&&o+=($i)||unset o[-1];};echo ${o[@]} 

Try it online!

Packed in function because, tio doesn't show output without it for some reason.

Bazil

Posted 2018-07-27T11:27:25.810

Reputation: 31

1A few tips: 1. A full program would be shorter. 2. in $@ is implicit and can be removed. 3. The if statement can be shortened to ((i))&&o+=($i)||unset o[-1]. – Dennis – 2018-07-29T14:56:28.073

1

Java 8, 65 bytes

flexible output permitting... the output stack is stored in the input array, with zero or more terminating -1 values

a->{int x=0,y=0;for(int e:a){a[y++]=-1;a[e>0?x++:--x]=e>0?e:-1;}}

all the remaining numbers on the stack are placed at the front of the array. Reaching -1 in the array indicates the end of the stack.

Jack Ammo

Posted 2018-07-27T11:27:25.810

Reputation: 430

1

Clojure, 139 bytes

(defn t[q](loop[c(rest q)n(first q)s '()](if(not(nil? n))(if(= n 0)(recur(rest c)(first c)(rest s))(recur(rest c)(first c)(cons n s)))s)))

Try it online!

Ungolfed

(defn stacktest [col]
  (loop [c  (rest col)
         n  (first col)
         s  '()]
    (if (not (nil? n))
      (if (= n 0) ; then
        (recur (rest c) (first c) (rest s))    ; then - pop
        (recur (rest c) (first c) (cons n s))) ; else - push
      s)))        ; else

Bob Jarvis - Reinstate Monica

Posted 2018-07-27T11:27:25.810

Reputation: 544

1

Ruby, 36 bytes

->a{b=[];a.map{|i|i>0?b<<i:b.pop};b}

Try it online!

dkudriavtsev

Posted 2018-07-27T11:27:25.810

Reputation: 5 781

1

dc, 24 bytes

[*+]sP[?d0=Pd0<l]dslxsxf

Try it online!

Input is one number per line and terminate with a negative number but remember that negative numbers are input with a leading underscore not a dash. There's something punny about implementing this in a stack based language and using the operand stack as the data structure. I'm especially happy about the *+ to "pop" the zero and the previous input.

Geoff Reedy

Posted 2018-07-27T11:27:25.810

Reputation: 2 828

1

F#, 84 bytes

let t v=
 let mutable s=List.empty
 for i in v do s<-if i=0 then s.Tail else i::s
 s

Try it online!

Takes advantage of the fact that in F# a List is a single-linked-list. Popping from the stack just takes the tail of the list (that is, everything after the first element). Pushing to the stack makes the individual value i the head of the list (that is, pre-appends it to the list).

Ciaran_McCarthy

Posted 2018-07-27T11:27:25.810

Reputation: 689

1

Scala, 50 bytes

(List[Int]()/:v)((x,i)=>if (i==0)x.tail else i::x)

Usage in the REPL

scala> val v = List(12,3,0,101,11,1,0,0,14,0,28)
v: List[Int] = List(12, 3, 0, 101, 11, 1, 0, 0, 14, 0, 28)

scala> (List[Int]()/:v)((x,i)=>if (i==0)x.tail else i::x)
res0: List[Int] = List(28, 101, 12)

scala>

Felix

Posted 2018-07-27T11:27:25.810

Reputation: 111

1

Lua, 115 bytes

t,a,s=table,arg,{}for i=1,#a do v=0+a[i]if v>0 then t.insert(s,1,v)else t.remove(s,1)end end print(t.concat(s,","))

quite simple iterates the arguments pushes and pops them to a table

Try it online!

Lycea

Posted 2018-07-27T11:27:25.810

Reputation: 141

You might want to add a TIO-link, I have no idea how to test this.

– ბიმო – 2018-08-01T12:08:28.207

Added a try it online link, sorry for the inconvenience I forget it most of the time :) – Lycea – 2018-08-01T12:19:33.010

1

Scheme, 115 bytes

Like all lisp variants, scheme is based around linked lists. Linked Lists are often used to implement stacks. So I thought scheme might be a competitive language for this challenge. However, I failed to find a way to leverage Scheme's easily accessible built-ins for stack building to overcome Scheme's sheer verbosity. I love scheme, but sometimes its just too long...

(define(g c)(define(f l s)(cond((null? l)s)((= 0(car l))(f(cdr l)(cdr s)))(else(f(cdr l)(cons(car l)s)))))(f c'()))

Try it Online!

Zachary Cotton

Posted 2018-07-27T11:27:25.810

Reputation: 679

1

Lua, 99 Bytes

I started looking for improvements for this answer, but ended with a solution that I find sufficently different to be an answer on its own.

As usual, you can Try it online!

It takes input as a list of arguments, and outputs each number separated by commas. The top of the stack (first element to pop()) is the last one printed

r={}for i=1,#arg
do
a=arg[i]+0s=a>0 and a or x
r[#r+(s and 1or 0)]=s
end
print(table.concat(r,","))

Ungolfed

r={}          -- Define our output array
for i=1,#arg  -- iterate over the argument
do
a=arg[i]+0    -- shorthand for the current argument, add 0 to coerce it into a number
s=a>0         -- s define the operation to do in the current loop
    and a     -- if a>0, then s=a
  or x        -- else, s=x, x isn't initialiazed, so it's equivalent to s=nil

r[#r+         -- modify the end of the array
  (s          -- if s is true (which means not nil)
      and 1   -- add 1 to the current index to perform a push
    or 0)]    -- else, let it alone, which means we overwrite the last value of the table
  =s          -- attrib s to that index

  --[[
    if s is nil, it gives us, ungolfed, r[r.length+0]=nil, which erase the last value we have
    if s is a number, it's equivalent to r[r.length+1]=arg[i], or table.push(r, arg[i])
  ]]
end

print(table.concat(r,",")) -- outputs the table separating each element by commas

Katenkyo

Posted 2018-07-27T11:27:25.810

Reputation: 2 857

97 bytes. I think you could also save bytes by using an anonymous function with loadstring, but that's up to you if you want that – Jo King – 2018-08-15T07:27:10.147

1

Prolog (SWI), 47 bytes

R-L:-append(A,[_,0|T],L),append(A,T,M),R-M;R=L.

Try it online! Call as output-input.

Explanation

R-L:-
     append(A,[_,0|T],L),                       % if list contains _,0
                         append(A,T,M),R-M;     % then remove it and recurse
                                           R=L. % else we're done, output = input

ASCII-only

Posted 2018-07-27T11:27:25.810

Reputation: 4 687

1

Ahead, 23 bytes

~$k*2!:Ivj~
~oNO@k!d<~#

Try it online!

snail_

Posted 2018-07-27T11:27:25.810

Reputation: 1 982

1

Dart, 69 bytes

f(l){var m=[];l.forEach((n){n>0?m.add(n):m.removeLast();});return m;}

Alternative

f(l,{m=List}){l.forEach((n){n>0?m.add(n):m.removeLast();});return m;}

Try it online!

Naive answer until I find a better way.

Elcan

Posted 2018-07-27T11:27:25.810

Reputation: 913

1

Common Lisp, 54 bytes

(let(s)(dolist(x(read)s)(if(= 0 x)(pop s)(push x s))))

Ultra-straightforward implementation!

Try it online!

Renzo

Posted 2018-07-27T11:27:25.810

Reputation: 2 260

1

Burlesque - 27 bytes

%f={Jz?{vvvv}if}ps(%f!)[]e!

But this is rather bad to be honest. Anyway:

%f={Jz?{vvvv}if}             defines f
                ps           parse
                  (%f!)      quoted call to f
                       []    intersperse
                         e!  eval

This essentially inserts a call to f between the numbers.

J            duplicate
 z?          zero?
   {vvvv}    pop two elemnets
         if  if

mroman

Posted 2018-07-27T11:27:25.810

Reputation: 1 382

0

Python 2, 65 bytes

def f(p,s=[]):
 for i in p:
  if i:s+=i,
  else:s.pop()
 return s

Try it online!

Beta Decay

Posted 2018-07-27T11:27:25.810

Reputation: 21 478

Actually, when written this way the function is non-reusable. – user202729 – 2018-07-27T13:29:43.690

@user202729 What does non-reusable mean? – Beta Decay – 2018-07-27T13:32:25.590

@user202729 Oh, I didn't realise – Beta Decay – 2018-07-27T13:38:19.823

0

JavaScript (Node.js), 63 bytes

a=>{let b=[];a.map(x=>x?b.push(x):b.pop());return b.reverse();}

Try it online!

Can probably be improved

Skidsdev

Posted 2018-07-27T11:27:25.810

Reputation: 9 656

49 bytes in right order a=>a.reduce((r,i)=>i?[i].concat(r):r.slice(1),[]). Reverse order I see nothing beating @Shaggy's answer – Alexis Facques – 2018-07-27T12:17:20.397

2@AlexisFacques 44 bytes: a=>a.reduce((r,i)=>i?[i,...r]:r.slice(1),[]) – Neil – 2018-07-27T12:24:48.230

0

JavaScript (ES6), 44 bytes

This code works directly on the original array rather than creating a new one. This is however longer than @Shaggy's answer.

a=>a.reverse(x=0).filter(n=>n?x?!x--:1:!++x)

Try it online!

Arnauld

Posted 2018-07-27T11:27:25.810

Reputation: 111 334

0

Python 3, 186 bytes

l = list() 
while True:
    one = int(input())
    if one<0:
        break
    elif one==0:
        if len(l)>0:
            l.pop()
    else:
        l.append(one)

l.reverse()
print(l)

Try it online!

Arnav Mukhopadhyay

Posted 2018-07-27T11:27:25.810

Reputation: 1

You place the language and byte code in your actual answer, not in the comments. – rayryeng - Reinstate Monica – 2018-07-28T07:55:04.613

1

Welcome to PPCG! This seems to be erroring. Also you need to add a byte-count and provide the language name in the answer itself.

– ბიმო – 2018-07-28T09:23:50.000

1@OMᗺ That's because the answer requires a negative integer to indicate EOF (I believe you permitted this in the spec). – O.O.Balance – 2018-07-28T10:02:41.713

94 bytes: https://bit.ly/2uRGQmj

– O.O.Balance – 2018-07-28T10:12:57.050

Ah that works! Yes, I did indeed. I took the freedom of editing the answer, if you're not happy with my edit, feel free to format it differently (however language name and byte-count should still be present) and incorporate the suggested golfs. – ბიმო – 2018-07-28T11:12:49.783

13 bytes off of the golf suggested by O.O.Balance: Try it online!

– ბიმო – 2018-07-28T11:16:58.663

@O.O.Balance if you're language doesn't has native support for lists ... I think that Python does. – Titus – 2018-07-28T15:33:03.383

@Titus we don't usually make different rules for different languages – but you are right, that is what it says. OP does not seem to mind – I'll ask them to clarify. – O.O.Balance – 2018-07-28T16:03:44.090

@Titus OP has now clarified that all languages may take input this way. – O.O.Balance – 2018-07-28T16:23:13.793

0

Scala, 61 bytes 48 bytes

(Seq[Int]()/:z)((z,b)=>if(b!=0)b+:z else z.tail)

Usage in the REPL

val z = Seq(1,2,3,4,0,3,2,5,0,1)

(Seq[Int]()/:z)((z,b)=>if(b!=0)b+:z else z.tail)

res0: Seq[Int] = List(1, 2, 3, 3, 2, 1)

Uses shorthand .foldLeft notation/: and .tail for popping items.

Lucian Enache

Posted 2018-07-27T11:27:25.810

Reputation: 101

0

Python 3, 60 bytes

def f(L,r=[]):
 for n in L:r=[n]+r if n else r[1:]
 return r

Try it online!

Jimmi

Posted 2018-07-27T11:27:25.810

Reputation: 1

0

Pepe, 57 bytes

rrEEReRerEerEEEEerEERrERREeEreErEEEEereeRrErEEReEEReeEree

Try it online!

Requires the input to end with -1. Note that "Separated by" option must be enabled. You might prefer to change the separator to , (it's a ; by default). Also, putting ,-1 on a newline might help you not accidentally remove the ,-1, preventing infinite loops and browser crashes.

Explanation

Text in brackets [] are values taken from the stack, r is the control-flow stack, R is the data stack

# prepare (11 bytes)
rrEE           # Define [implicit 0] as
  Re Re          # Double pop from R
rEe            # Return

# main (29 bytes)
rEEEEe         # Decrement [implicit 0], always returns -1
rEE            # Create label [-1]
  RrE            # Prepend 0 to r
  RREeE          # Prepend input to R
  reE            # Execute 0 (double pop) if [input] was 0
  rEEEEe         # Decrement [0] in r, always returns -1
ree           # If [input] wasn't -1, goto label -1

# output (17 bytes)
RrE           # Prepend 0 to r
rEE           # Create label [0]
  ReEE ReeE     # Output [pop R] and a newline
ree           # If there's anything on the stack (non-zero), goto [0]

RedClover

Posted 2018-07-27T11:27:25.810

Reputation: 719