31
\$\begingroup\$

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

  1. 12345003620004401234523623441
  2. 123450036200044123452362344
  3. 00000000000012
  4. 01234567891123456789
  5. 12345678901234567891
  6. 123456789123456789
  7. 01020300405011121324151

Note

The shortest answer in bytes wins as per rules

iBug
2,73118 silver badges37 bronze badges
asked Dec 21, 2022 at 12:11
\$\endgroup\$
2
  • 3
    \$\begingroup\$ What is a run of \10ドル\$ 0s replaced with? 11? \$\endgroup\$ Commented Dec 21, 2022 at 12:28
  • 1
    \$\begingroup\$ Not OP, but I think it will be replaced with 10 as no modifications to the output were also needed, as most answers suggest \$\endgroup\$ Commented Dec 21, 2022 at 12:45

50 Answers 50

1
2
15
\$\begingroup\$

Retina 0.8.2, 6 bytes

0+
$.&

Try it online! Link includes test cases. Explanation: Unary to decimal conversion.

answered Dec 21, 2022 at 12:39
\$\endgroup\$
3
  • \$\begingroup\$ That & is neat! What does it do? \$\endgroup\$ Commented Dec 21, 2022 at 12:48
  • \$\begingroup\$ @LuisMendo It refers to the entire match, like 0ドル does in Perl. \$\endgroup\$ Commented 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\$ Commented Dec 22, 2022 at 10:00
11
\$\begingroup\$

JavaScript, 31 bytes

s=>s.replace(/0+/g,x=>x.length)

Try it online!

answered Dec 21, 2022 at 12:40
\$\endgroup\$
10
\$\begingroup\$

Pip, 7 bytes

-1 byte by jezza_99 / DLosc

aR+X0#_

Wow pip is really good at regex

Try It Online!

aR+X0#_
aR+X0 Replace all occurrences of (regexified zero with a +)
 #_ with it's length
answered Dec 21, 2022 at 12:31
\$\endgroup\$
1
  • \$\begingroup\$ @DLosc might have another method, but I got this 7-byter \$\endgroup\$ Commented Dec 21, 2022 at 22:12
10
\$\begingroup\$

Japt, 7 bytes

r+iT Èl

Try it here

r+iT Èl :Implicit input of string
r :Replace
 +i : "+" prepended with
 T : 0, giving the RegEx /0+/g
 È : Pass each match through a function
 l : Length
answered Dec 21, 2022 at 12:38
\$\endgroup\$
9
\$\begingroup\$

QuadR, 5 bytes

0+
⍵L

Try it online!

0+ Replace any runs of zeros

⍵L with the match Length

answered Dec 21, 2022 at 12:34
\$\endgroup\$
7
\$\begingroup\$

Vyxal s, 7 bytes

ĠṠƛ0cßL

Try it Online!

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øṙ

Try it Online!

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
answered Dec 21, 2022 at 12:15
\$\endgroup\$
6
\$\begingroup\$

><>, 55 bytes

i:'0'= ?v>:0(?;o
='0':i<1<\n$v?
 \+1~ /

Try it

answered Dec 21, 2022 at 12:53
\$\endgroup\$
6
\$\begingroup\$

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*

Try it online!

-1 byte thanks to The Thonnu

I use the itertools module's groupby function to group consecutively.

answered Dec 21, 2022 at 12:25
\$\endgroup\$
4
  • 1
    \$\begingroup\$ You can replace the != with > to save a byte: Try it online! \$\endgroup\$ Commented Dec 21, 2022 at 14:07
  • 1
    \$\begingroup\$ @TheThonnu Thanks! \$\endgroup\$ Commented 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\$ Commented Dec 21, 2022 at 14:39
  • 2
    \$\begingroup\$ @Shaggy This isn't a recursive lambda, I am not calling the function within it. \$\endgroup\$ Commented Dec 21, 2022 at 14:40
6
\$\begingroup\$

Perl 5 -p, 16 bytes

s/0+/length$&/eg

Try it online!

answered Dec 21, 2022 at 23:58
\$\endgroup\$
6
\$\begingroup\$

05AB1E, 7 bytes

0ÃηRāR:

Try it online!

  • -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
answered Dec 21, 2022 at 13:57
\$\endgroup\$
2
  • \$\begingroup\$ .γ} can be γ; 0.å can be _ and }} can be ] for 8 bytes: try it online. Although 0ÃηRāR: is 1 byte shorter: try it online. \$\endgroup\$ Commented Dec 28, 2022 at 8:27
  • \$\begingroup\$ @KevinCruijssen thanks \$\endgroup\$ Commented Dec 28, 2022 at 10:19
5
\$\begingroup\$

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}

Attempt This Online!

R has some weird string manipulation functions...

answered Dec 21, 2022 at 13:44
\$\endgroup\$
2
  • \$\begingroup\$ Can't you swap the <- for simply = in the 2-liner to save a byte? \$\endgroup\$ Commented 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\$ Commented Dec 22, 2022 at 8:28
4
\$\begingroup\$

Raku, 18 bytes

{S:g[0+]=$/.chars}

Try it online!

answered Dec 21, 2022 at 17:32
\$\endgroup\$
1
  • 2
    \$\begingroup\$ still annoyed this can't be .=chars \$\endgroup\$ Commented Dec 23, 2022 at 3:55
4
\$\begingroup\$

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

answered Dec 22, 2022 at 4:04
\$\endgroup\$
0
4
\$\begingroup\$

Vim, 28 bytes

:s/0\+/\=len(submatch(0))/g Enter

Try it online!

We cannot use 0* because it matches the empty string between digits.

answered Dec 22, 2022 at 15:54
\$\endgroup\$
2
  • \$\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\$ Commented Dec 22, 2022 at 18:22
  • \$\begingroup\$ Thanks @DLosc, edited. \$\endgroup\$ Commented Dec 22, 2022 at 23:13
3
\$\begingroup\$

Retina 0.8.2, 8 bytes

(0+)
$.1

Try it online!

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

answered Dec 21, 2022 at 12:38
\$\endgroup\$
2
  • \$\begingroup\$ Oh, I see you had already posted your answer while I was writing mine. Sorry to outgolf you like that. \$\endgroup\$ Commented Dec 21, 2022 at 13:49
  • \$\begingroup\$ @Neil No problem at all, and great answer! \$\endgroup\$ Commented Dec 21, 2022 at 14:13
3
\$\begingroup\$

><>, 28 bytes

0i:"0"=?v{:?n}ol?!
~1+00. >

Try it online!

answered Dec 21, 2022 at 15:21
\$\endgroup\$
3
\$\begingroup\$

Ruby, 16 bytes

gsub /0+/,&:size

Attempt This Online!

answered Dec 21, 2022 at 19:41
\$\endgroup\$
3
\$\begingroup\$

Python, (削除) 62 (削除ここまで) 57 bytes

lambda n:re.sub("0+",lambda s:str(len(s[0])),n)
import re

Attempt This Online!

-5 bytes thanks to @xnor

Regex solution, port of @mathcat's Pip answer

answered Dec 21, 2022 at 22:28
\$\endgroup\$
1
  • 2
    \$\begingroup\$ I think you can do s[0] in place of s.group() \$\endgroup\$ Commented Dec 22, 2022 at 0:25
3
\$\begingroup\$

Brachylog, 11 bytes

ḅ{ị0&lṫ|}mc

Try it online!

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
answered Dec 22, 2022 at 18:30
\$\endgroup\$
3
\$\begingroup\$

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.

answered Dec 21, 2022 at 22:45
\$\endgroup\$
1
  • 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 the Longlong type literal in 64-bit installs of excel) \$\endgroup\$ Commented Apr 12, 2023 at 1:12
3
\$\begingroup\$

K (ngn/k), 25 bytes

{,/$(.'x)|#'x:(&~=':x)_x}

Try it online!

  • x:(&~=':x)_x split the input where it changes, and reassign to x
  • (.'x)|#'x take the maximum of the chunk of input (converted to its corresponding integer) and its count
  • ,/$ convert to strings and flatten (and implicitly return)
answered Apr 12, 2023 at 20:24
\$\endgroup\$
3
\$\begingroup\$

C (gcc), 70 bytes

n;f(char*a){*a-48?n=!printf(n?"%d":"%c",n?:*a++),*a&&f(a):f(a+!!++n);}

Try it online!

C (gcc), 62 bytes by c--

n;f(int*a){*a-48?n=!printf(n?"%d":a++,n),*a&&f(a):f(a+!!++n);}

Try it online!

answered Dec 21, 2022 at 15:45
\$\endgroup\$
0
2
\$\begingroup\$

Julia 1.0, 27 bytes

!x=replace(x,r"0+"=>length)

Try it online!

answered Dec 21, 2022 at 16:25
\$\endgroup\$
2
\$\begingroup\$

Jelly, 8 bytes

Œgċ"0ȯƊ€

A full program that accepts a string of digit characters and prints the result.

Try it online!

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
answered Dec 21, 2022 at 18:21
\$\endgroup\$
2
\$\begingroup\$

Husk, 8 bytes

ṁ?IosLig

Try it online!

answered Dec 21, 2022 at 21:44
\$\endgroup\$
2
\$\begingroup\$

Factor, 42 bytes

[ R/ 0+/ [ length >dec ] re-replace-with ]

Try it online!

answered Dec 22, 2022 at 0:07
\$\endgroup\$
2
\$\begingroup\$

Zsh --extendedglob, 24 bytes

<<<${1//(#m)0##/$#MATCH}

Try it Online!

answered Dec 22, 2022 at 12:39
\$\endgroup\$
2
\$\begingroup\$

Java, 88 bytes

s->java.util.regex.Pattern.compile("0+").matcher(s).replaceAll(r->r.group().length()+"")

Try it online!

answered Dec 22, 2022 at 19:58
\$\endgroup\$
2
\$\begingroup\$

><>, (削除) 23 (削除ここまで) 18 bytes

\&l:?n&o]
\i:'0'-?

Try it online!

answered Dec 23, 2022 at 3:24
\$\endgroup\$
2
\$\begingroup\$

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

Try it online!

Edit: replaced '0' with 48 as suggested in the comments. Thanks!

Edit: String concatentation is shorter than doing var o=System.out;

answered Dec 27, 2022 at 3:40
\$\endgroup\$
1
  • \$\begingroup\$ Welcome to Code Golf, and nice answer! \$\endgroup\$ Commented Dec 27, 2022 at 4:09
1
2

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.