4
\$\begingroup\$

This question already has an answer here:

Given a non-empty list of decimal digits (0, 1, ..., 9), replace each zero by the most recent nonzero, if possible.

Example 1: given

1 4 3 0 0 7 5 5 0 3

the output should be

1 4 3 3 3 7 5 5 5 3

Note how the first two zeros are replaced by 3, which is the most recent (i.e. rightmost) nonzero. Similarly, the last zero is replaced by 5.

Example 2: given

0 0 4 0 0 5 0

the output should be

0 0 4 4 4 5 5

Note how it is not possible to replace the first two zeros, because there isn't a nonzero number to the left ot them.

Additional rules

Test cases

Input, then output

1 4 3 0 0 7 5 5 0 3
1 4 3 3 3 7 5 5 5 3

0 0 4 0 0 5 0
0 0 4 4 4 5 5

0 0 0
0 0 0

0
0

0 1
0 1

4 2 1 0
4 2 1 1

8 0 0 0 6
8 8 8 8 6
\$\endgroup\$

marked as duplicate by AdmBorkBork code-golf Sep 27 at 16:14

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

  • 1
    \$\begingroup\$ Dupe? I think this challenge is generally worded better but I'm not sure being single positive digits and leading zeros changes the result in enough languages. \$\endgroup\$ – FryAmTheEggman Sep 27 at 16:08
  • \$\begingroup\$ @Fry I’m not sure. I didn’t remember yours. But the leading zeros do make a difference. What do others think? \$\endgroup\$ – Luis Mendo Sep 27 at 16:12
  • \$\begingroup\$ Three votes for a dupe from Code-Gold members is enough for me. \$\endgroup\$ – AdmBorkBork Sep 27 at 16:14
  • \$\begingroup\$ @Adm I changed my mind (and edited my comment) because of the leading zeros. But I’m not sure that makes it different enough. You are probably right \$\endgroup\$ – Luis Mendo Sep 27 at 16:21
  • 1
    \$\begingroup\$ @LuisMendo Yeah! But I figured nearly 4 years was long enough that I could forgive you ;) \$\endgroup\$ – FryAmTheEggman Sep 27 at 16:40
4
\$\begingroup\$

JavaScript (ES6),  22  21 bytes

A=>A.map(x=>A=x||~~A)

Try it online!

Commented

A =>          // A[] = input array
  A.map(x =>  // for each value x in A[]:
    A =       //   update A to:
      x ||    //     either x, if it's not equal to 0
      ~~A     //     or A coerced to an integer otherwise
  )           // end of map()

Because we're re-using the input array \$A[\:]\$ to store the last non-zero value, two special cases arise if the 2nd part of the condition is executed on the 1st iteration:

  • if \$A[\:]\$ is a singleton array containing \$0\$, ~~A is equal to ~~0
  • if \$A[\:]\$ is an array of several elements (starting with \$0\$), ~~A is equal to ~~NaN

which gives the expected \$0\$ in both cases.

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

Mathematica, 19 17 bytes

f@x_:=f@0=x;Map@f

Try it online!

Inspired by kglr's answer to a question on Mathematica Stack Exchange, which I assume was the inspiration for this challenge. :)

In the body of f, the value of f[0] is redefined to be the input, which is also returned. That way, whenever f is called with 0 after the first time it's called, it will always yield the "remembered" result, which is updated when f is called again with a nonzero argument.

Thanks to @attinat for 2 bytes.

mikado's answer yields a 20 byte solution:

FoldList[#2/. 0->#&]
\$\endgroup\$
  • \$\begingroup\$ simple -2 bytes with @ instead of [ ] \$\endgroup\$ – attinat Sep 27 at 21:34
2
\$\begingroup\$

Perl 5 -p, 21 bytes

s/([^0])0/$1$1/&&redo

Try it online!

\$\endgroup\$
  • \$\begingroup\$ Here's another 21, using math. \$\endgroup\$ – Grimy Sep 27 at 16:01
  • \$\begingroup\$ @Grimy Interesting idea, but it doesn't seem to work if the preceding digit is a nine: Try it online! \$\endgroup\$ – Xcali Sep 27 at 16:15
  • \$\begingroup\$ Right, my bad. It takes at least 2 bytes to fix it, so it's not worth it. \$\endgroup\$ – Grimy Sep 27 at 16:19
1
\$\begingroup\$

05AB1E, 5 bytes

ηε0†θ

Try it online!

For each prefix of the input, filter 0s to the front, then get its last digit. Yes, filter-to-the-front is somehow a single-byte built-in (). I didn't think I'd ever need it, but here we are.

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

Java 10, 65 bytes

s->{while(!s.equals(s=s.replaceAll("(.) 0","$1 $1")));return s;};

A Function that repeatedly replaces "N 0" with "N N" until such time as the String stops changing, then returns it.

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

Jelly, 3 bytes

ȯ@\

Try it online!

-2 bytes thanks to FryAmTheEggMan (it's close to being an entirely new solution because 5 -> 3 bytes is a 40% deduction and that's like half the code lol)

Explanation

ȯ@\  Main Program
  \  Cumulative Reduce
ȯ@   Logical OR (inverted; basically "right OR left")
\$\endgroup\$
  • \$\begingroup\$ @FryAmTheEggman That's clever, thanks! \$\endgroup\$ – HyperNeutrino Sep 27 at 17:24
1
\$\begingroup\$

K (ngn/k), 11 bytes

{$[y;y;x]}\

Try it online!

{ }\ scan - starting with the first element, apply the function in { } between the current result and the next element. collect intermediate results in a list.

$[y;y;x] cond - if the right argument y is truthy (not 0), return it, otherwise return the left argument x

\$\endgroup\$

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