17
\$\begingroup\$

Rearrange a given list such that all the odd numbers appear before all the even numbers. Besides for this requirement, the output list may be in any order.

The input will only contain integers, but they may be negative and there may be duplicates, and they may appear in any order.

Shortest solution wins.

Test cases

[1,2][1,2]

[2,1][1,2]

[1,0,0][1,0,0]

[0,0,-1][-1,0,0]

[3,4,3][3,3,4]

[-4,3,3][3,3,-4]

[2,2,2,3][3,2,2,2]

[3,2,2,2,1,2][1,3,2,2,2,2] or [3,1,2,2,2,2]

[-2,-2,-2,-1,-2,-3][-1,-3,-2,-2,-2,-2,] or [-3,-1,-2,-2,-2,-2,]

[][]

\$\endgroup\$
  • \$\begingroup\$ Ty. Good question. Answer: odd numbers can come in any order. :) \$\endgroup\$ – display_name Jul 18 '18 at 5:37
  • 11
    \$\begingroup\$ Even though the challenge is quite simple, adding some test cases would be nice. E.g. at first glance I thought the block of odd and even numbers also needs to be sorted. \$\endgroup\$ – Laikoni Jul 18 '18 at 7:17
  • 1
    \$\begingroup\$ @AsoneTuhid Yes:), numbers can repeat. \$\endgroup\$ – display_name Jul 18 '18 at 9:47
  • 11
    \$\begingroup\$ @Willmore You never know with code golf, rules are important. Please use the Sandbox next time to clarify your question before you post it. \$\endgroup\$ – Asone Tuhid Jul 18 '18 at 10:09
  • 12
    \$\begingroup\$ Please edit your question to include the clarifications you gave in the comments. \$\endgroup\$ – Laikoni Jul 18 '18 at 11:18

54 Answers 54

2
\$\begingroup\$

Java 8, 46 29 27 bytes

l->l.sort((i,j)->1-(i&1)*2)

Uses Java 8's List.sort(), thanks to JollyJoker for making me aware of it and for saving me 19 bytes. Try it online here.

Ungolfed:

l -> // lambda taking a List of Integers and modifying it
        l.sort( // sort the List according to ...
        (i, j) ->                // ... a Comparator<Integer> with a compare() method ...
                 1 - (i & 1) * 2 // ... that finds a number smaller than another if it's odd, and greater otherwise
\$\endgroup\$
  • 2
    \$\begingroup\$ Java 8 has List.sort() (if you don't interpret the question as requiring an array specifically) \$\endgroup\$ – JollyJoker Jul 18 '18 at 9:54
  • 1
    \$\begingroup\$ @JollyJoker In the absence of a comprehensive spec, I'll choose to interpret it that way :D Thanks for teaching me about List.sort(). This is one of the few instances where golfing suggestions actually improve your real-life programming knowledge. With regards to lists vs. arrays I would reason that since some languages don't have arrays, we can allow lists instead (in keeping with the general rule of when a limited language is allowed something, all languages are allowed that too). Meta post, vote if you like: codegolf.meta.stackexchange.com/a/16670/79343 \$\endgroup\$ – O.O.Balance Jul 18 '18 at 10:35
  • 1
    \$\begingroup\$ Upvoted your meta post. Also played around with the comparator a little but just got equivalent lengths with 1-((i&1)*2) and 1-(i*i%2*2). Thought I'd post them if you see something I missed. \$\endgroup\$ – JollyJoker Jul 18 '18 at 11:50
  • 1
    \$\begingroup\$ @JollyJoker You can drop the outer parentheses due to operator precedence: 1-(i&1)*2 or 1-i*i%2*2 => 27 bytes \$\endgroup\$ – O.O.Balance Jul 18 '18 at 11:55
  • 1
    \$\begingroup\$ Just came up with (i&1)*-2 for 26 \$\endgroup\$ – JollyJoker Jul 18 '18 at 11:59
2
\$\begingroup\$

Retina 0.8.2, 21 bytes

O$`.*(([02468])|.)
$2

Try it online! Link includes header that splits on commas for convenience. Explanation: The last digit of the number is captured if it is even, otherwise it is just matched (this avoids degenerate matches). The $ option then uses the matched digit as the sort key. Odd numbers don't match and end up with an empty sort key, causing them to be sorted first (in their original order), then the even numbers are sorted in order of last digit.

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

T-SQL, 33 bytes

SELECT*FROM t ORDER BY 1-ABS(i)%2

Per our IO standards, input is taken via pre-existing table t with integer column i.

The ABS() function is annoyingly necessary here because the T-SQL modulus operator % returns negative values for negative numbers, which in this case meant I was getting three possible results for i%2: -1, 0, and 1.

Subtracting from 1 is a couple bytes shorter than using DESC.

Note that per the question, I'm not doing any secondary sort, so the order of the odds and evens isn't predictable. If you want a secondary sort, add 2 bytes by adding ,i to the end.

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

C++, 174 165 164 149 129 bytes

  • Replace the two include lines with a single include, regex, that happens to include both required headers

 

#include <regex>
int main(int c,char**v){std::sort(v+1,v+c,[](auto s,auto t){return atoi(s)%2>atoi(t)%2;});for(;*++v;)puts(*v);}

149 Bytes

  • For loop trick for printing. This uses the fact that, on Linux at least, the argv array is null-terminated.
  • replace &1 with %2 to remove need for some brackets. Thank you Toby Speight!

 

#include<algorithm>
#include<cstdio>
int main(int c,char**v){std::sort(v+1,v+c,[](auto s,auto t){return atoi(s)%2>atoi(t)%2;});for(;*++v;)puts(*v);}

Older: 164 bytes

#include<algorithm>
#include<cstdio>
int main(int c,char**v){std::sort(v+1,v+c,[](auto s,auto t){return(atoi(s)&1)>(atoi(t)&1);});for(auto i=1;i<c;i++)puts(v[i]);}

Compile as C++14 or higher. Input is taken on the command line, and prints to standard output.

EDIT: removed un-needed return 0; statement

EDIT 2: Removed space after 'return'

\$\endgroup\$
  • 1
    \$\begingroup\$ Welcome to PPCG! I think you can remove the space after the first return to save a byte. \$\endgroup\$ – wastl Jul 18 '18 at 13:20
  • \$\begingroup\$ @Toby That would work but finding the last character of the string would involve a call to strlen, which already puts us behind. \$\endgroup\$ – Paul Belanger Jul 18 '18 at 13:28
  • 1
    \$\begingroup\$ You can save 1 byte: for(int i=1;i<c;)puts(v[i++]); \$\endgroup\$ – O.O.Balance Jul 18 '18 at 14:09
  • \$\begingroup\$ Thanks for the input -- I've managed to get it down to 129 bytes by removing an include line, and implementing the %2 trick to remove parens, and the second for loop trick! \$\endgroup\$ – Paul Belanger Jul 18 '18 at 19:31
  • 1
    \$\begingroup\$ That's certainly some golfing! Welcome to the crazy world of PPCG! I'm glad those tips helped - I'll just observe that Standard C++ guarantees that argv[argc] is null, so that's a portable technique, and not Linux-specific. Nice trick on the include (although that one is compiler-specific). I don't know whether you've found it yet, but if not: have a browse through the tips tag, and especially Tips for golfing in C++. \$\endgroup\$ – Toby Speight Jul 20 '18 at 8:19
2
\$\begingroup\$

Python, 35 bytes

lambda l:sorted(l,key=(-1).__pow__)

Try it online!

Sorts by the function x -> (-1)**x, which gives -1 for odd and 1 for even.

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

Python 2, 34 bytes

lambda a:sorted(a,lambda x,y:x%-2)

Try it online!

This seems to work, but I don't actually understand why it works. If anyone can explain why my half-witted compare function (It returns -1 if the first argument is odd and 0 if the first argument is even, and that's it) works, I'd greatly appreciate it.

\$\endgroup\$
  • \$\begingroup\$ Welcome to PPCG! :) \$\endgroup\$ – Shaggy Jul 20 '18 at 9:10
2
\$\begingroup\$

sed 4.2.2, 51 43 bytes

Includes +1 for -r

-8 Thanks to Toby Speight

:
s/([^,]*[02468]),([^,]*[13579])/\2,\1/
t

Try it online!

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

><>, 40 bytes

l\ /nao01.
:<}\?%2:$-1/?(1
l0=?;naof2.\~

Try it online!

Filter through the list, printing odd numbers, keeping even numbers
l                  Get the length of the stack, use it as an iterator
:          /?(1    Check that there is at least one value left to process
        $-1        Decrement the iterator
    \?%2           Test if the next number is divisible by two
    /nao           Print it if so,
   }               Else, move it to the bottom of the stack
            ~      Delete the iterator after exiting the loop

Print the even numbers left on the stack
l0=?               If there are no values left on the stack,
    ;              Terminate
     nao           Print the next value
\$\endgroup\$
2
\$\begingroup\$

Clojure, 18 bytes

#(sort-by even? %)

Try it online!

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

Haskell, 44 bytes

Not as byte efficient as Laikoni's answer, but a different approach.

import Data.List
f=uncurry(++).partition odd

Try it online!

Using a sort instead, 47 bytes.

import Data.List
f=sortBy((.even).compare.even)

Try it online!

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

><>, 25 bytes

l/!?:-1$v?%2:{~
$/<+2oan<

Try it online!

Input is via the -v flag. Ends with an error.

Explanation:

l\            ~  Push length of stack as the counter
 \<

         ?%2:{   Pull a number from the bottom of the stack and check if it is odd

 /   -1$v  If even, subtract one from the counter
 /<+2oan<  If odd, print the number and a newline and add two to the counter

 /!?:      If the counter is 0, go down
$/+2oan<   Print the even number anyway, and set the counter to 2

For a non-erroring version, you can replace the last ~ on the first line with ;?=1

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

C (gcc), 71 49 48 bytes

Many thanks to the commenters for the suggestions. Apparently gcc is happy with just a partial ordering of {equal, greater than} for qsort (just to check, clang seems to be happy with this as well.) Although I'm not happy with hardcoding type sizes, it does reduce 7 bytes from sizeof b: change 4 to 8 for systems with a 64-bit int.

q(int*a){a=1-*a&1;}f(a,b)int*a;{qsort(a,b,4,q);}

Try it online!

Alternative version using two passes through the array (79 bytes):

i,j;f(a,b)int*a;{for(i=2;~--i;)for(j=b;~--j;)!(a[j]%2)-i&&printf("%d\t",a[j]);}

Try it online!

\$\endgroup\$
  • 1
    \$\begingroup\$ 72 byte version using qsort: Try it online! \$\endgroup\$ – ErikF Jul 18 '18 at 8:48
  • \$\begingroup\$ 64 bytes if you replace sizeof(b) by 4 (obviously tying it to a common size of int). \$\endgroup\$ – O.O.Balance Jul 18 '18 at 9:55
  • 1
    \$\begingroup\$ Even if not, sizeof b is one byte shorter than sizeof(b). \$\endgroup\$ – Toby Speight Jul 18 '18 at 12:21
  • \$\begingroup\$ @TobySpeight I keep forgetting that sizeof is an operator, not a function. In any case, I've found that it pays to be liberal with parentheses in C, because some of the operator precedence rules are strange and often the cause of many hours of debugging and head-scratching in real programs! \$\endgroup\$ – ErikF Jul 18 '18 at 13:10
  • \$\begingroup\$ If you sort char elements, the element size is a constant 1. But char is allowed to be an unsigned type, and signed char would be required for correctness on one's complement systems, where checking the low bit does not determine odd/even. Of course, caring about extreme portability is pretty ridiculous when you're using a=blah blah instead of return. That's dependent on the implementation detail that gcc -O0 makes sure to evaluate expression in the return-value register (on all architectures I've looked at), but it of course breaks when compiled normally with optimization. \$\endgroup\$ – Peter Cordes Jul 19 '18 at 10:26
1
\$\begingroup\$

Perl 5 with -M5.010 + -MList::MoreUtils+(sort_by), 21 bytes

sub{sort_by{$_%-2}@_}

Try it online!

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

Wolfram Language (Mathematica), 15 12 bytes

SortBy@EvenQ

Try it online!

(saved three bytes thanks to JungHwan Min)


Previous version:

#~SortBy~EvenQ&

Try it online!

\$\endgroup\$
  • \$\begingroup\$ @JungHwanMin: Thank you, changed it. \$\endgroup\$ – celtschk Jul 18 '18 at 14:47
1
\$\begingroup\$

Pyke, 4 bytes

.#t1.&

Try it here!

.#t1.& - sorted(input, key=lambda i: ↓)
  t    -   i-1
   1.& -  ↑ & 1

4 byte hexdump:

A3 74 31 A6

Try it here!

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

Awk: 50 bytes

{and($1,1)?(o=o $1 RS):(e=e $1 RS)}END{print o e}

Input on stdin, Output on stdout

I use RS, the record separator, as a stand-in for "\n", saving two characters each time.

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

Ruby, 19 20 bytes

Works on ruby 2.5.1p57 (2018-03-29 revision 63029) [x86_64-linux] from Arch Linux repos.

->a{a.sort{|i|~i%2}}
\$\endgroup\$
  • \$\begingroup\$ Are you sure? It seems to me that this sorts even numbers first. Also, for me (ruby 2.5.1p57 from homebrew) this fails for negative numbers. \$\endgroup\$ – Asone Tuhid Jul 20 '18 at 6:34
  • \$\begingroup\$ @AsoneTuhid It did not fail for negative numbers for me and i just fixed it to sort odd numbers first (+1 byte) \$\endgroup\$ – dkudriavtsev Jul 21 '18 at 4:11
1
\$\begingroup\$

Rust, 38 bytes

|l:&mut Vec<_>|l.sort_by_key(|e|1^e&1)

Try It Online

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

Swift 4, 40 bytes

print(n.filter{$0%2>0}+n.filter{$0%2<1})

Try it online!

n is the input array

print will be like: [1, 3, 2, 2, 2]

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

Mathematica 25 bytes

Flatten@GatherBy[#, OddQ] &
\$\endgroup\$
1
\$\begingroup\$

Chip -z, 44 bytes

V z.
>~#<
|at|Bb
|A-}]~S
>vvv+Cc
DEFGH
defgh

Try it online!

Chip works in bytes, so this expects a sequence of byte-width values on stdin. I use 0x00 as a special delimiter, so that can't be one of the values. (This could be modified to use a different delimiter, at the expense of code size).

The TIO link above uses ASCII "123456789" as the input, corresponding to values 0x31, 0x32, 0x33, ..., 0x39.

This solution reads though the input twice (it knows it hit the end when it sees the 0x00 mentioned earlier, which is tacked onto the end by the flag -z). On the first pass, it prints the odd values, on the second the evens. It actually starts a third pass, but the termination logic kicks in before it does anything else.

Let's look at a rough overview of the code (Chip is 2D, so regions are described, each line on its own would do nothing useful):

           The V is a bookmarker of sorts. The mark is set at the start of a
V z.       pass, and then recalled when the input is exhausted. This does the
>~#<       looping (as opposed to using a stack or queue to hold the data).
|at|Bb     The # is a half-adder, it increments on each pass. When it
>A-}]~S    carries, the t is triggered, terminating the program. The S
>vvv+Cc    suppresses the values we don't want to print on this pass.
DEFGH      The remaining A-H letter pairs are a cat program, smooshed around
defgh      so that the input elements (capital letters) can do double duty,
           for things like detecting oddness, and the end of input.
\$\endgroup\$
1
\$\begingroup\$

Lua, 142 134 bytes

loadstring'p={...}n={}for i=1,#p*2 do n[#n+1]=i<=#p and p[i]%2==1 and p[i]or i>#p and p[i-#p]%2==0 and p[i-#p]or n[#n+1] end return n'

Try it online!

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

k, 8 bytes

{x@>2!x}

Try it online! Loosely based off of the J answer.

{      } /function
    2!x  /  modulo 2 (mapped through list)
   >     /  get indices to sort descending
 x@      /  return the original list at those indices
\$\endgroup\$
0
\$\begingroup\$

Kotlin, 33 bytes

{l:List<Int>->l.sortedBy{1-it%2}}

Try it online!

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