23
\$\begingroup\$

Inspired by this code review question, I am curious to see what happens if we turn that into a code-golf challenge!

The description is easy, the input is an array or any similar data structure with only unsigned integers, the output is a boolean if the number of odd numbers is equal to the number of even numbers inside (true or false doesn't matter, as long as the opposite is used in case the number doesn't match)

Here are some examples with true as output for matching (thanks to the original OP)

[5, 1, 0, 2]      ->  true 
[5, 1, 0, 2, 11]  ->  false
[]                ->  true 

Usual code-golf rules, shortest code wins.

\$\endgroup\$
11
  • \$\begingroup\$ Challenges should be self contained. References to external resources are welcome, but you should not rely on them. Please post some test cases here. \$\endgroup\$
    – manatwork
    May 22, 2020 at 10:39
  • 2
    \$\begingroup\$ @ElPedro I could say no if I wanted to be strict but, why not, maybe something interesting comes out of it. I'll edit the question. \$\endgroup\$
    – bracco23
    May 22, 2020 at 12:31
  • 3
    \$\begingroup\$ @ElPedro sorry not empty lists exemptions, you should always consider edge cases to avoid bugs :P \$\endgroup\$
    – bracco23
    May 22, 2020 at 12:36
  • 2
    \$\begingroup\$ @DomenicoModica A similar assumption has been made for the C solution. Since the input is only unsigned numbers, using a sentinel of -1 for end I think is fair. Go ahead ;) \$\endgroup\$
    – bracco23
    May 22, 2020 at 22:24
  • 1
    \$\begingroup\$ Does it need to be a Boolean or falsy/truthy is fine as usual? \$\endgroup\$
    – Luca Citi
    May 22, 2020 at 23:57

70 Answers 70

14
\$\begingroup\$

Haskell, 20 bytes

(==0).sum.map((-1)^)

Try it online!

\$\endgroup\$
9
\$\begingroup\$

Python 2, 33 bytes

lambda l:sum(n%-2|1for n in l)==0

Try it online!

n%-2|1 is a shorter way to do(-1)**n. It works like this:

   n  n%-2  n%-2|1
------------------
even     0       1
 odd    -1      -1

36 bytes

lambda l:sum(map((-1).__pow__,l))==0

Try it online!

\$\endgroup\$
1
  • \$\begingroup\$ Also works in Python 3 \$\endgroup\$
    – L3viathan
    May 27, 2020 at 16:04
7
\$\begingroup\$

Jelly, 4 bytes

Thanks to Nick Kennedy for fixing a bug after three years!

Ḃo-S

A monadic Link that accepts a list of integers and yields zero (falsey) if the odd and even counts are equal or a non-zero number (truthy) otherwise.

Try it online!

How?

Ḃo-S - Link: list of integers              e.g. [ 1, 2, 3, 4, 6]
Ḃ    - least-significant bit (vectorises)       [ 1, 0, 1, 0, 0]
  -  - -1
 o   - logical OR                               [ 1,-1, 1,-1,-1]
   S - sum                                      -1

Alternatively, ịØ+S, does the same thing using modular indexing.

\$\endgroup\$
2
  • \$\begingroup\$ @MarcusMangelsdorf - the 5 is the 1-based index of the rightmost zero. \$\endgroup\$ May 23, 2020 at 17:49
  • 1
    \$\begingroup\$ @NickKennedy Oops, schoolboy error; shocking that neither I nor others noticed at the time. Thanks for the fix :) \$\endgroup\$ Oct 14, 2023 at 14:20
5
\$\begingroup\$

-2 bytes, BIG Thanks to Arnauld

JavaScript (V8), 31 bytes

s=>s.map(e=>d+=e&1||-1,d=0)&&!d

Try it online!

\$\endgroup\$
1
  • 1
    \$\begingroup\$ Based on your answer s=>s.map(n=>c+=1-n%2*2,c=0)&&!c - 31 bytes \$\endgroup\$
    – EzioMercer
    Jan 25, 2023 at 23:26
4
\$\begingroup\$

perl -alp, 20 19 bytes

$_=@F-2*grep$_%2,@F

Try it online!

Just checks whether the size of the input is twice the number of odd integers. Accepts a list of space separated integers on STDIN. Prints 0 if the number of even and odd numbers are equal, something else otherwise.

\$\endgroup\$
4
\$\begingroup\$

Wolfram Language (Mathematica), 14 bytes

Tr[(-1)^#]==0&

Try it online!

\$\endgroup\$
1
  • 2
    \$\begingroup\$ Perfect! ... :) \$\endgroup\$ May 23, 2020 at 17:26
4
\$\begingroup\$

MathGolf, 4 bytes

Port of @xnor's Haskell answer. In MathGolf, summing an empty list yields 0.

b▬Σ┌

Try it online!

Explanation

b    Constant -1
 ▬   -1 ** input list (vectorizes)
  Σ  Sum the resulting list
   ┌ Convert to inverted boolean
\$\endgroup\$
4
\$\begingroup\$

Python 3, 30 bytes

lambda x:sum(i%2-.5for i in x)

Try it online!

\$\endgroup\$
4
\$\begingroup\$

x86 32-bit machine code, 13 bytes

Input: uint32_t *esi, size_t ecx
returns: EDX = len - 2*even = 0 for balanced, non-zero for unbalanced.
This conveniently works even for len=0 = balanced. As part of this asm custom calling convention / ABI, my boolean data type is 0 / non-zero, rather than the 0 / 1 that C ABIs use.

This avoids needing to actually compare, just decrement twice inside the loop, starting with the list length.

     1                         boe:
     2 00000000 89CA               mov    edx, ecx           ; balance = len
     3 00000002 E309               jecxz  .end
     4                         .loop:                        ; do {
     5 00000004 AD                 lodsd                       ; eax = *p++
     6 00000005 A801               test   al, 1
     7 00000007 7502               jnz   .odd
     8 00000009 4A                 dec    edx
     9 0000000A 4A                 dec    edx                 ; more compact than sub edx,2 in 32-bit code
    10                         .odd:
    11 0000000B E2F7               loop   .loop              ; }while(--ecx);
    12                         .end:
    13                         ;    xchg   eax, edx          ; custom calling convention: return in EDX instead of spending a byte on xchg
    14 0000000D C3                 ret

Try it online! (with a _start test case that exits with the return value as exit status)

An alternate version that calculates in EAX to return in the standard calling convention's register is 14 bytes. It uses test byte [edi], 1 (1 byte longer than test al,1) and increments the pointer with scasd (without caring about the FLAGS result of the eax - [edi] it also does). See the TIO link.

Uncommenting the xchg eax, edx at the bottom of the 13-byte version would do the same thing, and that version's loop is more efficient.


For 8-bit integer input, use lodsb instead. Unfortunately, we can't use and al, 1 / add dl, al or similar (without branching). That would only work for array sizes up to 255. and eax,1 is 3 bytes.

Also, masking and adding only does one increment. lea edx, [edx + eax*2] could work but that's also 3 bytes. Branching on the low bit with test/jnz seems to be best for size, although it sucks for performance with branch mispredicts.

Of course if we wanted to go fast, we'd load 16 bytes at once with movdqa, isolate the low bits with pand, and sum with paddd. Then hsum at the end. Or hsum with psadbw against a zeroed register, then paddq. SIMD is of course especially good for 8-bit elements, 16 per vector instead of 4, with an outer loop to avoid overflowing 8-bit counters. e.g. this AVX2 SO answer.

Something like this could maybe be smallish code-size if we limited it to a fixed-size 16-byte input array, or maybe 8-byte in MMX registers. Unfortunately we rarely get to play with SIMD in code golf because the instructions are larger and inputs can be odd lengths requiring cleanup loops.

\$\endgroup\$
4
\$\begingroup\$

Here is my version (Thanks to @ElPedro and to everyone in the comments for the corrections):

Python 3, 37 bytes

lambda x:sum(i%2for i in x)==len(x)/2

Try it online!

\$\endgroup\$
12
  • 1
    \$\begingroup\$ 37 if you use a lambda and lose the unneeded space between %2 and for \$\endgroup\$
    – ElPedro
    May 22, 2020 at 10:41
  • 1
    \$\begingroup\$ The space in front of for keyword is not necessary. \$\endgroup\$
    – manatwork
    May 22, 2020 at 10:44
  • \$\begingroup\$ 34, if you port the most upvoted answer at Code Review. \$\endgroup\$
    – user92069
    May 22, 2020 at 11:24
  • 1
    \$\begingroup\$ 34/31 if you use map instead of a comprehension: sum(map(lambda i:i%2,x))==len(x)/2 or sum(map(lambda i:i%2*2-1,x))==0 \$\endgroup\$
    – match
    May 22, 2020 at 18:50
  • 2
    \$\begingroup\$ I don't think the first answer is even valid, because it relies on a hardcoded list, and takes no input. \$\endgroup\$
    – mypetlion
    May 22, 2020 at 22:19
4
\$\begingroup\$

dc, 25 24 23 bytes

?0[r_1r^+z1<F]sFz1<Fd/p

Try it online!

Or verify the test examples.


Input on stdin: a line of space-separated integers.

Output on stdout: 0 for truthy, and 1 for falsey (dc doesn't have standard truthy/falsey values).

\$\endgroup\$
4
\$\begingroup\$

Ruby, 23 bytes

->x{x.sum{|n|~0**n}==0}

Try it online!

Special thanks to Manatwork, Dingus and to histocrat for finding the shortest solution, all credit to them.

\$\endgroup\$
5
  • 1
    \$\begingroup\$ You know the other method is shorter in Ruby too, right? Try it online! \$\endgroup\$
    – manatwork
    May 23, 2020 at 22:33
  • 2
    \$\begingroup\$ @manatwork Even shorter. \$\endgroup\$
    – Dingus
    May 24, 2020 at 13:20
  • 3
    \$\begingroup\$ Yet shorter \$\endgroup\$
    – histocrat
    May 24, 2020 at 14:43
  • \$\begingroup\$ Thank you all, I tried to understand all your solutions, very clever. Didn't know that n%-2 is equivalent to -(n%2) @histocrat would you mind explaining how the binary one's complement operator in ruby works? I don't understand how 05 = 0 is different from 04 = 0. Thanks! \$\endgroup\$ May 27, 2020 at 9:32
  • 1
    \$\begingroup\$ @ArmandFardeau, sure. ~ in Ruby is a two's complement negation, so ~0 is equal to -1. -1 to the power of an even number is one, but to the power of an odd number is negative one. The reason we can't just do the more readable -1**n is that ** has a higher precedence than -, so it ends up being parsed like -(1**n)which is always negative one. \$\endgroup\$
    – histocrat
    May 27, 2020 at 15:14
4
\$\begingroup\$

K (Kona), 7 6 bytes

-1 byte thanks to coltim

~+/-1^

Try it online!

J, 9 bytes

0=1#._1^]

Try it online!

Ports of xnor's Haskell solution - please upvote him!

\$\endgroup\$
2
  • 1
    \$\begingroup\$ You can trim a byte from Kona version by replacing 0= with ~ \$\endgroup\$
    – coltim
    Mar 25, 2021 at 19:47
  • \$\begingroup\$ @coltim Yes, indeed. Thank you! \$\endgroup\$ Mar 25, 2021 at 21:43
3
\$\begingroup\$

APL (Dyalog Extended), 7 bytes

Port of xnor's Haskell solution. Prompts for the input; -2 thanks to @Graham.

-1 byte thanks to @Adám by switching the language.

=+/¯1*⎕

Try it online!

\$\endgroup\$
2
  • 1
    \$\begingroup\$ Can you save 2 bytes by dropping ()∘ and replacing it by simple ⎕ input \$\endgroup\$
    – Graham
    May 22, 2020 at 12:05
  • \$\begingroup\$ You can save another byte by switching to Extended Dyalog APL (=+/¯1*⎕) or dzaima/APL (0=1⊥¯1*). \$\endgroup\$
    – Adám
    May 23, 2020 at 22:57
3
\$\begingroup\$

[Excel], 28 bytes

Paste this into a cell outside of column A, the array goes in column A.

=0=SUM(IF((A:A<>""),-1^A:A))

An example:

An example

\$\endgroup\$
1
  • \$\begingroup\$ Got some extra parens around the comparison, I think? \$\endgroup\$ Aug 1, 2020 at 15:11
3
\$\begingroup\$

Java (JDK), 28 bytes

a->a.map(n->-n%2|1).sum()==0

Try it online!

\$\endgroup\$
3
  • 1
    \$\begingroup\$ Nice job golfing it in Java! \$\endgroup\$
    – user
    Jul 31, 2020 at 23:02
  • \$\begingroup\$ Nice solution! I was wondering, is it really allowed in Java CodeGolf to have an IntStream as the input type? I was reluctant to use it, but i would really like to :) \$\endgroup\$
    – Fhuvi
    Jun 20, 2023 at 8:12
  • 1
    \$\begingroup\$ @Fhuvi "the input is an array or any similar data structure", also "Usual code-golf rules", so yes... \$\endgroup\$ Jun 20, 2023 at 10:13
3
\$\begingroup\$

Burlesque, 17 14 bytes

ps{2.%}pt)L[sm

Try it online!

Saved 3 bytes using shorthand map

Explanation:

ps                # Parse input as a block
  {2.%}pt         # Partition block based on modulo 2
         )L[      # Map blocks to their length
            sm    # Check lengths are the same
\$\endgroup\$
3
\$\begingroup\$

Befunge-98 (PyFunge), 13 12 bytes

-1 byte thanks to @Jo King!

#.&2%2*1-+#@

Try it online!

This uses the same logic (&2%2*1-+) as @Abigail's answer, but has a different control flow structure. Befunge-98 adds extra "error handling" functionality to the & and ~ input instructions: when EOF is reached, they reflect the instruction pointer. When this happens, the program can execute a different section of code without the need for an explicit conditional.

#.&2%2*1-+#@
               
               (Implicit: the counter, the top of the (empty) stack, starts at 0)
               (Implicit in program structure: begin loop)

#              Skip the next instruction
 .             (skipped)
  &            Get integer from STDIN
   2%          Take the integer modulo 2
     2*        Multiply that by 2 (results in 2 if the number was odd and 0 if even)
       1-      Subtract 1 (results in 1 if the number was odd and -1 if even)
         +     Add that to the counter
          #    Skip the next instruction
           @   (skipped)
               Repeat

When the input runs out: 
  &            Catch the EOF and reverse direction
 .             Output the counter (0 if odds and evens are matched, nonzero otherwise) as an integer
#              Skip the next instruction (a space)
           @   End the program
\$\endgroup\$
0
3
\$\begingroup\$

MATL, 6 5 bytes

-1 bytes thanks to @LuisMendo

oEqs~

Try it online!

Explanation

oEqs~
o      % Replace each elements with its parity (i.e. mod 2)
 E     % Multiply all element by 2
  q    % Decrement all elements by 1
   s   % Sum the array
    ~  % Boolean not the sum
\$\endgroup\$
0
3
\$\begingroup\$

sed -E, 78 80 bytes

+7 to account for 0's and empty lists, -5 from golfing

Tried to have some fun:) Input is spaced separated unary numbers. Ex: echo "!!! !! !!!!" | sed -Ef main.sed (if the code is saved to main.sed)

s/_/@/g
s/(!!)+/@/g
s/@*!/!/g
s/ //g
:l
s/(!@|@!)//g
tl
s/!+/true/g
s/^$/false/g

Try it online!

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

Uiua, 8 bytes

=0/+ⁿ∶¯1

Try it!

=0/+ⁿ∶¯1
    ⁿ∶¯1  # raise -1 to input
  /+      # sum
=0        # is it equal to zero?
\$\endgroup\$
3
  • 1
    \$\begingroup\$ Or 1 for falsy if there's more evens. \$\endgroup\$ Oct 1, 2023 at 19:04
  • 1
    \$\begingroup\$ @UnrelatedString Oops, fixed for +1. \$\endgroup\$
    – chunes
    Oct 1, 2023 at 19:23
  • 1
    \$\begingroup\$ Alternative 8: =∩/+¬.◿2 \$\endgroup\$
    – Bubbler
    Oct 13, 2023 at 5:13
3
\$\begingroup\$

K (ngn/k), 6 9 bytes

+3 bytes from fixing code per @Dominic van Essen's comment

~+/1 1'2!

Try it online!

  • 2! mod the (implicit) input by two
  • 1 1' convert 0's to -1's, leave 1s unchanged
  • ~+/ not the sum of the above
\$\endgroup\$
2
  • 1
    \$\begingroup\$ I don't think this can work for inputs with an odd-number of elements, but an even number of odd numbers, like [5 1 0 2 4]... \$\endgroup\$ Oct 13, 2023 at 15:32
  • \$\begingroup\$ Good catch - revised the approach to fix that behavior. Thanks! \$\endgroup\$
    – coltim
    Oct 13, 2023 at 16:29
2
\$\begingroup\$

05AB1E, 6 4 bytes

ÉD¢Ë

Try it online!

Explanation

É    Is the number odd?
 D   Duplicate
  ¢  Count the occurances of the bits in the original copy
   Ë Are all items in the list equal?
\$\endgroup\$
2
\$\begingroup\$

Factor, 52 bytes

: f ( s -- ? ) [ odd? ] partition [ length ] bi@ = ;

Try it online!

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

Pyth, 6 bytes

!sm^_1

Try it online!

Explanation

!sm^_1
  m    : map
   ^_1 : -1 power value
       : over implicit input
 s     : sum it
!      : logical negate the sum (i.e. 0 -> True, -1 -> False, 10 -> False)
\$\endgroup\$
2
\$\begingroup\$

R, 18 17 bytes

!sum((-1)^scan())

Try it online!

Edit: -1 byte thanks to Bart-Jan van Rossum

\$\endgroup\$
2
  • 1
    \$\begingroup\$ You can save 1 byte using !sum((-1)^scan()) \$\endgroup\$ May 25, 2020 at 11:58
  • \$\begingroup\$ Thankyou! That is clever, and I'm jealous that I didn't think of it myself. \$\endgroup\$ May 25, 2020 at 12:18
2
\$\begingroup\$

C (gcc), 45 44 43 bytes

Saved a byte thanks to ceilingcat!!!

Saved a byte thanks to Olivier Grégoire!!!

b;f(int*a){for(b=0;~*a;b+=-*a++%2|1);b=!b;}

Try it online!

Input:

\$-1\$ terminated int array.

Output

C boolean values: \$1\$ if number of odd are equal to the number of even numbers, \$0\$ otherwise.

How

Initialise a counter b to \$0\$. Then go through the elements in the array adding \$1\$ to b for every odd number and \$-1\$ to b for every even number. Return the boolean result of testing b equal to \$0\$.

\$\endgroup\$
2
  • \$\begingroup\$ b+=-*a++%2|1 to save a byte \$\endgroup\$ May 25, 2020 at 13:06
  • \$\begingroup\$ @OlivierGrégoire Nice one - thanks! :-) \$\endgroup\$
    – Noodle9
    May 25, 2020 at 21:48
2
\$\begingroup\$

brainfuck, 34 bytes

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

Try it online! (Check the ! box to enter input automatically.)

Takes input as code points. Prints a null byte if there are equal number of odds and evens. Otherwise, prints a non-null byte.

Memory layout:

a b 0 n 0

where a is the current number of odds, b is the current number of evens, and n is the current element in the array.

Explanation:

+>+>>        set a and b to 1, and pointer to n
,[           for each element n in the array
  [-[->]<]     if n is even, pointer stops at n, else, pointer stops at left of n
                 in both case, n is set to 0
                 this requires the cells left and right of n to be 0
  <<+          increment a or b appropriately
  [>]>,        pointer back to n, read new n
]            stop if n = 0 (end of array)
<<[-<->]<.   find b - a, and print that value
\$\endgroup\$
1
2
\$\begingroup\$

Brainetry, 342 bytes

Golfed version:

a b c d
a b
a b c d
a bb
a b
a b c d e f
a b c d e f g h
a b c d e f g h
a b c d e
a b c d e f g h
a b c d e
a b
a b c d e f g h i
a b c
a b c d e f g h i
a b c
a b c
a b c d
a b c d e f g h
a b
a b c d e f g h i
a b
a b c d e f
a b c d e f g h i
a b c
a b c
a b c d e f g h
a b c d e
a b c
a b c d e
a b
a b c d e f g h i
a b c
a b c d e f g

To make our lives easier we use the --numeric-io flag, so that we can take input and give output as integers, but we don't really need to and the answer works without it. Read the program below for due credit.

The golfed version was adapted from the program found below. To try this online you can

  • head over to this replit link, copy&paste the code into the btry/replit.btry file and hit the green "Run" button (takes input as ASCII characters (converts them to codepoints) and outputs ASCII characters, use CTRL-D in a newline to terminate input, doesn't really work well for this challenge.);
  • clone the github repo and from your terminal run ./brainetry btry/ppcg/evens_and_odds.btry --numeric-io (give one integer per line, use CTRL-Z or CTRL-D in an empty line to stop giving input).
"Check if an array
(or equivalent)
has the same number
of odd
and even
numbers - Code Golf Edition !"
That is the title of the codegolf.stackexchange.com challenge
that this brainetry program solves. Once more, with
no shame at all ,
I am piggy backing on someone else's answer.
This time, Surculose Sputum's answer.
Oh boy!
You can check the original answer over here: https://codegolf.stackexchange.com/a/205621/75323
Go upvote that!
This is a very literal port of that answer.
I am pretty
sure I could
have used brainetry's builtins
to make this easier, like » or ≥,
except that
would mean I would have to think... ugh... nope!
For now
I will stick to the low
hanging fruit just to show that brainetry is out.
If this is
the first time
you find a brainetry program, welcome! By now
you probably understood you are
allowed to write
pretty much anything as source.
(source code)
You only have to write lines of correct size
and with the
correct line modifiers. (That's a recent addition.)
\$\endgroup\$
1
  • 1
    \$\begingroup\$ This is amazing, +1 for the poem \$\endgroup\$ Jul 3, 2020 at 19:31
2
\$\begingroup\$

Brachylog, 6 bytes

%₂ᵍlᵐ=

Try it online!

How it works

%₂ᵍlᵐ=
  ᵍ     group input based on result of …
%₂        mod 2
   lᵐ   map length over all groups
     =  are the lengths equal?
\$\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.