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
0and1 - Contiguous string of
0and1 - Any other reasonable format
For example, the following three inputs are all acceptable:
[1, 0, 0, 1]"1\n0\n0\n1"(where\nis 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 code-golf. Shortest answer in bytes wins.
Standard loopholes apply.
68 Answers 68
-
\$\begingroup\$ This one will be hard to beat. \$\endgroup\$Adám– Adám2017年05月03日 10:15:13 +00:00Commented May 3, 2017 at 10:15
-
\$\begingroup\$ @Adám I'd say impossible to beat. \$\endgroup\$Erik the Outgolfer– Erik the Outgolfer2017年05月03日 11:13:15 +00:00Commented May 3, 2017 at 11:13
-
1
-
2\$\begingroup\$ That was easy; why didn't I think of that? \$\endgroup\$Leaky Nun– Leaky Nun2017年05月03日 07:09:27 +00:00Commented May 3, 2017 at 7:09
-
\$\begingroup\$
00is weird behavior... \$\endgroup\$Erik the Outgolfer– Erik the Outgolfer2017年05月03日 10:45:28 +00:00Commented May 3, 2017 at 10:45 -
1\$\begingroup\$ @EriktheOutgolfer: Sequential digits are concatenated to form a number, so
11is eleven and not1,1. A side effect of that is that00becomes00instead of0,0:) \$\endgroup\$Emigna– Emigna2017年05月03日 10:48:27 +00:00Commented May 3, 2017 at 10:48 -
\$\begingroup\$ @Emigna I'd have expected it to become
0or0 0instead, but whatever. \$\endgroup\$Erik the Outgolfer– Erik the Outgolfer2017年05月03日 10:56:43 +00:00Commented May 3, 2017 at 10:56 -
\$\begingroup\$
¤can also beN\$\endgroup\$Makonede– Makonede2023年06月16日 00:46:32 +00:00Commented Jun 16, 2023 at 0:46
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.
-
\$\begingroup\$ I feel that this can be forked to Prolog \$\endgroup\$Leaky Nun– Leaky Nun2017年05月03日 07:20:51 +00:00Commented May 3, 2017 at 7:20
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));}
-
1\$\begingroup\$ Would
s+=2-*s%2work? \$\endgroup\$Neil– Neil2017年05月03日 09:40:32 +00:00Commented 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– Neil2017年05月03日 10:06:10 +00:00Commented 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\$VisualMelon– VisualMelon2017年05月03日 13:55:50 +00:00Commented May 3, 2017 at 13:55 -
1\$\begingroup\$ Looking at the
putchardocs, can you dof(char*s){for(;*s;s+=50-putchar(*s));}? \$\endgroup\$VisualMelon– VisualMelon2017年05月03日 15:04:16 +00:00Commented 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– Khaled.K2017年05月03日 16:19:36 +00:00Commented May 3, 2017 at 16:19
-
3\$\begingroup\$ @boboquack Doesn't work, since it would always replace a run of
0s with0. \$\endgroup\$Erik the Outgolfer– Erik the Outgolfer2017年05月03日 11:02:47 +00:00Commented May 3, 2017 at 11:02 -
\$\begingroup\$ @EriktheOutgolfer No, it does just halve the length of runs of
0's: tio.run/##K05N@f@/WN/AQN9AP/3/fwMwAAA \$\endgroup\$steenbergh– steenbergh2022年01月17日 15:15:58 +00:00Commented Jan 17, 2022 at 15:15
Octave, 22 bytes
@(s)strrep(s,'00','0')
This is an anonymous function taking a string on the format '1001000011' as input, and replaces two consecutive zeros with a single zero.
Haskell, 28 bytes
f(h:t)=h:f(drop(1-h)t)
f e=e
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.
-
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– Jakob2017年12月12日 06:05:48 +00:00Commented Dec 12, 2017 at 6:05 -
1\$\begingroup\$ Even better, use
replaceinstead ofreplaceAllto save 3 bytes \$\endgroup\$Benjamin Urquhart– Benjamin Urquhart2019年04月17日 17:08:43 +00:00Commented Apr 17, 2019 at 17:08 -
\$\begingroup\$ @BenjaminUrquhart
replacewill only replace the first occurrence \$\endgroup\$Khaled.K– Khaled.K2019年04月21日 08:49:55 +00:00Commented Apr 21, 2019 at 8:49 -
1\$\begingroup\$ @Khaled.K in javascript, yes. In java, it replaces all occurrences \$\endgroup\$Benjamin Urquhart– Benjamin Urquhart2019年04月21日 12:39:35 +00:00Commented Apr 21, 2019 at 12:39
-
\$\begingroup\$ @BenjaminUrquhart is indeed correct, both
replaceandreplaceAllreplace all occurrences. The difference is thatreplaceAllsupports regex. To replace the first occurrence there is thereplaceFirstmethod (also supporting regex). I personally think Java'sreplaceis the worst-named method there is in Java. Better would be ifreplacewas calledreplaceAllandreplaceAllwas calledreplaceAllWithRegexor something along those lines.. :/ \$\endgroup\$Kevin Cruijssen– Kevin Cruijssen2022年01月14日 16:32:07 +00:00Commented Jan 14, 2022 at 16:32
Japt, (削除) 7 6 (削除ここまで) 5 bytes
d'020
Simply replaces each run of two zeroes in the input by one zero. Uses string input (i.e. "1001001").
-
1\$\begingroup\$ Nice! You don't even need the
'I think \$\endgroup\$ETHproductions– ETHproductions2017年05月03日 11:22:23 +00:00Commented May 3, 2017 at 11:22 -
\$\begingroup\$ Ooh, you can save another byte by replacing
"00"with'0²:-) \$\endgroup\$ETHproductions– ETHproductions2017年05月03日 12:21:47 +00:00Commented May 3, 2017 at 12:21 -
\$\begingroup\$ Well, that's weird. Thanks though! \$\endgroup\$Luke– Luke2017年05月03日 13:14:38 +00:00Commented May 3, 2017 at 13:14
Husk, 4 bytes
fG=1
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 (1) by this.
Alice, 13 bytes
/oe00/
@iS0e\
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).
-
2\$\begingroup\$ Looks like you fell in love with Alice recently... \$\endgroup\$Leaky Nun– Leaky Nun2017年05月03日 07:55:05 +00:00Commented May 3, 2017 at 7:55
-
7\$\begingroup\$ @LeakyNun Please don't tell my wife... \$\endgroup\$Martin Ender– Martin Ender2017年05月03日 10:40:30 +00:00Commented May 3, 2017 at 10:40
-
\$\begingroup\$ @MartinEnder I'm gonna tell that to Mrs. Ender! \$\endgroup\$Erik the Outgolfer– Erik the Outgolfer2017年05月03日 11:02:56 +00:00Commented May 3, 2017 at 11:02
Jelly, 8 bytes
ṣ1j1,1m2
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
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.
V, 4 bytes
òf0x
ò ' Recursively (until we error)
f0 ' Go to the next zero (errors when there are no zeros left)
x ' Delete it
sed, (削除) 8 (削除ここまで) 6 bytes
n;/0/d
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.
-
1\$\begingroup\$ A prolog answer, but not what I expected... \$\endgroup\$Leaky Nun– Leaky Nun2017年05月03日 08:26:23 +00:00Commented May 3, 2017 at 8:26
-
1\$\begingroup\$ Nice trick to use the
*operator. \$\endgroup\$Leaky Nun– Leaky Nun2017年05月03日 08:28:10 +00:00Commented May 3, 2017 at 8:28
PHP, 26
<?=strtr($argn,["00"=>0]);
simply replace all 00 by 0.
Lua, 33 bytes
print((io.read():gsub("00","0")))
Takes a string via input and condenses double zeros. Easy.
MATL, 5 bytes
FFOZt
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.
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]
Alice, (削除) 12 (削除ここまで) 10 bytes
2 bytes saved thanks to Martin Ender
i.h%.7%$io
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
-
\$\begingroup\$ You can actually save two more bytes with
i.h%...\$\endgroup\$Martin Ender– Martin Ender2017年05月04日 20:25:02 +00:00Commented May 4, 2017 at 20:25 -
\$\begingroup\$ @MartinEnder you're an evil person, going around teaching people to play dirty... :D \$\endgroup\$Leo– Leo2017年05月05日 10:09:58 +00:00Commented May 5, 2017 at 10:09
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>
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 //.).
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
-
\$\begingroup\$ Not beating Jelly anymore ;) \$\endgroup\$Adamátor– Adamátor2021年02月15日 22:38:56 +00:00Commented Feb 15, 2021 at 22:38
-
\$\begingroup\$ Ah, this better leverages the fact that runs of zero are even length! Very nice. \$\endgroup\$Giuseppe– Giuseppe2022年01月14日 13:25:44 +00:00Commented Jan 14, 2022 at 13:25
Vyxal, 4 bytes
ɖ=Tİ
Try it Online! Port of Dominic van Essen's Husk answer. See that for a more detailed explanation of how this works.
ɖ # Scan by
= # Equal to the current result?
# For runs of 1s, this is 1,
# For runs of 0s this alternates between 1 and 0
Tİ # Keep only items wihtt a 1 in the previous list
Brachylog, 10 bytes
ḅ{cẹ|ḍh}mc
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
{ }m 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
-
\$\begingroup\$ How is that a bug? \$\endgroup\$Leaky Nun– Leaky Nun2017年05月03日 07:44:30 +00:00Commented May 3, 2017 at 7:44
-
1\$\begingroup\$ @LeakyNun We should be able to concatenate
[0,0,4,2]into42. 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– Fatalize2017年05月03日 07:46:46 +00:00Commented May 3, 2017 at 7:46 -
\$\begingroup\$ Would you write a Prolog answer? \$\endgroup\$Leaky Nun– Leaky Nun2017年05月03日 07:50:07 +00:00Commented May 3, 2017 at 7:50
Python (list I/O), 36 bytes
f=lambda l:l and l[:1]+f(l[2-l[0]:])
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.
-
\$\begingroup\$ The first answer with format specified, nice. \$\endgroup\$Leaky Nun– Leaky Nun2017年05月03日 07:59:06 +00:00Commented May 3, 2017 at 7:59
-
1\$\begingroup\$ String I/O is allowed.
lambda s:s.replace('00','0')should be fine. \$\endgroup\$Jonathan Allan– Jonathan Allan2017年05月03日 10:49:45 +00:00Commented May 3, 2017 at 10:49
///, 11 bytes
/00/a//a/0/<input goes here>
Fun fact: /00/0/<input> won't work, because it reduces 0000 to 0. Hence the a-substitute.
trueandfalseinstead of1and0? \$\endgroup\$0to be truthy. \$\endgroup\$