34
\$\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

68 Answers 68

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
2
\$\begingroup\$

Batch, 24 bytes

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

Takes input on STDIN. Somewhat competitive for once.

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

Ruby, 41 40 bytes

->a{a.each_index{|i|a[i]>0||a[i..i]=[]}}
\$\endgroup\$
2
\$\begingroup\$

BitCycle, 18 17 15 bytes

Saved 2 bytes via a clever rearrangement by Jo King

?ABv
  +\!
 ^\<

Try it online!

Algorithm

Take two bits of the input at a time. Output the first one. Discard the second one if it is 0 and output it if it is 1.

Because we are guaranteed that all runs of 0s have even length, this approach will always discard half of the 0s from each run:

00 -> 0x
10 01 -> 1x 01
10 0  -> 1x 0

Implementation

The input bitstring comes in at the source ? and is directed into the A collector, which in turn dumps its output into the B collector. Each time the B collector opens, the bits are directed through the two splitters \, which split off the first and second bits. The first bit goes east, straight into the sink ! to be output. The second bit passes through the now-deactivated first splitter, hits the second splitter, and goes north into the +, which sends a 0 bit left (west) and off the playfield, but sends a 1 bit right (east) into the sink ! to be output.

Meanwhile, the rest of the bits pass through both splitters and back into the A collector. Once they are all there, A opens and the cycle starts over. This loop continues until all bits are disposed of.

\$\endgroup\$
1
  • 1
    \$\begingroup\$ @JoKing And here I thought I had it as tight as possible! How are you so good at this language? :^D \$\endgroup\$
    – DLosc
    Aug 14, 2020 at 4:37
2
\$\begingroup\$

Husk, 8 7 bytes

ṁ?IĊ2←g

Try it online!

might be shorter with strings.

-1 byte from Zgarb.

Explanation

ṁ?Io←½←g
       g group equal runs of elements
ṁ        map each group to function, and concatenate
 ?    ←  if first element is truthy
  I      leave as is
   o←½   else remove the second half
\$\endgroup\$
2
  • \$\begingroup\$ You can use Ċ2 to remove every second element. \$\endgroup\$
    – Zgarb
    Oct 5, 2020 at 6:45
  • \$\begingroup\$ @JoKing updated \$\endgroup\$
    – Razetime
    Oct 5, 2020 at 7:32
2
\$\begingroup\$

Factor, 18 bytes

[ "00""0"replace ]

Try it online!

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

R, 29 bytes

function(n)n[n|cumsum(!n)%%2]

Try it online!

Input as list of 0 and 1 or T/F

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

Excel, 24 22 bytes

Saved 2 bytes thanks to Taylor Raine seeing what should have been obvious.

=SUBSTITUTE(A1,"00",0)

Inputs is a contiguous string of 0 and 1 in cell A1. Output is wherever the formula is.

Straightforward use of a built-in.


If the output has to be an array even though the input isn't, the formula grows to 55 bytes.

=LET(a,SUBSTITUTE(A1,"00",0),MID(a,SEQUENCE(LEN(a)),1))

If the output has to be an array but it can have trailing empty space, it's 47 bytes.

=MID(SUBSTITUTE(A1,"00",0),SEQUENCE(LEN(A1)),1)
\$\endgroup\$
1
  • \$\begingroup\$ Drop the "s around the third argument for -2 bytes \$\endgroup\$ Jan 19, 2022 at 5:24
2
\$\begingroup\$

Vyxal, 6 5 bytes

\0d0V

Try it Online!

-1 thx to @Steffan

\$\endgroup\$
1
  • \$\begingroup\$ `00` => ‛00 (or \0d) \$\endgroup\$
    – naffetS
    Oct 13, 2022 at 2:31
2
\$\begingroup\$

Thunno 2, 5 bytes

`000v

Attempt This Online!

Explanation

`000v  # Implicit input
`00    # Push "00"
   0   # Push 0
    v  # Replace "00" with "0"
       # Implicit output
\$\endgroup\$
2
\$\begingroup\$

Nekomata, 4 bytes

ĭZĬ‼

Attempt This Online!

ĭZĬ‼        Take [1,0,0,1,0,0,1] as an example
ĭ       Uninterleave
            [1,0,0,1,0,0,1] -> [1,0,0,1] [0,1,0]
 Z      Check non-zero
            [0,1,0] -> [Failure,1,Failure]
  Ĭ     Interleave
            [1,0,0,1] [Failure,1,Failure] -> [1,Failure,0,1,0,Failure,1]
   ‼    Remove failures
            [1,Failure,0,1,0,Failure,1] -> [1,0,1,0,1]

The idea is to remove all zeros at odd positions (0-based).

The code makes use of the fact that Nekomata is lazy: Z will not fail immediately when it sees a zero, but only replace it with a "failure", that is, a nondeterministic object that has no value. Lists that contain failures can be used in most operations just like normal lists, and will only fail when they are printed as the final result. So we can safely interleave it with the original even-indexed part, and then remove all failures.

\$\endgroup\$
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\$
4
  • \$\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\$
    – Mayube
    May 3, 2017 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, 2017 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\$
    – Mayube
    May 3, 2017 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\$ May 3, 2017 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\$

Python 2, 84 68 bytes

Not nearly as short as xnor's answer, but that's okay. I wanted to use del.

L=input()
i=0
while i<len(L):
 if L[i]<1:del L[i]
 i+=2-L[i]
print L

Try it online

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

Perl 5 8 + 1 (for -p flag) = 9 bytes

s/00/0/g

I made another answer because I liked my first one too much :)

\$\endgroup\$
2
  • \$\begingroup\$ I count 8 Bytes (+1 for the fag = 9) \$\endgroup\$
    – Kevin
    May 3, 2017 at 17:19
  • \$\begingroup\$ @Kevin You're right. Must have miscounted. Thanks \$\endgroup\$
    – CraigR8806
    May 3, 2017 at 17:20
1
\$\begingroup\$

Pyth, 12 bytes

s.e?sbb*%k2b

Try this

Takes a quoted string.

I know there's a shorter Pyth answer already, but I thought someone might find this approach interesting/useful.

Explanation

s.e?sbb*%k2b
 .e         Q  # enumerated map on the implicit input string. b=element; k = position
   ?sb         # Is that character nonzero? (Done by converting char to int.)
      b        # If yes, just return that character
        %k2    # Mod 2 of the position: 0 if even 1 if odd
       *   b   # Take b that many times: "" if even, "0" if odd
s              # Concat everything.

So every even "0" gets replaced by "".

Similar, 13 bytes (12 bytes if it weren't for Pyth's unfortunate naming of map variables):

s.e?+%k2sbb""

Try that

\$\endgroup\$
1
  • \$\begingroup\$ The other takes in string so it isn't interesting, and this one can potentially take in a list... \$\endgroup\$
    – Leaky Nun
    May 3, 2017 at 17:33
1
\$\begingroup\$

Swift - 65 bytes

func g(a:String){print(a.replacingOccurrences(of:"00",with:"0"))}

Usage: g(a:"100100"), obviously the I/O method is through strings.

\$\endgroup\$
1
  • \$\begingroup\$ You can save a bunch of bytes using a closure: {$0.replacingOccurrences(of:"00",with:"0")}. Swift 5.7 added a bunch of string processing utilities and maybe one of those is shorter yet, but I recognize they didn't exist when you wrote this. \$\endgroup\$
    – Bbrk24
    Jun 15, 2023 at 18:59
1
\$\begingroup\$

CJam, 20 18 bytes

1l~]e`2/z~2ff/]z:~

Expects input as a list of bits, separated by spaces.

Explanation:

1   e# Push 1:              | 1
l   e# Read line:           | 1 "1 1 0 0 1 1 1 0 0 1 1"
~   e# Evaluate:            | 1 1 1 0 0 1 1 1 0 0 1 1
]   e# Wrap stack in array: | [1 1 0 0 1 1 1 0 0 1 1]
e`  e# Run-length encode:   | [[3 1] [2 0] [3 1] [2 0] [2 1]]
2/  e# Group by 2:          | [[[3 1] [2 0]] [[3 1] [2 0]] [[2 1]]]
z   e# Transpose:           | [[[3 1] [3 1] [2 1]] [[2 0] [2 0]]]
~   e# Unpack array:        | [[3 1] [3 1] [2 1]] [[2 0] [2 0]]
2ff/ e# Divide each by 2:   | [[[3 1] [3 1] [2 1]] [[1 0] [1 0]]]
]   e# Wrap stack in array: | [[[[3 1] [3 1] [2 1]] [[1 0] [1 0]]]]
z   e# Transpose:           | [[[3 1] [1 0]] [[3 1] [1 0]] [[2 1]]]
:~  e# Unpack each:         | [[3 1] [1 0] [3 1] [1 0] [2 1]]
e~  e# RLE decode:          | [1 1 1 0 1 1 1 0 1 1]
(;  e# Delete last element: | [1 1 0 1 1 1 0 1 1]
e# Implicit output: "110111011"

Alternative (9 bytes):

l~[0_]/0*

Expects input as a CJam list literal.

Explanation:

l~   e# Read line and eval: | [1 1 0 0 1 1 1 0 0 1 1]
[0_] e# Push [0 0]:         | [1 1 0 0 1 1 1 0 0 1 1] [0 0]
/    e# Split array:        | [[1 1] [1 1 1] [1 1]]
0*   e# Join with 0:        | [1 1 0 1 1 1 0 1 1]
\$\endgroup\$
1
\$\begingroup\$

ES7, 23 bytes

_=>_.replace(/00/g,`0`)

Input is string without whitespace + it allows odd lengths of runs of 0, it just keeps it as is.

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

Zsh, 13 bytes

<<<${1//00/0}

Try it online!

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

x86-16 machine code, 15 bytes

00000000: b401 aca8 0175 04f6 dc78 01aa e2f4 c3    .....u...x.....

Listing:

B4 01       MOV  AH, 1          ; set zero run counter flag set to positive 
        CLOOP: 
AC          LODSB               ; load next byte 
A8 01       TEST AL, 1          ; is a 1 or 0? 
75 04       JNZ  IS_ONE         ; if 1, store to output and loop 
F6 DC       NEG  AH             ; flip sign of zero run counter flag 
78 01       JS   ODD_ZERO       ; if negative, don't output 
        IS_ONE: 
AA          STOSB               ; copy char to output 
        ODD_ZERO: 
E2 F4       LOOP CLOOP          ; loop until end of input 
C3          RET                 ; return to caller

Callable function, input array at [SI], len in CX. Output to array at [DI].

Test program output:

enter image description here

Try it online!

\$\endgroup\$
1
  • \$\begingroup\$ 11 \$\endgroup\$
    – l4m2
    Oct 15, 2023 at 3:51
1
\$\begingroup\$

Brainfuck, 51 bytes

+[,[>+>+<<-]>>[.>+++++++[<------->-]<[,>]]<[<+>-]<]

Try It Online!

This program takes a string of 0's and 1's as input and prints a string of 0's and 1's as output.

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

Husk, 6 bytes

σD;0;0

Try it online!

Explanation

σD;0;0
σ       replace all                 with
 D                  2 copies of
  ;0                            [0]
    ;0                                   [0]
\$\endgroup\$
1
1
\$\begingroup\$

Pari/GP, 21 bytes

a->[i|i<-q=a,i||q=!q]

Try it online!

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

APOL, 33 bytes

j(ƒ(i ¿(!(I(∋)) ¿(≐(∈) 0 '') 1)))

Explanation:

j(            Join list to string
  ƒ(          List-builder for
    i         Get input
    ¿(        Returning if
      !(      Not
        I(    As number
          ∋   Loop item
        )
      )
              If true return
      ¿(      Returning if
        ≐(∈)  Loop counter is even
        0     If true return 0
        ''    Else return an empty string
      )
      1       Else return 1
    )
  )
)
\$\endgroup\$
1
\$\begingroup\$

convey, 32 bytes

{">>>v
 "+."@}
1#,0=]
^>@<<
^<$1

Try it online!

How it works with input [1,0,0,0,0,1]:

enter image description here

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

Lexurgy, 10 bytes

Input is a string of as and bs, where a is 1 and b is 0.

Finds two bs and replaces them with a b and an empty string.

a:
b b=>b *

Variant that does the same thing with actual 0 and 1 digits (12 bytes):

a:
\0\0=>\0 *
\$\endgroup\$

Your Answer

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

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