Challenge
Given a string of any length which contains only digits from 0 to 9, replace each consecutive run of the digit 0 with its length.
Test Cases
1234500362000440→1234523623441123450036200044→123452362344000000000000→120123456789→11234567891234567890→1234567891123456789→123456789010203004050→11121324151
Note
The shortest answer in bytes wins as per code-golf rules
50 Answers 50
Retina 0.8.2, 6 bytes
0+
$.&
Try it online! Link includes test cases. Explanation: Unary to decimal conversion.
-
\$\begingroup\$ That
&is neat! What does it do? \$\endgroup\$Luis Mendo– Luis Mendo2022年12月21日 12:48:05 +00:00Commented Dec 21, 2022 at 12:48 -
\$\begingroup\$ @LuisMendo It refers to the entire match, like
0ドルdoes in Perl. \$\endgroup\$Neil– Neil2022年12月21日 13:04:40 +00:00Commented Dec 21, 2022 at 13:04 -
\$\begingroup\$ @LuisMendo Actually my original source was wrong; PCRE, PHP and Java use
0ドルbut Perl actually uses$&, as does JavaScript. (Retina actually supports both.) \$\endgroup\$Neil– Neil2022年12月22日 10:00:14 +00:00Commented Dec 22, 2022 at 10:00
Pip, 7 bytes
-1 byte by jezza_99 / DLosc
aR+X0#_
Wow pip is really good at regex
aR+X0#_
aR+X0 Replace all occurrences of (regexified zero with a +)
#_ with it's length
-
\$\begingroup\$ @DLosc might have another method, but I got this 7-byter \$\endgroup\$jezza_99– jezza_992022年12月21日 22:12:22 +00:00Commented Dec 21, 2022 at 22:12
Vyxal s, 7 bytes
ĠṠƛ0cßL
Explained
ĠṠƛ0cßL
Ġ # Group on consecutive items
Ṡ # join each into a single string
ƛ # To each group:
0c # if it contains 0:
ßL # push the length of the string
# the s flag joins into a single string
An alternate 8 byter that uses regex match replacement
‛0+$(Løṙ
Explained
‛0+$(Løṙ
‛0+ # The string "0+"
$ # pushed under the input
(L # a function object that returns the length of its argument
øṙ # replace instances of runs of 0 with their length
Python 3, (削除) 91 (削除ここまで) 90 bytes
lambda x:''.join(l>"0"and l or f'{len([*g])}'for l,g in groupby(x))
from itertools import*
-1 byte thanks to The Thonnu
I use the itertools module's groupby function to group consecutively.
-
1\$\begingroup\$ You can replace the
!=with>to save a byte: Try it online! \$\endgroup\$The Thonnu– The Thonnu2022年12月21日 14:07:40 +00:00Commented Dec 21, 2022 at 14:07 -
1\$\begingroup\$ @TheThonnu Thanks! \$\endgroup\$U13-Forward– U13-Forward2022年12月21日 14:26:42 +00:00Commented Dec 21, 2022 at 14:26
-
\$\begingroup\$ As this is a recursive lambda, you'll need to include the
f=in your byte count. \$\endgroup\$Shaggy– Shaggy2022年12月21日 14:39:17 +00:00Commented Dec 21, 2022 at 14:39 -
2\$\begingroup\$ @Shaggy This isn't a recursive lambda, I am not calling the function within it. \$\endgroup\$U13-Forward– U13-Forward2022年12月21日 14:40:00 +00:00Commented Dec 21, 2022 at 14:40
05AB1E, 7 bytes
0ÃηRāR:
- -6 thanks to Kevin Cruijssen
Explanation
0ÃηRāR: # Implicit input
0Ã # List intersection with [0]
ηR # Reversed prefixes
āR # Reversed length range
: # Infinite replacement
Previous 13 byte answer
.γ}εD0.åig}}J # Implicit input
.γ} # Group by consecutive items
ε } # For each group:
D # Duplicate the group
0.åi } # If 0 is in the group:
g # Push its length
J # Join everything into a single string
-
\$\begingroup\$
.γ}can beγ;0.åcan be_and}}can be]for 8 bytes: try it online. Although0ÃηRāR:is 1 byte shorter: try it online. \$\endgroup\$Kevin Cruijssen– Kevin Cruijssen2022年12月28日 08:27:02 +00:00Commented Dec 28, 2022 at 8:27 -
\$\begingroup\$ @KevinCruijssen thanks \$\endgroup\$The Thonnu– The Thonnu2022年12月28日 10:19:30 +00:00Commented Dec 28, 2022 at 10:19
R, (削除) 64 (削除ここまで) (削除) 58 (削除ここまで) 57 bytes
Edit: -1 byte thanks to @Dominic van Essen .
\(x){regmatches(x,t)=Map(attr,t<-gregexpr("0+",x),"m")
x}
R has some weird string manipulation functions...
-
\$\begingroup\$ Can't you swap the
<-for simply=in the 2-liner to save a byte? \$\endgroup\$Dominic van Essen– Dominic van Essen2022年12月22日 07:33:21 +00:00Commented Dec 22, 2022 at 7:33 -
\$\begingroup\$ @DominicvanEssen, well, to my surprise, I can. Thanks! I thought that
...<-functions need the actual<-, but after a while of thought[<-works well with=, so why not other functions like that? \$\endgroup\$pajonk– pajonk2022年12月22日 08:28:16 +00:00Commented Dec 22, 2022 at 8:28
-
2\$\begingroup\$ still annoyed this can't be
.=chars\$\endgroup\$Jo King– Jo King2022年12月23日 03:55:26 +00:00Commented Dec 23, 2022 at 3:55
Bash - (削除) 181 (削除ここまで) 158 chars
Edit 1: I used this trick for the for loop, remove whitespace, condence an if statement
n=0;for ((i=0;i<${#1};i++));{ c="${1:$i:1}";if [ $c = '0' ]; then ((n++)); else [ $n -ne 0 ] && { echo -n $n;n=0;};echo -n $c;fi;};[ $n -ne 0 ] && echo -n $n
Explanation
# a counter of how far into a sequence of zeros we are
# this is zero if we're not in a 'zero-sequence'
n=0
# iterate over all the characters
# 1ドル is the first function argument (0ドル would be the script name)
for (( i=0; i<${#1}; i++ )); do
# get the current char
c="${1:$i:1}"
# if it is a zero, then increment the counter
if [ $c = '0' ]; then
((n++));
# if it is NOT a zero
else
# if a zero sequence is over (given that the counter is
# not equal to zero and the current char isn't zero)
if [ $n -ne 0 ]; then
# print the number of zeros in the sequence,
# and reset the counter to zero
echo -n $n;
n=0;
fi;
echo -n $c;
fi
done
# check if there was a zero sequence terminating the string,
# as we wouldn't otherwise check as there wouldn't be a non-zero
# char initiating the check
if [ $n -ne 0 ]; then echo -n $n; fi
I referred to this SO answer for how to iterate over a string in Bash and this AU answer for a short way to increment a variable
Vim, 28 bytes
:s/0\+/\=len(submatch(0))/g
Enter
We cannot use 0* because it matches the empty string between digits.
-
\$\begingroup\$ Here's a TIO link for you. The
%isn't necessary because the input "contains only digits from 0 to 9" and therefore contains no newlines. However, if your language is Vim and not V, I think you have to count the Enter keypress after the replace command (otherwise, the replacement doesn't happen), so that makes it 28 bytes. If you want to call it V instead of Vim, you can skip the newline and claim 27 bytes. \$\endgroup\$DLosc– DLosc2022年12月22日 18:22:41 +00:00Commented Dec 22, 2022 at 18:22 -
\$\begingroup\$ Thanks @DLosc, edited. \$\endgroup\$D. Ben Knoble– D. Ben Knoble2022年12月22日 23:13:25 +00:00Commented Dec 22, 2022 at 23:13
Retina 0.8.2, 8 bytes
(0+)
$.1
How it works
Match runs of zeros (0+), capture each match in a group (( )), replace it with the length of the most recent capture ($.1).
-
\$\begingroup\$ Oh, I see you had already posted your answer while I was writing mine. Sorry to outgolf you like that. \$\endgroup\$Neil– Neil2022年12月21日 13:49:11 +00:00Commented Dec 21, 2022 at 13:49
-
\$\begingroup\$ @Neil No problem at all, and great answer! \$\endgroup\$Luis Mendo– Luis Mendo2022年12月21日 14:13:40 +00:00Commented Dec 21, 2022 at 14:13
Python, (削除) 62 (削除ここまで) 57 bytes
lambda n:re.sub("0+",lambda s:str(len(s[0])),n)
import re
-5 bytes thanks to @xnor
Regex solution, port of @mathcat's Pip answer
-
2\$\begingroup\$ I think you can do
s[0]in place ofs.group()\$\endgroup\$xnor– xnor2022年12月22日 00:25:08 +00:00Commented Dec 22, 2022 at 0:25
Brachylog, 11 bytes
ḅ{ị0&lṫ|}mc
Explanation
I was hoping for some automatic number -> string conversion, but no dice.
ḅ{ị0&lṫ|}mc
ḅ Break the input string into blocks of identical characters
{ }m Map this predicate to each block:
ị Convert to integer
0 Assert that the result is zero
&l If so, get the length of the block
ṫ and convert to string
| If that failed (because the number wasn't zero), return the block unchanged
c Concatenate the results together into a single string
Excel VBA, (削除) 100 (削除ここまで) 77 bytes
Saved 23 bytes thanks to a translation by Taylor Raine
For i=2^15-1To 1Step-1:[B1]=i:[A1]=[Substitute(A1,Rept(0,B1),B1)]:Next:[B1]="
Input is in the cell A1 of the active sheet. Output is in the same cell. The code is run from the immediate window in VBA. The only clever bit is that Excel only allows 32,767 characters in a cell and counting down from there is less bytes than counting down from the length of the input.
-
1\$\begingroup\$ You could make this into an immediate window function something like
For i=2^15-1To 1Step-1:[B1]=i:[A1]=[Substitute(A1,Rept(0,B1),B1)]:Next:[B1]="for a pretty significant drop in bytes. (Also reminder that using^with no leading space makes this a 32-bit only solution as^is theLonglongtype literal in 64-bit installs of excel) \$\endgroup\$Taylor Raine– Taylor Raine2023年04月12日 01:12:56 +00:00Commented Apr 12, 2023 at 1:12
K (ngn/k), 25 bytes
{,/$(.'x)|#'x:(&~=':x)_x}
x:(&~=':x)_xsplit the input where it changes, and reassign tox(.'x)|#'xtake the maximum of the chunk of input (converted to its corresponding integer) and its count,/$convert to strings and flatten (and implicitly return)
Jelly, 8 bytes
Œgċ"0ȯƊ€
A full program that accepts a string of digit characters and prints the result.
How?
Œgċ"0ȯƊ€ - Main Link: list of characters, S
Œg - group runs
€ - for each group:
Ɗ - last three links as a monad - f(group):
"0 - literal '0' character
ċ - count occurrences
ȯ - logical OR (group)
- implicit, smashing print
Java, 88 bytes
s->java.util.regex.Pattern.compile("0+").matcher(s).replaceAll(r->r.group().length()+"")
Java 19, 156 (削除) 161 (削除ここまで) (削除) 162 (削除ここまで) bytes
interface A{static void main(String[] a){var i=0;var s="";for(var c:a[0].toCharArray())if(c==48)i++;else{s+=i>0?i+""+c:c;i=0;}System.out.print(i>0?s+i:s);}}
Without Java's golfing tax, 113 bytes
var i=0;var s="";for(var c:a[0].toCharArray())if(c==48)i++;else{s+=i>0?i+""+c:c;i=0;}System.out.print(i>0?s+i:s);
Edit: replaced '0' with 48 as suggested in the comments. Thanks!
Edit: String concatentation is shorter than doing var o=System.out;
-
\$\begingroup\$ Welcome to Code Golf, and nice answer! \$\endgroup\$2022年12月27日 04:09:08 +00:00Commented Dec 27, 2022 at 4:09
0s replaced with?11? \$\endgroup\$10as no modifications to the output were also needed, as most answers suggest \$\endgroup\$