41
\$\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\$
  • 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 '15 at 0:12
  • \$\begingroup\$ What happens if the input was [0,0]? \$\endgroup\$ – user41805 Dec 5 '15 at 6:56
  • 4
    \$\begingroup\$ @KριτικσιΛίθος "...where the first value is guaranteed to be non-zero" \$\endgroup\$ – Sp3000 Dec 5 '15 at 7:49
  • \$\begingroup\$ What if the input is [1,01]? Using, issac's Pyth answer, compare this and this. \$\endgroup\$ – Arcturus Dec 6 '15 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\$ – FryAmTheEggman Dec 6 '15 at 0:52

42 Answers 42

1
2
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\$

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\$
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\$
  • \$\begingroup\$ Running your test program on Ideone.com doesn't seem to work - it just duplicates the first number. \$\endgroup\$ – AdmBorkBork Dec 9 '15 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 '15 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\$ – AdmBorkBork Dec 9 '15 at 20:45
  • \$\begingroup\$ Also, welcome to Programming Puzzles & Code Golf! \$\endgroup\$ – AdmBorkBork Dec 9 '15 at 20:51
  • \$\begingroup\$ Thanks, slow day in work and I usually just read through these... \$\endgroup\$ – cleblanc Dec 9 '15 at 21:09
2
\$\begingroup\$

Mathematica, 28 27 25 bytes

Saved 2 bytes thanks to Martin Büttner.

If[#2==0,##]&~FoldList~#&
\$\endgroup\$
  • 1
    \$\begingroup\$ If[#2==0,##]&~FoldList~#&? \$\endgroup\$ – Martin Ender Dec 22 '15 at 17:17
2
\$\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\$
2
\$\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\$
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\$
  • 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 '15 at 8:25
  • \$\begingroup\$ @quintopia Hush, people are going to think you're my sock :P \$\endgroup\$ – Mego Dec 27 '15 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\$
  • \$\begingroup\$ b||c saves one byte over b?b:c. \$\endgroup\$ – Neil Dec 6 '15 at 19:18
  • \$\begingroup\$ Although then you just end up with @Dendrobium's answer. \$\endgroup\$ – Neil Dec 6 '15 at 19:24
  • \$\begingroup\$ His is surperior, I don't want to impersonate him \$\endgroup\$ – MayorMonty Dec 6 '15 at 21:48
  • \$\begingroup\$ (I hadn't seen his answer when I wrote my first comment.) \$\endgroup\$ – Neil Dec 7 '15 at 10:43
  • \$\begingroup\$ You're fine, but if his is better, than is better so be it. \$\endgroup\$ – MayorMonty Dec 8 '15 at 21:42
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.