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

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

39 Answers 39

9
\$\begingroup\$

Haskell, 20 bytes

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

Try it online!

| improve this answer | | | | |
\$\endgroup\$
8
\$\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\$
5
\$\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 2 days ago
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\$ – Λ̸̸ 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 | | | | |
New contributor
Yaroslav Gaponov is a new contributor to this site. Take care in asking for clarification, commenting, and answering. Check out our Code of Conduct.
\$\endgroup\$
3
\$\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\$
3
\$\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\$
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 2 days ago
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\$

Factor, 52 bytes

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

Try it online!

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

Burlesque, 17 bytes

ps{2.%}pt{L[}m[sm

Try it online!

Explanation:

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

Ruby, 30 bytes

->x{2*x.count(&:odd?)==x.size}

Try it online!

Edit: -3 bytes thanks to Dingus

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

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\$
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 21 hours ago
  • \$\begingroup\$ @OlivierGrégoire Nice one - thanks! :-) \$\endgroup\$ – Noodle9 12 hours ago
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\$ – Λ̸̸ 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\$

Wolfram Language (Mathematica), 14 bytes

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

Try it online!

| improve this answer | | | | |
\$\endgroup\$
  • \$\begingroup\$ Perfect! ... :) \$\endgroup\$ – Greg Martin 2 days ago
1
\$\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\$
1
\$\begingroup\$

Julia 18 bytes

Try it!

l->sum((-1).^l)==0
| improve this answer | | | | |
New contributor
jling is a new contributor to this site. Take care in asking for clarification, commenting, and answering. Check out our Code of Conduct.
\$\endgroup\$
1
\$\begingroup\$

Python 3, 30 bytes

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

Try it online!

| improve this answer | | | | |
\$\endgroup\$
1
\$\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 22 hours ago
  • \$\begingroup\$ Thankyou! That is clever, and I'm jealous that I didn't think of it myself. \$\endgroup\$ – Dominic van Essen 21 hours ago
0
\$\begingroup\$

APL+WIN, 15 bytes

Prompts for input of array. Can be anything from scalar, vector or multi dimensional array. TIO gives examples up to a 4 dimensional array:

(+/~n)=+/n←2|,⎕

Try it online! Coutesy of Dyalog Classic

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

Erlang (escript), 40 bytes

Port of the Python answer on Code Review.

f(I)->lists:sum([X rem 2*2-1||X<-I])==0.

Try it online!

Explanation

f(I)->    % Takes an input argument
||X<-I]   % For every inputted item:
[X rem 2*2-1 % Convert X % 2 into 1's and -1's, respectively
lists:sum()  % Sum the list
==0.          % Is it 0?
| improve this answer | | | | |
\$\endgroup\$
0
\$\begingroup\$

Befunge-93, 27 26 bytes

0v   @.$<
+>&:1+!#^_2%2*1-

Try it online!

Prints 0 if the number of odd and even numbers are equal, something else if they aren't. Keeps track of the difference between the number of even and odd numbers seen, adding 1 for an odd number, and -1 for an even number. Prints out this difference.

Edit: Moved the + to the left, saving a byte.

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

Charcoal, 5 bytes

¬ΣX±¹

Try it online! Port of @xnor's Haskell answer. Corresponds to the verbose code Print(Not(Sum(Power(Negate(1), Input())))); except that the input is implicit. Works even for zero-length arrays whose sum is Null rather than 0. Note: Zero-length input arrays seem to confuse Charcoal, so input that case as [[],[]].

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

Retina 0.8.2, 49 bytes

\d+
$*
+`(^|(,))(11)*(,1|1,)(11)*($|(\2)|,)
$7
^$

Try it online! Link includes test cases. Explanation:

\d+
$*

Convert to unary.

(^|(,))(11)*(,1|1,)(11)*($|(\2)|,)
$7

Match an even number of characters that includes a single , and is delimited on either side by either the end of the string or a ,, thus corresponding to a pair of numbers of opposite parity. Remove both numbers and at most one adjacent ,.

+`

Continue to remove pairs of numbers until all remaining numbers have the same parity.

^$

Check that there are no numbers left.

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

Husk, 6 bytes

Why does need so many bytes... help!

EmLk%2

Try it online!

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

R, 28 bytes

!sd(table(c(0,1,scan())%%2))

Try it online!

table gets the counts of the unique values in the array. By appending c(0,1) to the array, we take care of the empty case. The standard deviation is equal to zero if and only if all the values from table() are equal, so we take the logical negation of that to get the result.

Alternately:

R, 28 bytes

!any(diff(table(scan()%%2)))

Try it online!

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

Icon, 52 bytes

procedure f(a)
(s:=0)+:=-1^!a&\z
return(s=0&1)|0
end

Try it online!

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