45
\$\begingroup\$

Inspired by this SO question

As input you will be given a non-empty list of integers, where the first value is guaranteed to be non-zero. To construct the output, walk from the start of the list, outputting each non-zero value along the way. When you encounter a zero, instead repeat the value you most recently added to the output.

You may write a program or function, and have input/output take any convenient format which does not encode extra information, as long as is still an ordered sequence of integers. If outputting from a program, you may print a trailing newline. Except for this trailing newline, your output should be an acceptable input for your submission.

The shortest code in bytes wins.

Test Cases

[1, 0, 2, 0, 7, 7, 7, 0, 5, 0, 0, 0, 9] -> [1, 1, 2, 2, 7, 7, 7, 7, 5, 5, 5, 5, 9]
[1, 0, 0, 0, 0, 0] -> [1, 1, 1, 1, 1, 1]
[-1, 0, 5, 0, 0, -7] -> [-1, -1, 5, 5, 5, -7]
[23, 0, 0, -42, 0, 0, 0] -> [23, 23, 23, -42, -42, -42, -42]
[1, 2, 3, 4] -> [1, 2, 3, 4]
[-1234] -> [-1234]
\$\endgroup\$
8
  • 21
    \$\begingroup\$ A bit of trivia: The name for this operation in the world of statistics is LOCF (last observation carried forward) imputation. \$\endgroup\$
    – Alex A.
    Dec 5, 2015 at 0:12
  • \$\begingroup\$ What happens if the input was [0,0]? \$\endgroup\$
    – user41805
    Dec 5, 2015 at 6:56
  • 4
    \$\begingroup\$ @KριτικσιΛίθος "...where the first value is guaranteed to be non-zero" \$\endgroup\$
    – Sp3000
    Dec 5, 2015 at 7:49
  • \$\begingroup\$ What if the input is [1,01]? Using, issac's Pyth answer, compare this and this. \$\endgroup\$
    – Arcturus
    Dec 6, 2015 at 0:47
  • \$\begingroup\$ @Eridan 01 is not a valid integer in Pyth input, so isaac doesn't have to account for that. Other answers can accept input like that if they want, just so long as they are consistent (like how isaac's answer will never produce that list as output) \$\endgroup\$ Dec 6, 2015 at 0:52

56 Answers 56

1
2
3
\$\begingroup\$

05AB1E, 7 bytes

εĀiyU}X

Try it online!

My first try, using 05AB1E

ε       for each y in input
  Āi    if > 0
    yU  save current value in X
  }
  X     push X
        implicitly close for-loop and print list
\$\endgroup\$
3
\$\begingroup\$

Perl 6, 16 bytes

*.map($ [R||]=*)

Try it online!

Maps each element to the reverse logical OR with the previous calculated element. I wish I could do something like {[\R||] $_} but the R operator doesn't quite work that way.

\$\endgroup\$
3
\$\begingroup\$

Zsh, 21 bytes

for i;echo $[n=i?i:n]

Try it online!

We use echo instead of <<< because we need to set n. Using <<<$[n=i?i:n] expands $[n=i?i:n] in a subshell, which will prevent n from ever being set.

\$\endgroup\$
3
\$\begingroup\$

k4, 15 bytes

{^\?[0=x;0N;x]}

   ?[        ]  / vector conditional ?[cond;true;false]; eg ?[010b;2 2 2;3 3 3] -> 3 2 3
 ^\             / fills nulls (0N) with preceding value
\$\endgroup\$
3
\$\begingroup\$

Husk, 2 bytes

G|

Try it online!

scan from left with or.

\$\endgroup\$
2
\$\begingroup\$

Labyrinth, 21 bytes

The top half seems a bit wasteful, but I'm not sure what to do about it...

""?"
" #"
;  ;
,\!:
@

I/O via linefeed-delimited lists.

Try it online.

The idea is to keep the last printed thing on the stack and discard zeroes whenever we find them.

\$\endgroup\$
2
\$\begingroup\$

Arcyóu, 44 bytes

(F(L)(f x(_(_ L))(L((F(i)(?(L i)i($([ i))))x

This is an anonymous function taking one argument.

Explanation:

(F(L)               ; Anonymous function F(L)
  (f x (_ (_ L))    ; For x in range(len(L))
    (L              ; Implicit indexing
      (F(i)         ; Anonymous function F(i)
        (? (L i)    ; If L[i] is not 0:
          i         ; Return i; otherwise:
          ($ ([ i)) ; Recurse ($) with i decremented
        )           ; Then, we call this new function on x
      )             ; And use the return value as the index from line 3
      x             ; No final close-parens
\$\endgroup\$
2
\$\begingroup\$

C 45 Bytes

#define F(a,s) while(s--) *a=*a?*a++:*(a++-1)

Here's my test program

Go easy as it's my first try at code golf.

#include <stdio.h>

#define ARRAYSIZE(x) (sizeof(x)/sizeof(x[0]))
#define F(a,s) while(s--) *a=*a?*a++:*(a++-1)

void printSolutions(int * solutions, int size)
{
  do {
    printf("%d ", *solutions++);
  } while (--size > 0);
  printf("\n");
}

int main(int argc, char * argv[])
{
  static int testCase1[] = {1, 0, 2, 0, 7, 7, 7, 0, 5, 0, 0, 0, 9};
  static int testCase2[] = {1, 0, 0, 0, 0, 0}; 
  static int testCase3[] = {-1, 0, 5, 0, 0, -7};
  static int testCase4[] = {23, 0, 0, -42, 0, 0, 0};
  static int testCase5[] = {1, 2, 3, 4};
  static int testCase6[] = {-1234};
  int * p;
  int s;
  printSolutions(testCase1, ARRAYSIZE(testCase1));
  s = ARRAYSIZE(testCase1);
  p = testCase1;
  F(p, s);
  printSolutions(testCase1, ARRAYSIZE(testCase1));
  printSolutions(testCase2, ARRAYSIZE(testCase2));
  s = ARRAYSIZE(testCase2);
  p = testCase2;
  F(p, s);
  printSolutions(testCase2, ARRAYSIZE(testCase2));
  printSolutions(testCase3, ARRAYSIZE(testCase3));
  s = ARRAYSIZE(testCase3);
  p = testCase3;
  F(p, s);
  printSolutions(testCase3, ARRAYSIZE(testCase3));
  printSolutions(testCase4, ARRAYSIZE(testCase4));
  s = ARRAYSIZE(testCase4);
  p = testCase4;
  F(p, s);
  printSolutions(testCase4, ARRAYSIZE(testCase4));
  printSolutions(testCase5, ARRAYSIZE(testCase5));
  s = ARRAYSIZE(testCase5);
  p = testCase5;
  F(p, s);
  printSolutions(testCase5, ARRAYSIZE(testCase5));
  printSolutions(testCase6, ARRAYSIZE(testCase6));
  s = ARRAYSIZE(testCase6);
  p = testCase6;
  F(p, s);
  printSolutions(testCase6, ARRAYSIZE(testCase6));

  return 0;
}
\$\endgroup\$
5
  • \$\begingroup\$ Running your test program on Ideone.com doesn't seem to work - it just duplicates the first number. \$\endgroup\$ Dec 9, 2015 at 19:36
  • \$\begingroup\$ That's strange. I don't see where I'm relying on undefined behavior. Maybe some compiler optimization gone wrong? \$\endgroup\$
    – cleblanc
    Dec 9, 2015 at 20:33
  • \$\begingroup\$ Yeah, I'm not sure, either (I'm not super-well-versed in C). Both CodingGrounds and codepad have the same behavior. \$\endgroup\$ Dec 9, 2015 at 20:45
  • \$\begingroup\$ Also, welcome to Programming Puzzles & Code Golf! \$\endgroup\$ Dec 9, 2015 at 20:51
  • \$\begingroup\$ Thanks, slow day in work and I usually just read through these... \$\endgroup\$
    – cleblanc
    Dec 9, 2015 at 21:09
2
\$\begingroup\$

Mathematica, 28 27 25 bytes

Saved 2 bytes thanks to Martin Büttner.

If[#2==0,##]&~FoldList~#&
\$\endgroup\$
1
  • 1
    \$\begingroup\$ If[#2==0,##]&~FoldList~#&? \$\endgroup\$ Dec 22, 2015 at 17:17
2
\$\begingroup\$

Factor, 36 bytes

[ 0 [ dup 0 = -rot ? ] accumulate* ]

(Only works locally in Factor 0.98 or later. TIO is missing accumulate*.) ¯\_(ツ)_/¯

Explanation

  • 0 Push a zero to the data stack for accumulate* to use later. This is a 'starter' element so that a binary operation can be performed on something with the first element of the input sequence.
  • [ dup 0 = -rot ? ] Push a quotation to the data stack for accumulate* to use later. This is a function that says "Return the non-zero input if possible. Otherwise, return the second input." Shorter but harder to read than [ [ nip ] unless-zero ].
  • accumulate* Like reduce, except the intermediate results are mapped into a sequence of the same size as the input sequence.
\$\endgroup\$
2
\$\begingroup\$

K (ngn/k), 9 bytes

{y+x*~y}\

Try it online!

Take the cumulative sums of the input, resetting to 0 whenever a new non-zero value is encountered in the list.

If the 0's in the input are replaced with nulls (0N), ^\ (fill-scan) suffices for two bytes.

\$\endgroup\$
2
\$\begingroup\$

Groovy, 34 25 bytes

f={it.collect{it?n=it:n}}

Try it online!

A more readable solution:

f = { // define new closure
  it.collect { // taking advantage of implicit "it". collect applies the closure
               // on every element in order and returns the new, mapped array
    it ? // Groovy Boolean evaluation: 0 = false, 1+ = true
    n = it // assign value to holding variable (if not 0). assignments are expressions
    :
    n // in Groovy, if no return, last expression evaluated is returned
  } // same as above, returns the mapped array
} // end of closure

Groovy is supposed to be similar to Java (and it is), but the Java answer is more than two times longer. Just something to think about.

EDIT: reduced it by 9 bytes(!) by not declaring the n variable beforehand (saves 6 bytes), and using a ternary operator instead of an if (saves 3 bytes)

\$\endgroup\$
1
\$\begingroup\$

rs, 14 bytes

+(\S+) 0/\1 \1

1 byte shorter than Retina!!

Live demo and test cases.

\$\endgroup\$
1
\$\begingroup\$

Seriously, 12 bytes

0╗,`╜@;I;╗`M

Try it online

Explanation:

0╗,    initialize first register to 0 and get input
`...`M map the function over the input:
  ╜@;I    push the result of (a if a else <value in register 0>)
  ;╗      dupe result and push to register 0
\$\endgroup\$
2
  • 1
    \$\begingroup\$ I was thinking this challenge had no seriously answer...and rather than check, I sat down and wrote this exact solution byte-for-byte. \$\endgroup\$
    – quintopia
    Dec 27, 2015 at 8:25
  • \$\begingroup\$ @quintopia Hush, people are going to think you're my sock :P \$\endgroup\$
    – user45941
    Dec 27, 2015 at 18:05
1
\$\begingroup\$

Gema, 21 characters

0=$p
<N>=@set{p;$0}$0

Sample run:

bash-4.3$ gema '0=$p;<N>=@set{p;$0}$0' <<< '23 0 0 -42 0 0 0'
23 23 23 -42 -42 -42 -42
\$\endgroup\$
1
\$\begingroup\$

JavaScript, 20 Bytes

a=>a.map(b=>c=b?b:c)

Explanation:

a=>           // Define anonymous function which takes argument a
  a.map(      // Loop through input
    b=>       // Looping function
      c=b     // Assign c to the loop value (returns b)
      ?b:c    // Ternary Operator: If b (previous expression) is truthy (Non-zero integers are) return b else return c (last value)          
)
\$\endgroup\$
5
  • \$\begingroup\$ b||c saves one byte over b?b:c. \$\endgroup\$
    – Neil
    Dec 6, 2015 at 19:18
  • \$\begingroup\$ Although then you just end up with @Dendrobium's answer. \$\endgroup\$
    – Neil
    Dec 6, 2015 at 19:24
  • \$\begingroup\$ His is surperior, I don't want to impersonate him \$\endgroup\$
    – bren
    Dec 6, 2015 at 21:48
  • \$\begingroup\$ (I hadn't seen his answer when I wrote my first comment.) \$\endgroup\$
    – Neil
    Dec 7, 2015 at 10:43
  • \$\begingroup\$ You're fine, but if his is better, than is better so be it. \$\endgroup\$
    – bren
    Dec 8, 2015 at 21:42
1
\$\begingroup\$

Perl 5 + -pl, 9 bytes

$;=$_||=$

Try it online!

Explanation

This reads each number in as $_ (-p), then sets $; to $_, after first setting $_ to $; if $_ is falsy (0) and is implicitly printed (-p). Requires -l as otherwise $_ would include \n which would mean 0 isn't falsy. The final ; can be omitted as -p (well, specifically the -n part of -p) adds while(<STDIN>){ ... ;} around your code, resulting in $; at the end.

\$\endgroup\$
1
\$\begingroup\$

QBasic, 54 bytes

INPUT n
FOR i=1TO n
INPUT x
IF x=0THEN x=p
?x
p=x
NEXT

Input is the length of the list, followed by the numbers in the list one at a time. (Compare this I/O default, which is the same basic idea even though it refers specifically to passing an array to a function.)

You can try it at Archive.org.

Ungolfed

INPUT arrayLength
FOR i = 1 TO arrayLength
  INPUT number
  IF number = 0 THEN number = previous
  PRINT number
  previous = number
NEXT i
\$\endgroup\$
2
  • \$\begingroup\$ Is there somewhere I can test this? It has been too long since I've written any variant of Basic for me to remember any syntax, etc. I'm sure it is fine, but I always like to check for my own questions! \$\endgroup\$ Oct 19, 2021 at 16:10
  • 1
    \$\begingroup\$ Sure--you can run it at Archive.org, though you have to type it in by hand. \$\endgroup\$
    – DLosc
    Oct 19, 2021 at 16:21
1
\$\begingroup\$

TI-Basic, 37 bytes

Prompt A
For(I,2,dim(ʟA
ʟA(I)+ʟA(I-1)not(ʟA(I→ʟA(I
End

Output is stored in ʟA.

\$\endgroup\$
1
\$\begingroup\$

Python 3.8 (pre-release), 44 bytes

g=lambda l,s=0:l and[a:=l[0]or s]+g(l[1:],a)

Try it online!

\$\endgroup\$
1
\$\begingroup\$

Batch 147 bytes

@Set A=%* &@Setlocal EnableDelayedExpansion
@Set "L=%A: ="&If .!C!==. Set "C=%"
@Set "A=%A: ="&2>nul Set/AL/L&&Set/AC=L&<nul Set/p=!C! &Set "L=%"

Approach:
Update Value to output only when value is non zero

How:

Line one: Arg asssignment and environment prep. Defines the array from arg to the batch file IE: 4 1 0 2 4 3

Line two: Uses a substring operation for each whitespace present in the string with an if condition to isolate the first substring preceding a space for assignment to Last and CCurrent variables.

Line three: Uses Substring modification to iterate through the array from each space in the substring; divides the Last value by itself and on command success (&&) transfers the Last value to Current. (a 0 value results in divide by zero error, redirected to nul). Current value is output after each step of the substitution.


Example Input / output:

4 3 2 0 3
4 3 2 2 3
\$\endgroup\$
1
\$\begingroup\$

05AB1E, 6 bytes

Å»‚0Kθ

Unfortunately 05AB1E lacks a logical-OR builtin, and a bitwise-OR isn't what we want here.

Try it online or verify all test cases.

Explanation:

Å»      # Cumulative left-reduce the (implicit) input-list by:
  ‚     #  Pair the current and previous integers together
   0K   #  Remove any potential 0
     θ  #  And pop and push the last item of this singleton-list/pair
        # (after which the result is output implicitly)
\$\endgroup\$
1
\$\begingroup\$

MathGolf, 7 bytes

êæαç┤o╘

Prints all values on a separated line to STDOUT.

Try it online.

Explanation:

ê       # Push the input as integer-array
 æ      # Foreach over these integers, using four characters as inner code-block:
  α     #  Wrap the top two values on the stack into a list
        #  (the first iteration will pair with an implicit 0)
   ç    #  Remove all 0s (falsey filter)
    ┤   #  Push it's last item to the stack (unfortunately doesn't pop the list)
     o  #  Print it with trailing newline (without popping)
 ╘      # After the foreach: empty the stack (otherwise it would implicitly output the
        # entire stack; feel free to remove it in the TIO-link to see the difference)
\$\endgroup\$
1
\$\begingroup\$

Ly, 19 bytes

&nry[p[s!]plu9`oy]p

Try it online!

This works by running through all the numbers on the list and remember the current number if it's non-zero. Then it unconditionally deleted the current character and what's printed is whatever number is in the backup cell.

&nr                  - read all the nunbers into the stack, reverse them
   y[p          y]   - loop while the stack length is >0
      [  ]           - if/then, true is current number !=0
       s             - save the number to the backup cell
        !            - flip to 0 to exit the loop
                  p  - delete loop boolean so it doesn't print
          p          - delete current number
           lu        - load backup cell and print
             9`o     - print a LF
\$\endgroup\$
0
\$\begingroup\$

Clojure, 49 bytes

#(reduce(fn[c i](conj c(if(= i 0)(last c)i)))[]%)

Well this is very boring. TIO

\$\endgroup\$
0
\$\begingroup\$

Desmos, 80 bytes

L=l[1...i-1]
A=L[LL>0]
f(l)=[\{l[i]=0:A[A.\length],l[i]\}\for i=[1...l.\length]]

Most likely golfable, though I don't see anything at the moment.

Try It On Desmos!

Try It On Desmos! - Prettified

\$\endgroup\$
1
2

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.