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

40 Answers 40

27
\$\begingroup\$

Retina, 4 bytes

00
0

Try it online!

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

05AB1E, 5 bytes

00¤.:

Try it online!

Explanation

00     # push 00
  ¤    # tail, pushes 0
   .:  # replace
\$\endgroup\$
  • 2
    \$\begingroup\$ That was easy; why didn't I think of that? \$\endgroup\$ – Leaky Nun May 3 '17 at 7:09
  • \$\begingroup\$ 00 is weird behavior... \$\endgroup\$ – Erik the Outgolfer May 3 '17 at 10:45
  • \$\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 '17 at 10:48
  • \$\begingroup\$ @Emigna I'd have expected it to become 0 or 0 0 instead, but whatever. \$\endgroup\$ – Erik the Outgolfer May 3 '17 at 10:56
7
\$\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\$
  • \$\begingroup\$ I feel that this can be forked to Prolog \$\endgroup\$ – Leaky Nun May 3 '17 at 7:20
7
\$\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\$
  • 1
    \$\begingroup\$ Would s+=2-*s%2 work? \$\endgroup\$ – Neil May 3 '17 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 '17 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\$ – VisualMelon May 3 '17 at 13:55
  • 1
    \$\begingroup\$ Looking at the putchar docs, can you do f(char*s){for(;*s;s+=50-putchar(*s));} ? \$\endgroup\$ – VisualMelon May 3 '17 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 '17 at 16:19
6
\$\begingroup\$

sed, 8 bytes

s/00/0/g

Try it online!

\$\endgroup\$
  • 2
    \$\begingroup\$ @boboquack Doesn't work, since it would always replace a run of 0s with 0. \$\endgroup\$ – Erik the Outgolfer May 3 '17 at 11:02
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\$

Java, 50 bytes

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

Try Online

\$\endgroup\$
  • 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 '17 at 6:05
  • \$\begingroup\$ Even better, use replace instead of replaceAll to save 3 bytes \$\endgroup\$ – Benjamin Urquhart Apr 17 at 17:08
  • \$\begingroup\$ @BenjaminUrquhart replace will only replace the first occurrence \$\endgroup\$ – Khaled.K Apr 21 at 8:49
  • \$\begingroup\$ @Khaled.K in javascript, yes. In java, it replaces all occurrences \$\endgroup\$ – Benjamin Urquhart Apr 21 at 12:39
5
\$\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\$
5
\$\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\$
  • 1
    \$\begingroup\$ Nice! You don't even need the ' I think \$\endgroup\$ – ETHproductions May 3 '17 at 11:22
  • \$\begingroup\$ Ooh, you can save another byte by replacing "00" with '0² :-) \$\endgroup\$ – ETHproductions May 3 '17 at 12:21
  • \$\begingroup\$ Well, that's weird. Thanks though! \$\endgroup\$ – Luke May 3 '17 at 13:14
4
\$\begingroup\$

PHP, 26

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

simply replace all 00 by 0.

\$\endgroup\$
4
\$\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\$
  • 2
    \$\begingroup\$ Looks like you fell in love with Alice recently... \$\endgroup\$ – Leaky Nun May 3 '17 at 7:55
  • 6
    \$\begingroup\$ @LeakyNun Please don't tell my wife... \$\endgroup\$ – Martin Ender May 3 '17 at 10:40
  • \$\begingroup\$ @MartinEnder I'm gonna tell that to Mrs. Ender! \$\endgroup\$ – Erik the Outgolfer May 3 '17 at 11:02
3
\$\begingroup\$

Prolog (SWI), 42 bytes

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

Try it online!

\$\endgroup\$
  • \$\begingroup\$ A prolog answer, but not what I expected... \$\endgroup\$ – Leaky Nun May 3 '17 at 8:26
  • \$\begingroup\$ Nice trick to use the * operator. \$\endgroup\$ – Leaky Nun May 3 '17 at 8:28
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\$

Lua, 33 bytes

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

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

\$\endgroup\$
3
\$\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\$
3
\$\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\$
  • \$\begingroup\$ You can actually save two more bytes with i.h%... \$\endgroup\$ – Martin Ender May 4 '17 at 20:25
  • \$\begingroup\$ @MartinEnder you're an evil person, going around teaching people to play dirty... :D \$\endgroup\$ – Leo May 5 '17 at 10:09
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\$
  • \$\begingroup\$ The first answer with format specified, nice. \$\endgroup\$ – Leaky Nun May 3 '17 at 7:59
  • 1
    \$\begingroup\$ String I/O is allowed. lambda s:s.replace('00','0') should be fine. \$\endgroup\$ – Jonathan Allan May 3 '17 at 10:49
2
\$\begingroup\$

APL (Dyalog), 9 bytes

'00'⎕R'0'

Try it online!

\$\endgroup\$
2
\$\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\$
2
\$\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\$
2
\$\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\$
1
\$\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\$
  • \$\begingroup\$ How is that a bug? \$\endgroup\$ – Leaky Nun May 3 '17 at 7:44
  • \$\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 '17 at 7:46
  • \$\begingroup\$ Would you write a Prolog answer? \$\endgroup\$ – Leaky Nun May 3 '17 at 7:50
1
\$\begingroup\$

C#, 191 bytes

string a(string s){var l=(s+'1').ToCharArray();s="";int b=0;for(int i=0;i<l.Length;i++){if(l[i]=='1'){if(b>0){s+=new string('0',b/2);b=0;}s+=l[i];}else b++;}return s.Substring(0,s.Length-1);}

Try it online!

It's neither clean nor short, but it works.

Takes input as a contiguous string of characters, outputs in the same format

Explanation:

string a(string s){                  //Define method a that takes input string s and returns a string
  var l=(s+'1').ToCharArray();       //Add a 1 to the end of s and split into char array l
  s="";                              //Empty s
  int b=0;                           //Initialize int b with value 0
  for(int i=0;i<l.Length;i++){       //Loop through l
    if(l[i]=='1'){                   //If current char is 1
      if(b>0){                       //If b is not 0
        s+=new string('0',b/2);      //Add half the amount of 0s we've counted to s
        b=0;                         //Reset b
      }                              //End if b is not 0
      s+=l[i];                       //Add current char to s
    }                                //End if current char is 1
    else b++;                        //If current char is not 1, increment b
  }                                  //End loop
  return s.Substring(0,s.Length-1);  //Return string minus last char
}                                    //End method

Note

Yes I am aware this could simply be done using s.Replace("00","0"), my aim was to avoid using the obvious solution. After all, the whole point of PPCG is to have fun, right? ;)

\$\endgroup\$
  • \$\begingroup\$ @Mr.Xcoder That's not true. This is about as golfed as you can get without using the language's built-in Replace I'm using C# so I'm under no delusions about getting the shortest possible code, especially with languages like Jelly around, so might as well have a little fun in the process. \$\endgroup\$ – Skidsdev May 3 '17 at 12:09
  • \$\begingroup\$ of course fun is important as well. I apologise for the comment above and I must admit I liked your answer myself (the technique you used). \$\endgroup\$ – Mr. Xcoder May 3 '17 at 12:15
  • \$\begingroup\$ @Mr.Xcoder no hard feelings, ultimately we're all here to have fun and flex our otherwise useless ability to compress code as much as possible ;) \$\endgroup\$ – Skidsdev May 3 '17 at 12:28
  • \$\begingroup\$ You can do a lot shorter than this without replace! string a(string s){var r="";for(int i=0;i<s.Length;i+=50-s[i])r+=s[i];return r;} (looks like this is basically the C answer) \$\endgroup\$ – VisualMelon May 3 '17 at 13:42
1
\$\begingroup\$

Pyth, 8 bytes

:z"00"\0

Try-it link.

Explanation:

:z"00"\0 Takes unquoted contiguous 1-line input.
 z       Initialized to unevaluated first input line (Q won't be any shorter)
  "00"   Matching regex pattern /00/g
      \0 Substitution string "0"
:        Regex find-and-replace
\$\endgroup\$
1
\$\begingroup\$

Awk - 18 bytes

First try doing anything with Awk so it might be possible to golf it more.

{gsub(00,0);print}

Usage: echo "1001001" | awk '{gsub(00,0);print}'

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

Batch, 24 bytes

@set/ps=
@echo %s:00=0%

Takes input on STDIN. Somewhat competitive for once.

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

Common Lisp, SBCL, 48 32 bytes

-16 bytes thanks to Julian Wolf

(format t"~{~[0~*~;1~]~}"(read))

input:

(1 0 0 0 0 1 1 1 0 0)

output:

1001110

Explanation

We read input list. List is used in format function. We loop through it outputting 1 if element is 1 and outputting 0 and skipping next element of list for 0.

\$\endgroup\$
  • \$\begingroup\$ Using ~[ rather than ~:[ lets you index with 0 and 1 directly, which should save you a bunch of bytes \$\endgroup\$ – Julian Wolf May 3 '17 at 16:07
  • \$\begingroup\$ @JulianWolf Thank you! \$\endgroup\$ – user65167 May 3 '17 at 16:14
1
\$\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\$
1
\$\begingroup\$

Jelly, 10 bytes

Œg¹m2$S?€F

Try it online!

Explanation

Œg¹m2$S?€F
Œg          - Group runs of equal elements
        €   - To each run...
      S?    - If sum is truthy,
  ¹         -   return the run as it is
   m2$      - Else return every second element of the run.
\$\endgroup\$

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.