g | x | w | all
Bytes Lang Time Link
010UiuaSBCS240729T164444ZEurope20
029Arturo230126T100747Zchunes
004Nekomata230621T021938Zalephalp
003Thunno 2230620T182543ZThe Thon
007Japt151204T220525ZETHprodu
044Prolog SWI220828T020407ZnaffetS
002Vyxal220828T015512ZnaffetS
019Ly220507T094412Zcnamejj
080Desmos220507T072006ZAiden Ch
049Clojure211021T163906ZNikoNyrh
025Groovy211020T192238ZSeggan
007MathGolf211021T105804ZKevin Cr
00605AB1E211021T103132ZKevin Cr
147Batch211019T193745ZT3RR0R
044Python 3.8 prerelease211020T005643ZStephen
037TIBasic211019T222152ZYouserna
054QBasic211019T154741ZDLosc
009Perl 5 + pl210331T163941ZDom Hast
009K ngn/k210331T131951Zcoltim
002Husk210331T041644ZRazetime
036Factor210331T040831Zchunes
003Jelly151204T224713ZDennis
015k4190928T130036Zscrawl
021Zsh190928T122921ZGammaFun
016Perl 6190928T005340ZJo King
00705AB1E190927T190731ZDorian
003Japt190927T162748ZShaggy
054Prolog SWI171224T172855ZWheat Wi
025Mathematica151205T040849Zalephalp
045C 45 Bytes151209T172811Zcleblanc
032Powershell151204T230730ZDanko Du
011CJam151204T220231ZDennis
078Java151208T142456ZGeobits
nan151208T121303ZBlacklig
020JavaScript151206T024149Zbren
033R151205T003153ZAlex A.
036R151206T001347Zflodel
021Gema151205T214240Zmanatwor
031O151205T005432Zjado
012Seriously151205T173654Zuser4594
044Arcyóu151204T225907Zjqkul
014rs151205T171626Zkirbyfan
009Dyalog APL151204T223405Zlirtosia
021Perl 6151205T163007ZBrad Gil
008Gol><>151205T092420Zrandomra
712𝔼𝕊𝕄𝕚𝕟151205T024603ZMama Fun
041Matlab151204T233745ZLuis Men
033Julia151205T005653ZAlex A.
033Milky Way 1.2.1151205T003005ZZach Gat
015Retina151204T235547ZMartin E
021Labyrinth151205T000503ZMartin E
010Minkolang 0.14151204T230216ZEl'e
008Sed151204T224917ZDigital
010GolfScript151204T222038ZIlmari K
008Pyth151204T220055Zlirtosia
038Mathematica151204T222140ZDavidC
019Javascript ES6151204T221220ZDendrobi
008J151204T221147ZZgarb
006Pyth151204T220111Zisaacg
029Python 2151204T215611Zxnor
025Ruby151204T215527ZDoorknob
021Haskell151204T215045Zxnor

UiuaSBCS, 10 bytes

\(⊢▽≠0.⊂:)

Try it here!

Inspired by @lirtosiast's APL answer.

Explanation

\(⊢▽≠0.⊂:)
\(       ) Cumulative reduce of:
       ⊂:  Swap arguments, then join
   ▽≠0.    Remove 0s
  ⊢        First 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

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

Thunno 2, 3 bytes

Ʋs|

Attempt This Online!

Explanation

Ʋs|  # Implicit input
Ʋ    # Cumulative reduce by:
 s|  #  Swapped logical OR
     # Implicit output

Japt, 8 7 bytes

N£U=XªU

Pretty simple. Takes input separated by commas. Try it online!

Ungolfed and explanation

N£    U=Xª U
NmXYZ{U=X||U

        // Implicit: N = input, U = first item
NmXYZ{  // Map each item X to:
U=Z||U  //  Set U to (X || U) and return.
        //  If X is non-zero, this sets U to X.
        //  Otherwise, this leaves U as the last non-zero we've encountered.
        // Implicit: output last expression

4-byte version:

Nå!ª

Explanation:

Nå!ª
Nå!||
NåXY{Y||X}

        // Implicit: N = input, U = first item
NåXY{   // Cumulatively reduce N; take each item Y and prev value X,
Y||X}   //  and return Y if it is non-zero; return X otherwise.
        // Implicit: output last expression

Try it online!

Prolog (SWI), 44 bytes

f(0,B,B).
f(A,_,A).
X*O:-scanl(f,X,0,[_|O]).

Try it online!

Vyxal, 2 bytes

ɖ∨

Try it Online!

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

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

Clojure, 49 bytes

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

Well this is very boring. TIO

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)

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)

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)

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

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!

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.

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

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.

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.

Husk, 2 bytes

G|

Try it online!

scan from left with or.

Factor, 36 bytes

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

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

Explanation

Jelly, 3 bytes

o@\

Try it online!

How it works

o      Take the logical OR of its arguments.
 @     Reverse the argument order of the link to the left.
  \    Do a cumulative reduce, using the link to the left.

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

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.

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.

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

Japt, 3 bytes

å!ª

Try it

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

Prolog (SWI), 54 bytes

[X,0|T]+[X,X|Y]:-[X|T]+[X|Y].
[X|T]+[X|Y]:-T+Y.
[]+[].

Try it online!

Explanation

I'm really happy with this answer.

First we say that the empty list is the solution of the empty list:

[]+[].

Then we say that [X,X|Y] is the solution of [X,0|T], if by removing the second entry of each of the remaining solutions.

[X,0|T]+[X,X|Y]:-[X|T]+[X|Y].

Lastly we say that any thing left over is valid if they start with the same value and the rest of the the two lists match each other.

If that explanation isn't working for you here is the code translated into Haskell:

g(a:0:x)=a:g(a:x)
g(a:x)=a:g x
g x=x

Try it online!

Mathematica, 28 27 25 bytes

Saved 2 bytes thanks to Martin Büttner.

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

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

Powershell, 32 bytes

param($x)$x|%{($t=($_,$t)[!$_])}

$x|%{...} does the script block for each element in $x. ($_,$t) is an array of current element and $t, and [!$_] means that we use !$_ to index into the array. The index will be 0 (false) for non-zero elements and 1 (true) when current element is zero, so $t will be either current element or $t. The parentheses surround the assignment expression so its value is emitted. Without parantheses it would be just a "quiet" assignment to $t.

CJam, 11 bytes

q~{1$e|}*]p

Try it online.

How it works

q~             Read and evaluate all input.
  {    }*      Fold; for each element but the first:
   1$e|          Copy the previous element and take their logical OR.
         ]p   Wrap all results in an array and print it.

Java, 78

int[]f(int[]a){for(int i=-1,b=i;++i<a.length;a[i]=b=a[i]==0?b:a[i]);return a;}

Here we just keep track of the last non-zero and shove it in where appropriate. Seems like the obvious way to do it.

Rust, 100 bytes

fn f(i:&[i64])->Vec<i64>{let(mut o,mut l)=(i.to_vec(),0);
for x in&mut o{if *x==0{*x=l}else{l=*x}};o}

Stumbled across this challenge, thought I'd try it in my favorite language. Tried using [T]::windows_mut() at first, before finding out that it doesn't exist. And it might've actually been longer than this. Anyway, it turns out that golfed Rust is very ugly and very not-competitive (especially with all those goshdarned esoterics!)1

The newline isn't included in the bytecount; it's only there so you don't have to scroll sideways. It doesn't change the meaning of the code.

Ungolfed:

fn cover_zeroes(input: &[i64]) -> Vec<i64> {
    let mut output = input.to_vec();
    let mut last_nonzero = 0;
    for item in &mut output {
        if *item == 0 {
            *item = last_nonzero;
        }
        else {
            last_nonzero = *item;
        }
    }
    output
}

[1] At least it's not as bad as Java.

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

R, 39 37 33 bytes

function(x)zoo::na.locf(x*(x|NA))

This is an unnamed function that accepts a vector and returns a vector. It requires the zoo package to be installed. Note that it doesn't require zoo to be attached to the namespace since we're referencing it directly.

The name for this operation in the world of statistics is LOCF imputation, where LOCF stands for Last Observation Carried Forward. To accomplish this in R, we can use na.locf from the zoo package, which replaces NA values with the last known non-NA value. We just have to replace the zeros in the input with NAs first.

To do that, we use x|NA, which will be TRUE when x != 0 and NA otherwise. If we multiply this by x, the TRUE elements are replaced by the corresponding elements of x and the NAs stay NA, thereby replacing all zeros. This is then passed to zoo::na.locf which gives us exactly what we want.

Saved 4 bytes thanks to flodel!

R, 36 bytes

function(x)x[cummax(seq(a=x)*(!!x))]

Let's see how this works using x=

c(1, 0, 2, 0, 7, 7, 7, 0, 5, 0, 0, 0, 9)

as an example. Here, !!x will be the logical (True/False) vector:

c(T, F, T, F, T, T, T, F, T, F, F, F, T)

Also, seq(a=x) gives a vector of indices as long as x:

c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13)

We multiply both, giving:

c(1, 0, 3, 0, 5, 6, 7, 0, 9, 0, 0, 0, 13)

We take the cumulative maximum:

c(1, 1, 3, 3, 5, 6, 7, 7, 9, 9, 9, 9, 13)

Finally, we use that last vector as the indices to extract from x:

c(1, 1, 2, 2, 7, 7, 7, 7, 5, 5, 5, 5, 9)

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

O, 31 bytes

[[I',T%T/]{n#}d]{n.{:V}{;V}?}d]

This takes an input separated by , and outputs the same list in [].

7,0,3,0,0,2,-50,0,0 => [7,7,3,3,3,2,-50,-50,-50]

Explanation:

[                             ] Put result into array
 [I',T%T/]{n#}d]                Format input into array of numbers
                {n.{:V}{;V}?}d  Fill in zeros (see below for how this works)

17 bytes

I~]{n.{:V}{;V}?}d

Takes input as a list of numbers separated by spaces using postfix notation and can only handle single digit hexadecimal numbers. Negatives are postfixed with _.

5 4 0 0 1 0 0 => 5 4 4 4 1 1 1
A 3 0 0 1 B 0 => 10 3 3 3 1 11 11
67* 0 0 78* 0 => 42 42 42 56 56
67*_ 4 3_ 0 0 => -42 4 -3 -3 -3

Explanation:

I~]               Puts input into integer array
   {           }d For each number in the input
    n.{;V}{:V}?   If the number is 0, push V
                  If not, set V to the number

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

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

rs, 14 bytes

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

1 byte shorter than Retina!!

Live demo and test cases.

Dyalog APL, 12 10 9 bytes

(⊃0~⍨,⍨)\

Inspired by @Zgarb's J answer.

(⊃0~⍨,⍨)\      Monadic function:
        \      Cumulative reduce by
(⊃0~⍨,⍨)       the dyadic function:
     ,⍨           Arguments concatenated in reverse order
  0~⍨             With zeroes removed
 ⊃                Take the first element

Try it here.

Perl 6, 21 bytes

*.map: {$_=($^a||$_)}

usage:

# store the Whatever lambda as a subroutine
# just so that we don't have to repeat it
my &code = *.map: {$_=($^a||$_)}

say code [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)

say [-1, 0, 5, 0, 0, -7].&code;
# (-1 -1 5 5 5 -7)

say ([1, 0, 0, 0, 0, 0],[-1, 0, 5, 0, 0, -7]).map: &code;
# ((1 1 1 1 1 1) (-1 -1 5 5 5 -7))

Gol><>, 8 bytes

IE;:Z~:N

Input and output are newline separated numbers.

Explanation:

I         push next integer to stack
 E;       halt if EOF
   :Z~    remove top stack element if 0
      :N  print top stack element while also keeping it on the stack
          wrap around code implicitly

Try it online here.

𝔼𝕊𝕄𝕚𝕟, 7 chars / 12 bytes

ïⓜa=$⋎a

Try it here (Firefox only).

Explanation

        // implicit: ï = input array
ïⓜ     // map over input
  a=    // set a to:
    $   // (if element is truthy (not 0)) element itself
     ⋎a // else whatever a was set to before
        // implicit output

Matlab, 41 46 bytes

This is inspired in my original answer, with the following differences:

  1. Use logical indexing instead of nonzeros.
  2. Double logical negation instead of comparing with 0.
  3. The transpose can be removed, as the output format is flexible
  4. Removing an intermediate variable.

Thanks to Tom Carpenter for item 4, and for his suggestion to use a program instead of a function; together these allowed a reduction of 5 bytes.

x=input('');u=x(~~x);disp(u(cumsum(~~x)))

Example:

>> x=input('');u=x(~~x);disp(u(cumsum(~~x)))
[4 0 3 2 0 5 6 0]
     4     4     3     2     2     5     6     6

Julia, 33 bytes

g(x,a=0)=[(i!=0&&(a=i);a)for i=x]

This is a function g that accepts an array and returns an array. We start a temporary variable a at 0. For each element i of the input, if i isn't 0 then we assign a to i. If i is 0, a doesn't change at that iteration. We use a as the value in that position in the output array.

Milky Way 1.2.1, 33 bytes

:y;=<:&{~<?{0b_^;:3≤_;}1-}^<Ω!

This assumes that the list of integers is solely on the stack.


Explanation

:    : :           :              # duplicate the TOS
 y                                # push the length of the TOS
  ;               ;    ;          # swap the TOS and STOS
   =                              # dump a list to the stack
    < <    <                 <    # rotate the stack leftward
        &{~                }      # while loop
            ?{  _     _ }         # if-else statements
              0     3    1        # push an integer
               b                  # == on the TOS and STOS
                 ^          ^     # pop the TOS without output
                     ≤            # rotate the top N stack elements leftward
                          -       # subtract the TOS from the STOS
                              Ω   # push a list made of the top N stack elements
                               !  # output the TOS

Retina, 15 bytes

+`(\S+) 0
$1 $1

Try it online.

Repeatedly replaces a number followed by a zero with twice that number until the string stops changing.

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.

Minkolang 0.14, 12 10 bytes

$I?.nd?xdN

Try it here. Input can be given as in the question, but without brackets.

Explanation

$I      Push the length of the input on the stack.
  ?.    If this is 0, stop. Otherwise, continue.

nd        Take number from input and duplicate it.
  ?x      If this number is 0, dump the top of stack.
    dN    Duplicate the top of stack and output as number

Minkolang is toroidal, so this loops around to the beginning and keeps going until it hits the . and stops.

Sed, 8

/^0$/g
h

Integers are newline separated. e.g:

$ printf -- "-1\n0\n5\n0\n0\n7\n" | sed -f zerocover.sed
-1
-1
5
5
5
7
$ 

GolfScript, 10 bytes

~{1$or}*]`

This program takes input from stdin, in the form of a GolfScript array literal (e.g. [1 0 2 0]), and writes its output to stdout in the same format (e.g. [1 1 2 2]).

Try it online.

A function (taking and returning a GolfScript array) would be three bytes longer, due to the need to wrap it in a block and assign it to a symbol:

{[{1$or}*]}:f

Of course, if only the function body (i.e. [{1$or}*]) is counted, then I can actually save one byte compared to the stand-alone program.

Pyth, 8 bytes

t.u|YNQ0

Uses .u (cumulative reduce) by | (Python's or), with base case 0.

Mathematica 38 bytes

Pattern matching repeatedly replaces ...a,0,... with ...a,a...

#//.{b___,a_/;a!=0,0,e___}:>{b,a,a,e}&

Javascript ES6, 19 bytes

s=>s.map(i=>p=i||p)

Straightforward solution, loop through input, assign p to current element i or to p if i is 0 and output it.

Example run (assigning anonymous function to f):

>> f([1, 0, 2, 0, 7, 7, 7, 0, 5, 0, 0, 0, 9])
<< Array [1, 1, 2, 2, 7, 7, 7, 7, 5, 5, 5, 5, 9]

J, 8 bytes

{:@-.&0\

This is a unary function, invoked as follows.

   f =: {:@-.&0\
   f 2 0 0 4 0 _1 0
2 2 2 4 4 _1 _1

Explanation

{:@-.&0\
       \  Map over non-empty prefixes:
   -.      remove all occurrences
     &0    of the number 0 and
{:@        take the last element.

Pyth, 6 bytes

mJ|dJQ

Demonstration

m ... Q means this maps a function over the input. The function being mapped is J|dJ. That means J = d or J in Python, since J is implicity assigned to the following value on first use. Unlike Python, assignment expressions return the value assigned in Pyth, so the map returns each successive value of J, as desired.

Python 2, 29 bytes

while 1:x=input()or x;print x

Takes input as numbers given one per line, and outputs in the same format. Terminates with error after finishing.

Using the short-circuiting nature of or, the variable x is updated to the input, unless that input is 0 (which is Falsey), in which case it remains its current value. Then, x is printed. Note that since the first list value is nonzero, x is not evaluated in the right hand side before it is assigned.

Ruby, 25 bytes

->a{a.map{|x|x==0?a:a=x}}

This is actually really evil.

Specifically, the snippet x==0 ? a : (a=x).

If I had used any other variable name for a (the previous nonzero value)—let's say y—I would have to declare it outside the map (because y=x would only have a scope of inside that single map iteration). That would use four chars more (y=0;).

But if I use the variable name a... yep, you guessed it. I'm actually reassigning to the argument that we got as input (the original array).

map doesn't care because it only cares about the original value of the thing its being called on, so this actually works.

Haskell, 21 bytes

a%0=a
a%b=b
scanl1(%)

The (anonymous) function we make is in the last line. The first two lines define a helper function.

scanl1(%) [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]

The binary function % outputs the second argument, unless it's 0, in which case it outputs the first argument instead. scanl1 iterates this function over the input list, outputting the result at each step.