17
\$\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\$
  • \$\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 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 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 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 at 22:24
  • 1
    \$\begingroup\$ Does it need to be a Boolean or falsy/truthy is fine as usual? \$\endgroup\$ – Luca Citi May 22 at 23:57

50 Answers 50

12
\$\begingroup\$

Haskell, 20 bytes

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

Try it online!

| improve this answer | |
\$\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!

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ Also works in Python 3 \$\endgroup\$ – L3viathan May 27 at 16:04
  • \$\begingroup\$ -3 bytes \$\endgroup\$ – cschultz2048 Jun 2 at 18:15
6
\$\begingroup\$

Jelly, 4 bytes

ḂĠẈE

A monadic Link accepting a list of integers which yields 0 (falsey) or 1 (truthy).

Try it online!

How?

ḂĠẈE - Link: list of integers              e.g. [1,2,3,4,6]
Ḃ    - least-significant bit (vectorises)       [1,0,1,0,0]
 Ġ   - group (1-based) indices by value         [[2,4,5],[1,3]]
  Ẉ  - length of each                           [3,2]
   E - all equal?                               0
| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ @MarcusMangelsdorf - the 5 is the 1-based index of the rightmost zero. \$\endgroup\$ – Jonathan Allan May 23 at 17:49
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.

| improve this answer | |
\$\endgroup\$
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
| improve this answer | |
\$\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!

| improve this answer | |
\$\endgroup\$
  • 1
    \$\begingroup\$ 37 if you use a lambda and lose the unneeded space between %2 and for \$\endgroup\$ – ElPedro May 22 at 10:41
  • 1
    \$\begingroup\$ The space in front of for keyword is not necessary. \$\endgroup\$ – manatwork May 22 at 10:44
  • \$\begingroup\$ 34, if you port the most upvoted answer at Code Review. \$\endgroup\$ – user92069 May 22 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 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 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).

| improve this answer | |
\$\endgroup\$
3
\$\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!

| improve this answer | |
\$\endgroup\$
3
\$\begingroup\$

Wolfram Language (Mathematica), 14 bytes

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

Try it online!

| improve this answer | |
\$\endgroup\$
  • 2
    \$\begingroup\$ Perfect! ... :) \$\endgroup\$ – Greg Martin May 23 at 17:26
3
\$\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.

| improve this answer | |
\$\endgroup\$
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!

| improve this answer | |
\$\endgroup\$
  • 1
    \$\begingroup\$ Can you save 2 bytes by dropping ()∘ and replacing it by simple ⎕ input \$\endgroup\$ – Graham May 22 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 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

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ Got some extra parens around the comparison, I think? \$\endgroup\$ – Calculuswhiz yesterday
3
\$\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.

| improve this answer | |
\$\endgroup\$
  • 1
    \$\begingroup\$ You know the other method is shorter in Ruby too, right? Try it online! \$\endgroup\$ – manatwork May 23 at 22:33
  • 2
    \$\begingroup\$ @manatwork Even shorter. \$\endgroup\$ – Dingus May 24 at 13:20
  • 3
    \$\begingroup\$ Yet shorter \$\endgroup\$ – histocrat May 24 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\$ – Armand Fardeau May 27 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 at 15:14
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
| improve this answer | |
\$\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
| improve this answer | |
\$\endgroup\$
2
\$\begingroup\$

K (Kona), 7 bytes

0=+/-1^

Try it online!

J, 9 bytes

0=1#._1^]

Try it online!

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

| improve this answer | |
\$\endgroup\$
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?
| improve this answer | |
\$\endgroup\$
2
\$\begingroup\$

Factor, 52 bytes

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

Try it online!

| improve this answer | |
\$\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)
| improve this answer | |
\$\endgroup\$
2
\$\begingroup\$

Python 3, 30 bytes

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

Try it online!

| improve this answer | |
\$\endgroup\$
2
\$\begingroup\$

R, 18 17 bytes

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

Try it online!

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

| improve this answer | |
\$\endgroup\$
  • 1
    \$\begingroup\$ You can save 1 byte using !sum((-1)^scan()) \$\endgroup\$ – Bart-Jan van Rossum May 25 at 11:58
  • \$\begingroup\$ Thankyou! That is clever, and I'm jealous that I didn't think of it myself. \$\endgroup\$ – Dominic van Essen May 25 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\$.

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ b+=-*a++%2|1 to save a byte \$\endgroup\$ – Olivier Grégoire May 25 at 13:06
  • \$\begingroup\$ @OlivierGrégoire Nice one - thanks! :-) \$\endgroup\$ – Noodle9 May 25 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
| improve this answer | |
\$\endgroup\$
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.)
| improve this answer | |
\$\endgroup\$
  • 1
    \$\begingroup\$ This is amazing, +1 for the poem \$\endgroup\$ – Surculose Sputum Jul 3 at 19:31
2
\$\begingroup\$

Keg, 13 10 bytes

÷⑷0;$Ë⑸⅀0=

Try it online!

Transpiled Code

item_split(stack)
keg_map(stack, '0;$Ë')
summate(stack)
integer(stack, 0)
comparative(stack, '=')

0;$Ë turns into:

integer(stack, 0)
decrement(stack)
swap(stack)
exponate(stack)
| improve this answer | |
\$\endgroup\$
2
\$\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
| improve this answer | |
\$\endgroup\$
1
\$\begingroup\$

jq, 24 characters

map(.%2)|add+0==length/2

Just a write of the question owner's Python solution.

(Grr! 2 characters wasted because []|add results null.)

Sample run:

bash-5.0$ jq 'map(.%2)|add+0==length/2' <<< '[5, 1, 0, 2]'
true

Try it online! / Try all test cases online!

jq, 21 characters

map(.%2*2-1)|add+0==0

The other most efficient solution from Code Review.

Sample run:

bash-5.0$ jq 'map(.%2*2-1)|add+0==0' <<< '[5, 1, 0, 2]'
true

Try it online! / Try all test cases online!

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ Does jq not have a logical negation operator that can return true for both null and 0, so that you don't have to use +0==0? \$\endgroup\$ – Neil May 22 at 12:34
  • \$\begingroup\$ @Neil If jq has one, I'd be able to golf my Erlang solution. \$\endgroup\$ – user92069 May 22 at 12:35
  • \$\begingroup\$ @Neil, in jq the only negation is the not filter, but as jq is quite strictly typed, all numbers are truthy: jq -c 'map(not)' <<< '[null,0]' results [true,false]. Even that + is working as an exception as the other arithmetic operators throw error on null operand. \$\endgroup\$ – manatwork May 22 at 13:05
1
\$\begingroup\$

Julia 18 bytes

Try it!

l->sum((-1).^l)==0
| improve this answer | |
\$\endgroup\$
1
\$\begingroup\$

Java (JDK), 28 bytes

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

Try it online!

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ Nice job golfing it in Java! \$\endgroup\$ – user 2 days ago
1
\$\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?
| improve this answer | |
\$\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.