The task is simple: consolidate an array of ints. Consolidating this array consists of the following:
- All instances of 0 need to be moved to the end of the array.
- There should be no 0s between the non-zero integers.
- All non-zero indices should retain their order.
Challenge
Consolidate an array in the least amount of bytes.
You are consolidating an array of random length with a size up to your language's max with random integers. Input may be any natural way for your language.
Examples
Input
0 5 8 8 3 5 1 6 8 4 0 3 7 5 6 4 4 7 5 6 7 4 4 9 1 0 5 7 9 3 0 2 2 4 3 0 4 8 7 3 1 4 7 5 1 2 1 8 7 8 7 7 2 6 3 1 2 8 5 1 4 2 0 5 0 6 0 3
Output
5 8 8 3 5 1 6 8 4 3 7 5 6 4 4 7 5 6 7 4 4 9 1 5 7 9 3 2 2 4 3 4 8 7 3 1 4 7 5 1 2 1 8 7 8 7 7 2 6 3 1 2 8 5 1 4 2 5 6 3 0 0 0 0 0 0 0 0
Input
-1 -7 -6 5 1 -5 -2 7 -3 -8 0 8 9 1 -8 -1 6 -4 1 -2 1 -7 5 4 -6 7 -3 9 8 3 -1 0 -5 -7 3 8 1 1 3 -3 -2 -2 0 -7 0 -4 8 6 -3 6 0 5 3 2 2 2 -2 -7 -3 9 -1 6 0 6 -7 9 4 -2 8 -8 -4 1 -8 4 3 7 3 5 1 0 3 3 7 -1 -5 1 -3 4 -7 0 3 2 -2 7 -3 0 0 2 -5 8 -3 -2 -7 -5 7 -3 -9 -7 5 8 -3 9 6 7 -2 4 7
Output
-1 -7 -6 5 1 -5 -2 7 -3 -8 8 9 1 -8 -1 6 -4 1 -2 1 -7 5 4 -6 7 -3 9 8 3 -1 -5 -7 3 8 1 1 3 -3 -2 -2 -7 -4 8 6 -3 6 5 3 2 2 2 -2 -7 -3 9 -1 6 6 -7 9 4 -2 8 -8 -4 1 -8 4 3 7 3 5 1 3 3 7 -1 -5 1 -3 4 -7 3 2 -2 7 -3 2 -5 8 -3 -2 -7 -5 7 -3 -9 -7 5 8 -3 9 6 7 -2 4 7 0 0 0 0 0 0 0 0 0 0
Example Code (Java)
public class Consolidate {
public static void main(String[] args) throws Exception {
int[] toConsolidate = new int[args.length];
for (int i=0; i<args.length; i++){
toConsolidate[i]=Integer.parseInt(args[i]);
}
for (int i=0; i<toConsolidate.length; i++) {
for (int k=0; k<toConsolidate.length-1; k++) {
if (toConsolidate[k] == 0){
toConsolidate[k] = toConsolidate[k+1];
toConsolidate[k+1] = 0;
}
}
}
for (int i:toConsolidate)
System.out.print(i+" ");
}
}
-
\$\begingroup\$ Any integer or single digits like the examples? \$\endgroup\$edc65– edc652016年02月02日 21:30:38 +00:00Commented Feb 2, 2016 at 21:30
-
\$\begingroup\$ @edc65 Any integer that your language supports. \$\endgroup\$Addison Crump– Addison Crump2016年02月02日 21:35:43 +00:00Commented Feb 2, 2016 at 21:35
-
1\$\begingroup\$ @A.L in fairness, it is fully ungolfed and a terrible algorithm. \$\endgroup\$Addison Crump– Addison Crump2016年02月03日 00:50:20 +00:00Commented Feb 3, 2016 at 0:50
-
8\$\begingroup\$ Isn't "There should be no 0s between the non-zero integers." redundant? \$\endgroup\$Martin Ender– Martin Ender2016年02月03日 09:48:18 +00:00Commented Feb 3, 2016 at 9:48
-
2\$\begingroup\$ @immibis Might not be the right language for this challenge. :P \$\endgroup\$Addison Crump– Addison Crump2016年02月04日 07:48:10 +00:00Commented Feb 4, 2016 at 7:48
67 Answers 67
-
\$\begingroup\$
Q
can be implicit at the end of any Pyth script (assuming it's outside of a lambda, which this is), making this 2 bytes. \$\endgroup\$hakr14– hakr142018年03月28日 02:33:27 +00:00Commented Mar 28, 2018 at 2:33 -
\$\begingroup\$ @hakr14 That feature didn't exist 2 years ago. \$\endgroup\$Dennis– Dennis2018年03月28日 16:26:56 +00:00Commented Mar 28, 2018 at 16:26
Jelly, 3 bytes
¬Ụị
Sorts the list by the logical NOT of its values. Try it online!
How it works
¬Ụị Main link. Input: A (list)
¬ Compute the logical NOT of each element of A.
Ụ Grade up; sort the resulting list's indices by their corresponding values.
ị Retrieve the elements of A at that indices.
-
2\$\begingroup\$ Oh hey, modern Jelly can do a 2-byte
¬Þ
, even! \$\endgroup\$lynn– lynn2016年09月13日 00:42:14 +00:00Commented Sep 13, 2016 at 0:42
Octave, 18 bytes
@(A)[A(~~A) A(~A)]
sort()
takes too many bytes. I'll just use logical indexing.
Examples on ideone.
-
\$\begingroup\$ Nicely done. +1. \$\endgroup\$rayryeng– rayryeng2016年03月07日 17:36:16 +00:00Commented Mar 7, 2016 at 17:36
-
\$\begingroup\$ Wow, works in Matlab too! I didn't know that such indexing is possible \$\endgroup\$brainkz– brainkz2016年09月13日 09:13:30 +00:00Commented Sep 13, 2016 at 9:13
R, (削除) 29 (削除ここまで) (削除) 23 (削除ここまで) 21 bytes
As noted by MarcoBreitig, we can shorten it to 21 bytes if we don't need to provide it as a function:
x=scan();x[order(!x)]
Previous versions:
function(x)x[order(!x)]
The function takes a vector as input and orders by the logical vector that results from negating the input.
Original answer:
function(x)c(x[x!=0],x[x==0])
The function takes a vector as input and the concatenates (c()
) the non-zero values and then the zero-values.
-
2\$\begingroup\$ x=scan();x[order(!x)] is only 21 bytes long. \$\endgroup\$Marco Breitig– Marco Breitig2016年02月03日 14:44:14 +00:00Commented Feb 3, 2016 at 14:44
-
\$\begingroup\$ @MarcoBreitig, that's right. I thought it should be a function (and initially, the requirement was a "full-fledged program"). Will update my answer \$\endgroup\$docendo discimus– docendo discimus2016年02月03日 15:13:20 +00:00Commented Feb 3, 2016 at 15:13
-
1\$\begingroup\$ I used the same method in my Java answer (if I'm reading this right). :D \$\endgroup\$Addison Crump– Addison Crump2016年02月02日 20:14:45 +00:00Commented Feb 2, 2016 at 20:14
Python, 32 bytes
lambda x:sorted(x,key=0..__eq__)
Takes argument as any iterable (list, tuple, etc.). Thanks to @xnor for teaching me a new trick!
-
\$\begingroup\$ It's a bit shorter to use
key=0..__eq__
(yes, two dots). \$\endgroup\$xnor– xnor2016年02月03日 08:28:44 +00:00Commented Feb 3, 2016 at 8:28 -
\$\begingroup\$ @xnor That's neat... How does it work? \$\endgroup\$user45941– user459412016年02月03日 08:36:18 +00:00Commented Feb 3, 2016 at 8:36
-
7\$\begingroup\$ Most Python objects have an equality method, so for example
"abc".__eq__("abc")==True
. It's what's called when you do"abc"==
. For reasons, Python integers don't have it but floats do, and since0. == 0
, we can substitute its equality operator., which is0..__eq__
. \$\endgroup\$xnor– xnor2016年02月03日 08:52:01 +00:00Commented Feb 3, 2016 at 8:52 -
\$\begingroup\$ @xnor ahh, I knew about the
.__eq__
method, but the double dots were confusing me. I didn't catch that the first one was the decimal point in a float literal. \$\endgroup\$user45941– user459412016年02月03日 09:14:18 +00:00Commented Feb 3, 2016 at 9:14
ES6, 23 bytes
a=>a.sort((x,y)=>!x-!y)
It used to be the case that sort
wasn't stable, in which case you needed 41 bytes:
a=>a.filter(x=>x).concat(a.filter(x=>!x))
Python byte code (2.7.9), 252 bytes, 33 opcodes, 0.0228 seconds
This was build when the contest was still a fastest-code contest
Opens a file in the current directory called 'SourceArray'
for use
LOAD_CONST ''
STORE_FAST no_zeroes# no_zeroes = ''
LOAD_NAME open
LOAD_CONST 'SourceArray'
CALL_FUNCTION 0,1# open('SourceArray')
LOAD_ATTR read
CALL_FUNCTION 0,0# .read()
LOAD_ATTR split
CALL_FUNCTION 0,0# .split()
DUP_TOP
DUP_TOP #Start if
BUILD_LIST 0
COMPARE_OP ==
POP_JUMP_IF_TRUE 35# if list == [], GOTO 35
LOAD_ATTR pop
LOAD_CONST 0
CALL_FUNCTION 0,1# list.pop(0)
DUP_TOP
LOAD_CONST '0'
COMPARE_OP ==
POP_JUMP_IF_TRUE 28# if list.pop(0) == '0', GOTO 28
PRINT_ITEM # print list.pop(0)
JUMP_ABSOLUTE 13
POP_TOP
LOAD_CONST '0%_'# '0 '
LOAD_FAST no_zeroes
INPLACE_ADD
STORE_FAST no_zeroes# no_zeroes = no_zeroes + '0 '
JUMP_ABSOLUTE 13
LOAD_FAST no_zeroes
PRINT_ITEM # print no_zeroes
LOAD_CONST None
RETURN_VALUE
The co_code
(The actual codey bit)
'd\x01\x00}\x00\x00\te\x00\x00\x83\x00\x00\tj\x01\x00\x83\x00\x00\t\x04\x04g\x00\x00k\x02\x00sG\x00j\x02\x00d\x02\x00\x83\x01\x00\x04d\x03\x00k\x02\x00s8\x00Gq\x15\x00\t\x01d\x04\x00|\x00\x007}\x00\x00q\x15\x00\t|\x00\x00G\td\x00\x00S'
Or a .pyc file version 03F3
03 F3 0D 0A 40 FD B0 56 63 00 00 00 00 01 00 00 00 03 00 00 00 00 00 00 00 73 59 00 00 00 64 01 00 7D 00 00 09 65 00 00 64 02 00 83 01 00 6A 01 00 83 00 00 09 6A 02 00 83 00 00 09 04 04 67 00 00 6B 02 00 73 50 00 6A 03 00 64 03 00 83 01 00 04 64 04 00 6B 02 00 73 41 00 47 71 1E 00 09 01 64 05 00 7C 00 00 37 7D 00 00 71 1E 00 09 7C 00 00 47 09 64 00 00 53 28 06 00 00 00 4E 74 00 00 00 00 74 0B 00 00 00 53 6F 75 72 63 65 41 72 72 61 79 69 00 00 00 00 74 01 00 00 00 30 73 02 00 00 00 30 20 28 04 00 00 00 74 04 00 00 00 6F 70 65 6E 74 04 00 00 00 72 65 61 64 74 05 00 00 00 73 70 6C 69 74 74 03 00 00 00 70 6F 70 28 01 00 00 00 74 09 00 00 00 6E 6F 5F 7A 65 72 6F 65 73 28 00 00 00 00 28 00 00 00 00 74 09 00 00 00 70 79 6B 65 5F 63 6F 64 65 52 08 00 00 00 01 00 00 00 52 00 00 00 00
You can try to compile my source code yourself using my library on github. I just posted a commit to it that allowed comments so I hope this is still competing as far as fastest-code goes ;)
Roughly equivalent to
no_zeroes = ''
unamed_variable = open('SourceArray').read().split()
while unamed_variable != []:
unamed_variable_2 = unamed_variable.pop()
if unamed_variable_2 == '0':
no_zeroes += '0 '
else:
print unamed_variable_2,
print no_zeroes,
-
\$\begingroup\$ Wooow. You cut a ton of time off of that. \$\endgroup\$Addison Crump– Addison Crump2016年02月02日 19:42:53 +00:00Commented Feb 2, 2016 at 19:42
-
\$\begingroup\$ @VoteToClose that's about 1.5x the speed it ran on my laptop :O Who said Python was that slow? \$\endgroup\$Blue– Blue2016年02月02日 19:46:36 +00:00Commented Feb 2, 2016 at 19:46
Matlab: 21 bytes
@(a)[a(a~=0),a(a==0)]
Prints nonzero elements first, then concatenates with zero elements
@(a)____
create an anonymous function with one input argument a
[___,___]
concatenates horizontally vectors inside brackets, separated by commas
a(a~=0)
returns vector with all nonzero elements of vector a
a(a==0)
returns vector with all zero elements of vector a
APL: 8 bytes
(⍴a)↑a~0
a~0 remove zeros from a (read "a without 0")
(⍴a) original length of a (read "shape of a")
↑ pad a without zeros to a's original length
Try it in http://ngn.github.com/apl/web/index.html
Test data: a←1 0 1 2 3 4 0 1 0 0 0 0 1 2 3 4 5
-
1\$\begingroup\$ You should either write a full program and read the input from stdin, or write a function and read the input from its parameters. But you can use
⍴↑{⍵~0}
and that's even shorter. \$\endgroup\$jimmy23013– jimmy230132016年02月03日 13:26:37 +00:00Commented Feb 3, 2016 at 13:26 -
\$\begingroup\$ Not so fast. ⍴↑{⍵~0} won't work everywhere, not in APL2000, nor in IBM APL2. \$\endgroup\$Lobachevsky– Lobachevsky2016年02月07日 16:17:53 +00:00Commented Feb 7, 2016 at 16:17
-
\$\begingroup\$ ⍴↑{⍵~0} will return an empty vector. ⍴⍴↑{⍵~0} is a (one element vector) zero. \$\endgroup\$Lobachevsky– Lobachevsky2016年02月08日 08:56:45 +00:00Commented Feb 8, 2016 at 8:56
Zsh, 22 bytes
(input passed as arguments to the script/function ($@
aka $argv
array), output on stdout as space separated list, newline terminated)
<<<${@:#0}\ ${(M)@:#0}
<<< string
: here-string here passed as stdin to the$NULLCMD
command (cat
by default).${@:#0}
$@
except elements being 0.${(M)@:#0}
reverse of the above
That assumes (like several other answers here) that zeroes in the input are all expressed as 0
(no 00
nor 0x0
nor 36#0
).
-
\$\begingroup\$ verified on tio :) \$\endgroup\$roblogic– roblogic2020年11月13日 14:43:10 +00:00Commented Nov 13, 2020 at 14:43
Haskell, 26 bytes
f x=filter(/=0)x++[0|0<-x]
Take all non-zero numbers followed by all zeros. Filtering constants (here: 0
) is quite short when using a list comprehension: [0|0<-x]
.
Mathematica, 14 bytes
Sort[#,#!=0&]&
-
4\$\begingroup\$
Sort[#!=0&]
should be enough. \$\endgroup\$Martin Ender– Martin Ender2016年02月03日 08:21:27 +00:00Commented Feb 3, 2016 at 8:21
Common Lisp, 46 bytes
(lambda(a)(stable-sort a(lambda(_ b)(= 0 b))))
Sort the array so that for each couple (a,b), we have a < b if b is zero. When neither a < b or b < a, the sort is stable: the original order between elements is retained.
I also tried with adjust-array and remove, but this was too long:
(lambda(a)(adjust-array(remove 0 a)(length a):initial-element 0))
Javascript, (削除) 52 (削除ここまで) (削除) 54 (削除ここまで) 51 bytes
s=>s.replace(/\b0 /g,x=>++i&&'',i=0)+' 0'.repeat(i)
-
\$\begingroup\$ This doesn't work when the input does not contain any zeroes \$\endgroup\$rink.attendant.6– rink.attendant.62016年02月02日 22:07:33 +00:00Commented Feb 2, 2016 at 22:07
-
\$\begingroup\$ @rink.attendant.6. Thanks, I've updated and still looking for some bytes off :) \$\endgroup\$removed– removed2016年02月02日 22:46:03 +00:00Commented Feb 2, 2016 at 22:46
Java 7, 78 bytes
void g(int[]a){int c=0;for(int o:a)a[o==0?c:c++]=o;for(;c<a.length;a[c++]=0);}
I'm not sure why the other Java entries are using strings. If you want to filter an integer array, it seems best to use an integer array. This modifies the input in place by keeping two indices, then just filling the remaining slots with zeros.
-
\$\begingroup\$ Heh, I used it because I felt like it. I think you should be able to declare
o
withint c=0,o;for(o:a)...
. You can also convert to Java 8 lambda syntax:a->{int c=0;for(int o:a)a[o==0?c:c++]=o;for(;c<a.length;a[c++]=0);}
and state that it expects input as an int array. \$\endgroup\$Addison Crump– Addison Crump2016年02月04日 20:35:44 +00:00Commented Feb 4, 2016 at 20:35 -
\$\begingroup\$ Wait, scratch the o declaration thingy. But still, java 8 lambda. :D \$\endgroup\$Addison Crump– Addison Crump2016年02月04日 20:44:45 +00:00Commented Feb 4, 2016 at 20:44
-
\$\begingroup\$ @VoteToClose I thought it had to be self-contained. If I can declare types and stuff elsewhere without counting it, that doesn't seem right. \$\endgroup\$Marky Markov– Marky Markov2016年02月04日 22:28:06 +00:00Commented Feb 4, 2016 at 22:28
-
\$\begingroup\$ Since this is a function, input is passed to it by a previously executed statement anyways. The lambda can assume an input type, so its essentially the same. \$\endgroup\$Addison Crump– Addison Crump2016年02月04日 23:00:49 +00:00Commented Feb 4, 2016 at 23:00
AWK, 34 bytes
{for(;a++-NF;c?$++b=c:0)$a-=c=$a}1
This code runs through all the commandline arguments, shifts non-zero values to the left and clears arguments as it processes them.
The top of loop "should we iteration" condition expression is:
a++-NF
which increments a
until it hits the number of commandline arguments NF
.
The body of the loop,
$a-=c=$a
saves the value of the current commandline argument in variable c
, then sets the current argument to 0.
At the end of each iteration, the ternery:
c?$++b=c:0
checks to see if the current argument c
is non-zero and if so, increments the b
(the number of non-zero argument found so far) and stores the current argument value in that slot.
After the code block processes the commandline arguments, the only left to do is trigger AWK to print all the commandline arguments with a truthy
test without a code block.
1
Vyxal, (削除) 3 (削除ここまで) 2 bytes
μ¬
Sort by logical negation. The header puts the input into a list format.
PHP, (削除) 73 (削除ここまで) (削除) 71 (削除ここまで) (削除) 70 (削除ここまで) (削除) 52 (削除ここまで) (削除) 49 (削除ここまで) (削除) 48 (削除ここまで) 46 bytes - BIG thanks to Ismael Miguel
// Assuming
$a = array(4,8,6,1,0,8,0,0,0,0,0,-4,'-5',-1,564,0);
// Produces a notice-level error
foreach($a as$v)$v?print"$v ":$b.="0 ";echo$b;
-
1\$\begingroup\$
$v==0
can be replaced with!$v
, saving you 2 bytes. \$\endgroup\$Ismael Miguel– Ismael Miguel2016年02月02日 21:17:34 +00:00Commented Feb 2, 2016 at 21:17 -
\$\begingroup\$ You're welcome. I see you did manage to cut a byte. Try this:
foreach($argv as$v)$v?$f.=" $v":$b.=" $v";echo$f.$b;
. It is.... some bytes, I don't know... \$\endgroup\$Ismael Miguel– Ismael Miguel2016年02月02日 21:41:35 +00:00Commented Feb 2, 2016 at 21:41 -
2\$\begingroup\$ Or
foreach($a as$v)$v?print("$v "):$b.="$v ";echo$b;
for a more neat way, that looks exactly the same \$\endgroup\$Ismael Miguel– Ismael Miguel2016年02月02日 21:49:44 +00:00Commented Feb 2, 2016 at 21:49 -
1\$\begingroup\$ @IsmaelMiguel Nice! I would cry if I ever had to pick up someone else's project and found this level of code-golfing lol \$\endgroup\$MonkeyZeus– MonkeyZeus2016年02月02日 21:54:52 +00:00Commented Feb 2, 2016 at 21:54
-
\$\begingroup\$ @IsmaelMiguel Shaved a few more! \$\endgroup\$MonkeyZeus– MonkeyZeus2016年02月02日 22:04:24 +00:00Commented Feb 2, 2016 at 22:04
Bash + GNU utilities, 23
grep -v ^0 a
grep ^0 a
Assumes input is newline-separated entries in a file called a
. Score includes +1 for this filename.
-
\$\begingroup\$ @sch Yes, it should be bash - fixed. \$\endgroup\$Digital Trauma– Digital Trauma2016年02月03日 16:24:23 +00:00Commented Feb 3, 2016 at 16:24
Perl 5, 26 bytes
23 plus three for -an
(-E
is free)
say for sort{!$a-!$b}@F
Thanks to Dennis for reminding me of -a
, saving two bytes.
JavaScript ES6, 16 bytes
x=>x.sort(t=>!t)
Works on firefox
CJam, 6 bytes
{{!}$}
An anonymous function. Sort using "whether or not an element is zero" as a key.
Clojure/ClojureScript, 18 bytes
#(sort-by zero? %)
MATL, 7 bytes
t~FT#S)
t % input array. Duplicate
~ % logical negate: nonzero values become false, zeros become true
FT#S % sort (false, then true) and output a vector with the indices of the sorting
) % apply that vector of indices to original array
Seriously, 12 bytes
4,n`Y`M@░)░+
Explanation:
4,n`Y`M@░)░+
4,n push 4 copies of input
`Y`M map logical negate
@░) filter (take zeroes) and push to bottom of stack
░ filter (take non-zeroes)
+ append zeroes
Perl6, 11 bytes
{.sort(!*)}
Produces a Block - which can be called on an array:
{.sort(!*)}.([1,2,0,3]).say
Although it would be more natural (and shorter) to write:
[1,2,0,3].sort(!*).say
How it works: if the perl6 sort routine is called with a block which accepts only one argument, the list elements are sorted according to by($a) cmp by($b)
. In this case, the block is !*
, i.e. a negation of the whatever operator.
I notice that:
- The example in the question is a class which provides a method, not including boilerplate required to read in
- The description of the task does not require printing, and, except for the fact that the example prints, implies that an array might be returned
TeX (Plain format), 160 bytes
Make the 0
character active (that is, make the interpreter process it as a command), then define that command to skip the character and increment a counter. At the end of the string, print as many zeros as were counted.
Save this as zero.tex
and give the input through the command line with this command:
pdftex "\def\I{0 1 0 3 2 0 0 8 0 5 0 1 9 4}\input zero"
\def\I{}\newcount\Z\def\L{\loop\advance\Z by-1\ifnum\Z>00 \repeat}
\begingroup\catcode`013円 \def0{\advance\Z by1}
\scantokens\expandafter{\I\empty}\endgroup\L\bye
(Newlines added for clarity)