24
\$\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\$
16
  • \$\begingroup\$ Ty. Good question. Answer: odd numbers can come in any order. :) \$\endgroup\$ Jul 18, 2018 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, 2018 at 7:17
  • 1
    \$\begingroup\$ @AsoneTuhid Yes:), numbers can repeat. \$\endgroup\$ Jul 18, 2018 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\$ Jul 18, 2018 at 10:09
  • 13
    \$\begingroup\$ Please edit your question to include the clarifications you gave in the comments. \$\endgroup\$
    – Laikoni
    Jul 18, 2018 at 11:18

65 Answers 65

2
\$\begingroup\$

Elixir, 37 35 bytes

Code:

fn x->Enum.sort_by x,&(-rem&1,2)end

Expanded version:

fn x -> Enum.sort_by(x, fn y -> -rem(y, 2) end) end

Try it online!

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

Clojure - 35 bytes

(defn o[c](sort(fn[p _](odd? p))c))

Ungolfed:

(defn oddsort [col]
  (sort (fn [p _] (odd? p)) col))
\$\endgroup\$
2
  • \$\begingroup\$ There is lots of room for improvement, for example you can submit an anonymous function which has a shorter creation syntax via #(...). Also you could give sort-by a try, although the submission already exists. \$\endgroup\$
    – NikoNyrh
    Jul 22, 2018 at 10:32
  • \$\begingroup\$ @NikoNyrh: tried a #() anonymous function but got an arity error as two parameters were passed but only on expected/used, and bringing %2 into it added more characters. Would be interested to see how this could be done. \$\endgroup\$ Jul 22, 2018 at 16:11
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\$
7
  • 2
    \$\begingroup\$ Java 8 has List.sort() (if you don't interpret the question as requiring an array specifically) \$\endgroup\$
    – JollyJoker
    Jul 18, 2018 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\$ Jul 18, 2018 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, 2018 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\$ Jul 18, 2018 at 11:55
  • 1
    \$\begingroup\$ Just came up with (i&1)*-2 for 26 \$\endgroup\$
    – JollyJoker
    Jul 18, 2018 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\$
6
  • 1
    \$\begingroup\$ Welcome to PPCG! I think you can remove the space after the first return to save a byte. \$\endgroup\$
    – wastl
    Jul 18, 2018 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\$ Jul 18, 2018 at 13:28
  • 1
    \$\begingroup\$ You can save 1 byte: for(int i=1;i<c;)puts(v[i++]); \$\endgroup\$ Jul 18, 2018 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\$ Jul 18, 2018 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\$ Jul 20, 2018 at 8:19
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\$
1
  • \$\begingroup\$ Welcome to PPCG! :) \$\endgroup\$
    – Shaggy
    Jul 20, 2018 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\$
0
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\$
1
  • 1
    \$\begingroup\$ Welcome to the site! If you want to talk Haskell/Haskell golfing with us we have a chat room. \$\endgroup\$
    – Wheat Wizard
    Jul 22, 2018 at 0:29
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\$
13
  • 1
    \$\begingroup\$ 72 byte version using qsort: Try it online! \$\endgroup\$
    – ErikF
    Jul 18, 2018 at 8:48
  • \$\begingroup\$ 64 bytes if you replace sizeof(b) by 4 (obviously tying it to a common size of int). \$\endgroup\$ Jul 18, 2018 at 9:55
  • 1
    \$\begingroup\$ Even if not, sizeof b is one byte shorter than sizeof(b). \$\endgroup\$ Jul 18, 2018 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, 2018 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\$ Jul 19, 2018 at 10:26
2
\$\begingroup\$

Go, 105 bytes

import."sort"
func f(I[]int)[]int{Slice(I,func(i,j int)bool{k:=I[i]
if k<0{k=-k}
return k%2>0})
return I}

Attempt This Online!

\$\endgroup\$
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\$
0
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\$
3
  • \$\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\$ Jul 20, 2018 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\$
    – anna328p
    Jul 21, 2018 at 4:11
  • \$\begingroup\$ 18 bytes no question. The improvement comes from using implicit params introduced in Ruby 2.7 \$\endgroup\$
    – south
    Sep 8, 2022 at 23:55
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\$
1
\$\begingroup\$

Julia 1.0, 27 bytes

f(l)=l[sortperm(l.%2 .==0)]

Try it online!

This works too and is a lot more elegant:

f(l)=sort(l,lt=(a,b)->b%2==0)

But it's a few bytes longer :(

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

Zsh, 31 bytes

grep [02468]$<i
grep [13579]$<i

Attempt This Online!

Takes input from a file called i.

\$\endgroup\$
2
  • \$\begingroup\$ You don't need the $<, just a space. ATO \$\endgroup\$ Jun 17, 2022 at 7:26
  • 1
    \$\begingroup\$ @DeathIncarnate The $ is needed, because I need grep to only match at the end of the line, because otherwise it would break for numbers of more than one digit (example). And then changing <i to ​ i doesn't make any difference. \$\endgroup\$
    – pxeger
    Jun 17, 2022 at 7:28
1
\$\begingroup\$

Vyxal, 2 bytes

µ₂

Try it Online!

µ  # Sort by...
 ₂ # Even?
\$\endgroup\$
1
\$\begingroup\$

Fig, \$3\log_{256}(96)\approx\$ 2.469 bytes

^@E

See the README to see how to run this

Aww loses to fancier languages.

^@E # Full program
^   # Sort...
 @  # by...
  E # Is even?
\$\endgroup\$
1
\$\begingroup\$

Thunno 2, 2 bytes

ÞE

Attempt This Online!

Explanation

ÞE  # Implicit input
Þ   # Sort by:
 E  #  Is even?
    # Implicit output
\$\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.