33
\$\begingroup\$

Task

Given a non-empty array of 0 and 1, halve the lengths of the runs of 0.

Input

An array of 0 and 1. Acceptable format:

  • Real array in your language
  • Linefeed-separated string of 0 and 1
  • Contiguous string of 0 and 1
  • Any other reasonable format

For example, the following three inputs are all acceptable:

  • [1, 0, 0, 1]
  • "1\n0\n0\n1" (where \n is a linefeed U+000A)
  • "1001"

You may assume that the runs of 0 will have even length.

Output

An array of 0 and 1, in the acceptable formats above.

Testcases

input ↦ output
[1,0,0,1,0,0,1] ↦ [1,0,1,0,1]
[1,1,0,0,1,1,0,0,1] ↦ [1,1,0,1,1,0,1]
[1,1,0,0,1,1,1,0,0,1,1] ↦ [1,1,0,1,1,1,0,1,1]
[1,1,1] ↦ [1,1,1]
[0,0,1] ↦ [0,1]
[0,0] ↦ [0]
[1,1,1,0,0,0,0,1,1,1,1,0,0,1,0,0,1,1,0,0,1,1,1,1,0,0,1,0,0] ↦ [1,1,1,0,0,1,1,1,1,0,1,0,1,1,0,1,1,1,1,0,1,0]

Scoring

This is . Shortest answer in bytes wins.

Standard loopholes apply.

\$\endgroup\$
10
  • \$\begingroup\$ In the last testcase, don't the runs of zeroes not have even length? \$\endgroup\$
    – AAM111
    May 3, 2017 at 11:26
  • \$\begingroup\$ @OldBunny2800 Read the test case carefully; the 0-runs have lengths 4, 2, 2, 2, 2, and 2. \$\endgroup\$
    – hyper-neutrino
    May 3, 2017 at 12:21
  • \$\begingroup\$ Can we take true and false instead of 1 and 0? \$\endgroup\$
    – Cyoce
    May 3, 2017 at 18:13
  • \$\begingroup\$ @Cyoce which language? \$\endgroup\$
    – Leaky Nun
    May 3, 2017 at 18:15
  • 1
    \$\begingroup\$ @LeakyNun Ruby, which considers 0 to be truthy. \$\endgroup\$
    – Cyoce
    May 3, 2017 at 18:16

62 Answers 62

30
\$\begingroup\$

Retina, 4 bytes

00
0

Try it online!

\$\endgroup\$
3
  • \$\begingroup\$ This one will be hard to beat. \$\endgroup\$
    – Adám
    May 3, 2017 at 10:15
  • \$\begingroup\$ @Adám I'd say impossible to beat. \$\endgroup\$ May 3, 2017 at 11:13
  • 1
    \$\begingroup\$ Works in QuadR too! \$\endgroup\$
    – Adám
    Jun 27, 2017 at 10:07
13
\$\begingroup\$

05AB1E, 5 bytes

00¤.:

Try it online!

Explanation

00     # push 00
  ¤    # tail, pushes 0
   .:  # replace
\$\endgroup\$
4
  • 2
    \$\begingroup\$ That was easy; why didn't I think of that? \$\endgroup\$
    – Leaky Nun
    May 3, 2017 at 7:09
  • \$\begingroup\$ 00 is weird behavior... \$\endgroup\$ May 3, 2017 at 10:45
  • 1
    \$\begingroup\$ @EriktheOutgolfer: Sequential digits are concatenated to form a number, so 11 is eleven and not 1,1. A side effect of that is that 00 becomes 00 instead of 0,0 :) \$\endgroup\$
    – Emigna
    May 3, 2017 at 10:48
  • \$\begingroup\$ @Emigna I'd have expected it to become 0 or 0 0 instead, but whatever. \$\endgroup\$ May 3, 2017 at 10:56
8
\$\begingroup\$

Haskell, 33 bytes

f(0:0:r)=0:f r
f(x:r)=x:f r
f e=e

Try it online! Usage: f[1,1,0,0,1,1,0,0,1]. Iterates over the list and replaces two consecutive zeros by one zero.

\$\endgroup\$
1
  • \$\begingroup\$ I feel that this can be forked to Prolog \$\endgroup\$
    – Leaky Nun
    May 3, 2017 at 7:20
8
\$\begingroup\$

C (gcc), 35 bytes

f(char*s){while(*s)putchar(*s),*s++-48?:s++;}

48 is the ascii code of '0'

better version 43 bytes as suggested by Neil

f(char*s){while(*s)putchar(*s),s+=2-*s%2;}

another one 40 byte this time (again as suggested by Neil & VisualMelon) :)

f(char*s){for(;*s;s+=50-*s)putchar(*s);}

and then 35 bytes thanks to Khaled.K

f(char*s){*s&&f(s+50-putchar(*s));}

Try it online!

\$\endgroup\$
6
  • 1
    \$\begingroup\$ Would s+=2-*s%2 work? \$\endgroup\$
    – Neil
    May 3, 2017 at 9:40
  • 1
    \$\begingroup\$ If I've counted correctly I think for(;*s;s+=2-*s%2)putchar(*s); saves another byte. \$\endgroup\$
    – Neil
    May 3, 2017 at 10:06
  • 1
    \$\begingroup\$ What would be wrong with s+=50-*s? Not done C for ages and don't want to embarrass myself by invoking undefined behaviour (coming from C# where there is none) \$\endgroup\$ May 3, 2017 at 13:55
  • 1
    \$\begingroup\$ Looking at the putchar docs, can you do f(char*s){for(;*s;s+=50-putchar(*s));} ? \$\endgroup\$ May 3, 2017 at 15:04
  • 3
    \$\begingroup\$ You can save 5 bytes by making it recursive f(char*s){*s&&f(s+50-putchar(*s));} \$\endgroup\$
    – Khaled.K
    May 3, 2017 at 16:19
7
\$\begingroup\$

sed, 8 bytes

s/00/0/g

Try it online!

\$\endgroup\$
2
6
\$\begingroup\$

Octave, 22 bytes

@(s)strrep(s,'00','0')

Verify all test cases here.

This is an anonymous function taking a string on the format '1001000011' as input, and replaces two consecutive zeros with a single zero.

\$\endgroup\$
6
\$\begingroup\$

Haskell, 28 bytes

f(h:t)=h:f(drop(1-h)t)
f e=e

Try it online!

Recursively takes the first element, dropping the second one if the first one is zero, until the list of empty. If the first entry is h, then the first 1-h are dropped from the remainder.

\$\endgroup\$
6
\$\begingroup\$

Java, 50 bytes

String f(String s){return s.replaceAll("00","0");}

Try Online

\$\endgroup\$
5
  • 1
    \$\begingroup\$ A very good input choice! By the way, if you're interested in switching to a Java 8+ solution, you could use a lambda: s->s.replaceAll("00","0"). \$\endgroup\$
    – Jakob
    Dec 12, 2017 at 6:05
  • 1
    \$\begingroup\$ Even better, use replace instead of replaceAll to save 3 bytes \$\endgroup\$ Apr 17, 2019 at 17:08
  • \$\begingroup\$ @BenjaminUrquhart replace will only replace the first occurrence \$\endgroup\$
    – Khaled.K
    Apr 21, 2019 at 8:49
  • 1
    \$\begingroup\$ @Khaled.K in javascript, yes. In java, it replaces all occurrences \$\endgroup\$ Apr 21, 2019 at 12:39
  • \$\begingroup\$ @BenjaminUrquhart is indeed correct, both replace and replaceAll replace all occurrences. The difference is that replaceAll supports regex. To replace the first occurrence there is the replaceFirst method (also supporting regex). I personally think Java's replace is the worst-named method there is in Java. Better would be if replace was called replaceAll and replaceAll was called replaceAllWithRegex or something along those lines.. :/ \$\endgroup\$ Jan 14 at 16:32
6
\$\begingroup\$

Japt, 7 6 5 bytes

d'0²0

Try it online!

Simply replaces each run of two zeroes in the input by one zero. Uses string input (i.e. "1001001").

\$\endgroup\$
3
  • 1
    \$\begingroup\$ Nice! You don't even need the ' I think \$\endgroup\$ May 3, 2017 at 11:22
  • \$\begingroup\$ Ooh, you can save another byte by replacing "00" with '0² :-) \$\endgroup\$ May 3, 2017 at 12:21
  • \$\begingroup\$ Well, that's weird. Thanks though! \$\endgroup\$
    – Luke
    May 3, 2017 at 13:14
5
\$\begingroup\$

Alice, 13 bytes

/oe00/
@iS0e\

Try it online!

Explanation

/.../
@...\

This is a simple template for linear programs which operate entirely in Ordinal mode. The initial / reflects the IP to move south east and then it bounces diagonally up and down through the code until the mirrors at the end. Those simply offset the position by one so that on the way back the IP traverses the remaining cells. Reading the code in this zigzag fashion it becomes:

ie00e0So@

This is a simple string substitution:

i   Read all input.
e   Push an empty string.
00  Append two zeros to create the string "00".
e   Push an empty string.
0   Append a zero to create the string "0".
S   Substitute all occurrences of "00" in the input with "0".
o   Output the result.   
@   Terminate the program.

There are a few other ways to push the two strings, e.g. '00'0 or e000t, but I haven't found anything that beats 5 bytes there (and I'd have to shave off two bytes to be able to shorten the program).

\$\endgroup\$
3
  • 2
    \$\begingroup\$ Looks like you fell in love with Alice recently... \$\endgroup\$
    – Leaky Nun
    May 3, 2017 at 7:55
  • 7
    \$\begingroup\$ @LeakyNun Please don't tell my wife... \$\endgroup\$ May 3, 2017 at 10:40
  • \$\begingroup\$ @MartinEnder I'm gonna tell that to Mrs. Ender! \$\endgroup\$ May 3, 2017 at 11:02
5
\$\begingroup\$

Jelly, 8 bytes

ṣ1j1,1m2

Try it online!

Possibly other answers in languages without a .replace() or similar could use this trick.

Explanation

ṣ1j1,1m2 - (duplicates the 1s, then halves all lengths)
ṣ1       - split by the element 1
  j1,1   - join the elements with the two-element list 1,1
      m2 - get every second element
\$\endgroup\$
5
\$\begingroup\$

V, 4 bytes

òf0x

Try it online!

ò    ' Recursively (until we error)
 f0  ' Go to the next zero (errors when there are no zeros left)
   x ' Delete it
\$\endgroup\$
5
\$\begingroup\$

sed, 8 6 bytes

n;/0/d

Try it online!

Takes a linefeed-separated string of 0 and 1.

n skips a line, and /0/d deletes a line if it has a zero in it. This has the net effect of deleting every 0 on an even-numbered line. Since any even-length contiguous list of 0 has the same number of even-numbered and odd-numbered lines, this has the effect of halving the length of every run of 0.

\$\endgroup\$
4
\$\begingroup\$

Prolog (SWI), 42 bytes

[0,0|T]*[0|R]:-T*R.
[H|T]*[H|R]:-T*R.
H*H.

Try it online!

\$\endgroup\$
2
  • 1
    \$\begingroup\$ A prolog answer, but not what I expected... \$\endgroup\$
    – Leaky Nun
    May 3, 2017 at 8:26
  • 1
    \$\begingroup\$ Nice trick to use the * operator. \$\endgroup\$
    – Leaky Nun
    May 3, 2017 at 8:28
4
\$\begingroup\$

PHP, 26

<?=strtr($argn,["00"=>0]);

simply replace all 00 by 0.

\$\endgroup\$
4
\$\begingroup\$

Lua, 33 bytes

print((io.read():gsub("00","0")))

Takes a string via input and condenses double zeros. Easy.

\$\endgroup\$
4
\$\begingroup\$

Perl 5, 7+1(-p flag)=8 bytes

<>if/0/

Takes input as newline separated numbers. Skips the next line if it sees a zero.

\$\endgroup\$
4
\$\begingroup\$

Alice, 12 10 bytes

2 bytes saved thanks to Martin Ender

i.h%.7%$io

Try it online!

Explanation

This is a 1-D code operating in cardinal mode, so it's easy to follow its flow:

i                   Read a byte from input (pushes -1 on EOF)
 .h                 Duplicate it and add 1 to the copy
   %                Compute n%(n+1). This will exit with an error on n==-1
                    and return n for any non-negative n.
    .7%             Duplicate the input again and compute its value modulo 7
                    This returns 6 for '0' (unicode value 48) and 0 for '1'
                    (unicode value 49)
       $i           If this last result was not 0, input another number.
                    This ignores every other '0' in the input
                    and moves to the following number (another '0')
         o          Output the last byte read

                    At the end, wrap back to the beginning of the line
\$\endgroup\$
2
  • \$\begingroup\$ You can actually save two more bytes with i.h%... \$\endgroup\$ May 4, 2017 at 20:25
  • \$\begingroup\$ @MartinEnder you're an evil person, going around teaching people to play dirty... :D \$\endgroup\$
    – Leo
    May 5, 2017 at 10:09
4
\$\begingroup\$

Jelly, 4 bytes

¹‘ƭƇ

Try it online!

Explanation

¹‘ƭƇ   Main monadic link
   Ƈ   Filter by
  ƭ      Every time this is called, switch between
¹          doing nothing and
 ‘         adding 1
\$\endgroup\$
4
\$\begingroup\$

Husk, 4 bytes

fG=¹

Try it online!

How?
The Husk scanl command (G) applies a function to each element of a list and the result-so-far. The initial result-so-far is set to the first element.

In this case, used with the eq (=) function, it checks whether each element is equal to the result-so-far. For runs of 1, this will always output 1 (truthy). Now, the first of any run of 0s will be 0 (falsy), of course; then, the next result will be 1 (since 0 is equal to the result-so-far), and then 0, and so on, alternating 0s at odd positions in the run and 1s at even positions, until the end of the run. Since there are always an even number of 0s in each run, then last result-so-far must be 1: so, when we enter the next run of 1s, the first result will be 1 (truthy) again, and so on...

So: runs of 0s get alternating 0 and 1, and runs of 1s always get 1, and we just need to filter (f) the input list (¹) by this.

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

Java, 131 123 bytes

int[]f(int[]a){int c=0,i=0,l=a.length;for(int x:a)c+=1-x;int[]r=new int[l-c/2];for(c=0;c<l;c+=2-a[c])r[i++]=a[c];return r;}

Try it online!

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

JavaScript (ES6), 26 21 bytes

Takes the input as a string and returns a string.

s=>s.replace(/00/g,0)

Try It

f=
s=>s.replace(/00/g,0)
i.addEventListener("input",_=>o.innerText=f(i.value))
console.log(f("1001001")) // "10101"
console.log(f("110011001")) // "1101101"
console.log(f("11001110011")) // "110111011"
console.log(f("111")) // "111"
console.log(f("001")) // "01"
console.log(f("00")) // "0"
console.log(f("11100001111001001100111100100")) // "1110011110101101111010"
<input id=i><pre id=o>

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

Mathematica, 24 bytes

StringReplace["00"->"0"]

A function that expects a string of "0"s and "1"s and returns a similar string. Self-explanatory syntax. Mathematica has lots of transformation builtins; the key is to use one that transforms every relevant subexpression (unlike /.) but only passes through the expression once (unlike //.).

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

MATL, 5 bytes

FFOZt

Try it online!

Explanation

This is similar to Stewie Griffin's Octave answer:

FF     % Push [0 0]
O      % Push 0
Zt     % Implicitly take input. Replace [0 0] by 0. Implicitly display

8 bytes

vy~f2L)(

This avoids the string/array replacement builtin.

Try it online!

Explanation

Consider input [1,0,0,1,0,0,1] as an example:

v      % Concatenate stack (which is empty): pushes []
       % STACK: []
y      % Implicit input. Duplicate from below
       % STACK: [1,0,0,1,0,0,1], [], [1,0,0,1,0,0,1]
~f     % Negate, find: gives indices of zeros
       % STACK: [1,0,0,1,0,0,1], [], [2,3,5,6]
2L     % Push [2,2,1i]. As an index, this is interpreted as 2:2:end
       % STACK: [1,0,0,1,0,0,1], [], [2,3,5,6], [2,2,1i]
)      % Reference indexing. This selects the even-indexed entries
       % STACK: [1,0,0,1,0,0,1], [], [3,6]
(      % Assignment indexing. This deletes the specified entries
       % (assigns them the empty array). Implicitly display
       % STACK: [1,0,1,0,1]
\$\endgroup\$
3
\$\begingroup\$

Pip, 5 bytes

aR00i

Takes a string of 0s and 1s. Try it online!

Explanation

Beating Jelly? Inconceivable!

a      Take the first command-line argument
 R     and replace
  00   00 (an integer literal, so it doesn't need quotes)
    i  with i (variable preinitialized to 0)
       Autoprint
\$\endgroup\$
1
  • \$\begingroup\$ Not beating Jelly anymore ;) \$\endgroup\$
    – xigoi
    Feb 15, 2021 at 22:38
3
\$\begingroup\$

R, 21 bytes

function(n)n[n+1:0>0]

Try it online!

\$\endgroup\$
1
  • \$\begingroup\$ Ah, this better leverages the fact that runs of zero are even length! Very nice. \$\endgroup\$
    – Giuseppe
    Jan 14 at 13:25
2
\$\begingroup\$

Brachylog, 10 bytes

ḅ{cẹ|ḍh}ᵐc

Try it online!

Not sure this is optimal yet…

Explanation

This exploits the bug that c on a list of integers that has leading zeroes will fail.

ḅ               Blocks; group consecutive equal elements together
 {     }ᵐ       Map on each block:
  c               It is possible to concatenate the block into an int (i.e. it contains 1s)
   ẹ              Split it again into a list of 1s
    |             Else
     ḍh           Dichotomize and take the head
         c      Concatenate the blocks into a single list
\$\endgroup\$
3
  • \$\begingroup\$ How is that a bug? \$\endgroup\$
    – Leaky Nun
    May 3, 2017 at 7:44
  • 1
    \$\begingroup\$ @LeakyNun We should be able to concatenate [0,0,4,2] into 42. Leading zeroes make it fail right now because it's here to prevent infinite leading zeroes when the Input is a variable, but here the Input is fully grounded so that limitation shouldn't exist. \$\endgroup\$
    – Fatalize
    May 3, 2017 at 7:46
  • \$\begingroup\$ Would you write a Prolog answer? \$\endgroup\$
    – Leaky Nun
    May 3, 2017 at 7:50
2
\$\begingroup\$

Python (list I/O), 36 bytes

f=lambda l:l and l[:1]+f(l[2-l[0]:])

Try it online!

Recursively takes the first element, then removes the remaining one if the first one was zero.


38 bytes:

lambda l:eval(`l`.replace('0, 0','0'))

Try it online This takes a Python list and outputs a Python list by doing replacement on its string representation. String I/O would allow a more direct and shorter solution, such as

lambda s:s.replace('00','0')

for '1001' format.

\$\endgroup\$
2
  • \$\begingroup\$ The first answer with format specified, nice. \$\endgroup\$
    – Leaky Nun
    May 3, 2017 at 7:59
  • 1
    \$\begingroup\$ String I/O is allowed. lambda s:s.replace('00','0') should be fine. \$\endgroup\$ May 3, 2017 at 10:49
2
\$\begingroup\$

///, 11 bytes

/00/a//a/0/<input goes here>

Try it online!

Fun fact: /00/0/<input> won't work, because it reduces 0000 to 0. Hence the a-substitute.

\$\endgroup\$
2
\$\begingroup\$

APL (Dyalog), 9 bytes

'00'⎕R'0'

Try it online!

\$\endgroup\$
1
  • \$\begingroup\$ It says DOMAIN ERROR: I-Beam function 7160 has been withdrawn \$\endgroup\$
    – Razetime
    Aug 14, 2020 at 14:50

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.