Cover up zeroes in a list

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]

• A bit of trivia: The name for this operation in the world of statistics is LOCF (last observation carried forward) imputation. Commented Dec 5, 2015 at 0:12
• What happens if the input was [0,0]? Commented Dec 5, 2015 at 6:56
• @KριτικσιΛίθος "...where the first value is guaranteed to be non-zero" Commented Dec 5, 2015 at 7:49
• What if the input is [1,01]? Using, issac's Pyth answer, compare this and this. Commented Dec 6, 2015 at 0:47
• @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) Commented Dec 6, 2015 at 0:52

Japt, 3 bytes

å!ª


Try it

å!ª     :Implicit input of array
å       :Cumulatively reduce
!      :Flip the arguments
ª     :Logical OR


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


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.

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. 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  Prolog (SWI), 44 bytes f(0,B,B). f(A,_,A). X*O:-scanl(f,X,0,[_|O]).  Try it online! Thunno 2, 3 bytes Ʋs|  Attempt This Online! Explanation Ʋs| # Implicit input Ʋ # Cumulative reduce by: s| # Swapped logical OR # Implicit output  Nekomata, 4 bytes pZ‼l  Attempt This Online! Find the last nonzero element in each prefix of the input array. pZ‼l p For each prefix: Z‼ Remove zeros l Last element  Arturo, 32 29 bytes $=>[0map&'x->(0=x)?[<=]-><=x]


Try it

$=>[ ; a function where input is assigned to & 0 ; push 0 to stack map&'x-> ; map over input, assign current elt to x (0=x)? ; is the current element zero? [<=] ; then duplicate top of stack -> ; otherwise, <=x ; push x and duplicate it ] ; end function  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. 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


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;
}

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

Mathematica, 2827 25 bytes

Saved 2 bytes thanks to Martin Büttner.

If[#2==0,##]&~FoldList~#&

• If[#2==0,##]&~FoldList~#&? Commented Dec 22, 2015 at 17:17

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.

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.

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. 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) Vyxal, 2 bytes ɖ∨  Try it Online! rs, 14 bytes +(\S+) 0/\1 \1  1 byte shorter than Retina!! Live demo and test cases. 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  • I was thinking this challenge had no seriously answer...and rather than check, I sat down and wrote this exact solution byte-for-byte. Commented Dec 27, 2015 at 8:25 • @quintopia Hush, people are going to think you're my sock :P – user45941 Commented Dec 27, 2015 at 18:05 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


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

• b||c saves one byte over b?b:c.
– Neil
Commented Dec 6, 2015 at 19:18
• Although then you just end up with @Dendrobium's answer.
– Neil
Commented Dec 6, 2015 at 19:24
• His is surperior, I don't want to impersonate him
– bren
Commented Dec 6, 2015 at 21:48
• (I hadn't seen his answer when I wrote my first comment.)
– Neil
Commented Dec 7, 2015 at 10:43
• You're fine, but if his is better, than is better so be it.
– bren
Commented Dec 8, 2015 at 21:42

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

• 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! Commented Oct 19, 2021 at 16:10
• Sure--you can run it at Archive.org, though you have to type it in by hand. Commented Oct 19, 2021 at 16:21

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.

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!

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


05AB1E, 6 bytes

Å»‚0Kθ


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

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)


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)


Ly, 19 bytes

&nry[p[s!]plu9oy]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


UiuaSBCS, 10 bytes

\(⊢▽≠0.⊂:)


Try it here!

\(⊢▽≠0.⊂:)