The modulo parity party

You are given an array A of n strictly positive integers, with n ≥ 2.

• 1 if Aj mod Ai is odd for each j such that 1 ≤ j ≤ n and j ≠ i
• 2 if Aj mod Ai is even for each j such that 1 ≤ j ≤ n and j ≠ i
• 0 otherwise (mixed parities)

Example

For A = [ 73, 50, 61 ], we have:

• 50 mod 73 = 50, 61 mod 73 = 61 → mixed
• 73 mod 50 = 23, 61 mod 50 = 11 → all odd
• 73 mod 61 = 12, 50 mod 61 = 50 → all even

Therefore, the expected output is [ 0, 1, 2 ].

Rules

• You may use any three distinct values (of any type) instead of 0, 1 and 2 as long as they're consistent. Please specify your mapping if you're not using the one described in the challenge.
• Should there be any doubt about that, zero is even.
• This is , so the shortest answer in bytes wins!

Test cases

[ 1, 2 ] --> [ 2, 1 ]
[ 3, 4 ] --> [ 1, 1 ]
[ 1, 2, 3 ] --> [ 2, 1, 0 ]
[ 4, 4, 4 ] --> [ 2, 2, 2 ]
[ 73, 50, 61 ] --> [ 0, 1, 2 ]
[ 941, 459, 533 ] --> [ 1, 0, 0 ]
[ 817, 19, 928, 177 ] --> [ 1, 2, 1, 1 ]
[ 312, 463, 336, 729, 513 ] --> [ 0, 2, 0, 0, 0 ]
[ 53, 47, 33, 87, 81, 3, 17 ] --> [ 0, 0, 0, 1, 0, 2, 0 ]

• Related Feb 6, 2018 at 17:33
• Do the output values have to be integers or would [1], [0, 1], and [1, 1] work? Feb 6, 2018 at 18:33
• @Dennis Any consistent values are fine. So yes, that would work! Feb 6, 2018 at 18:40

Python 2, 6867 66 bytes

-1 byte thanks to Mr. Xcoder
-1 byte thanks to ovs

x=input()
for j in x:k=sum(i%j%2for i in x);print(k<len(x)-1)+0**k


Try it online!

Returns 1,0,2 instead 0,1,2.

• replace (k<1) with 0**k for -1 byte.
– ovs
Feb 6, 2018 at 18:16

Jelly, 9 bytes

%þœ-€0Ḃ‘Ṭ


Returns [1, 1], [0, 1], [1] instead of 0, 1, 2.

Try it online!

How it works

%þœ-€0Ḃ‘Ṭ  Main link. Argument: A (array)

%þ           Build the modulus table.
œ-€0       Remove one 0 from each list of moduli.
Ḃ      Take the last bit of each.
‘     Increment, mapping 0 and 1 to 1 and 2.
Ṭ    Untruth; map each array to an aray of 1's at the specified indices.
This yields:
[1] if the array contains only 1's (all even).
[0, 1] if the array contains only 2's (all odd).
[1, 1] if the array contains 1's and 2's.

• Could you replace ‘ṬUḄ with Q€Ḅ to save a byte? Feb 6, 2018 at 18:25
• Sadly, no. Q€ could return [0, 1] or [1, 0]. Feb 6, 2018 at 18:30
• Oh, right. I think [1], [1,1], and [0,1] are three distinct values so %þœ-€0Ḃ‘Ṭ should be acceptable for 9. EDIT - ah I see you asked this exact question :) Feb 6, 2018 at 18:55
• Another 9 byte alternative is ¹-Ƥ%"%2‘Ṭ Feb 7, 2018 at 13:53

MATL, 12 bytes

!G\o~tAws1=-


This uses 0, -1, 1 instead of 0, 1, 2 respectively.

Explanation

!    % Implicit input: row vector. Transpose into a column
G    % Push input again
\    % Modulus, element-wise with broadcast. Gives a square matrix
o    % Parity: gives 1 for odd, 0 for even
~    % Logical negate: 0 for odd, 1 for even
t    % Duplicate
A    % All: gives 1 for columns that contain only 1
w    % Swap
s    % Sum of each column
1    % Push 1
=    % Is equal? Gives 1 if the column sum was 1, 0 otherwise
-    % Subtract, element-wise. Implicit display


Mathematica, 5749 48 bytes

(s=#;And@@#.Or@@#&@OddQ@Rest@Sort[s~Mod~#]&)/@#&


This returns:

• False.True for 0 (mixed)
• True.True for 1 (all odd)
• False.False for 2 (all even)

Try it online!

Here's a slightly longer alternative (49 bytes):

Sign[(s=#;Tr@Mod[s~Mod~#,2]&)/@#/.Tr[1^#]-1->-1]&


This one returns:

• 1 for 0 (mixed)
• -1 for 1 (all odd)
• 0 for 2 (all even)

Try it online!

C (gcc), 118114979291 86 bytes

• Thanks to Peter Cordes for bugfixing.
• Saved four twenty-one bytes thanks to Peter Cordes; suggesting to use a different output value mapping; [0 1 2] ~ [3 2 1].
• Saved five bytes; using yet another mapping; [0 1 2] ~ [  ].
• Saved a byte; golfed for(i=0;i<n;i++,putchar... to for(i=~0;++i<n;putchar....
• Saved five bytes thanks to ceilingcat.
i,j,r;f(A,n)int*A;{for(i=~0;++i<n;putchar(r))for(r=0,j=n;j--;)r|=j-i?A[j]%A[i]%2+1:0;}


Try it online!

• Your test functions on TIO don't pass enough args, and this undefined behaviour leads to a division by zero (SIGFPE) from the last test case. f(I,7) overwrites the first element of I[] (A[] in f()) with one of the args that you're using as locals. f() assumes that arg was passed on the stack by the caller, but the caller didn't know that, and what's actually on the stack above the return address is A[0]. (i.e. this UB caused t and A[0] to have the same address). Anyway, this is only UB in your test function on TIO. Feb 7, 2018 at 4:02
• And BTW, I couldn't repro the crash locally so I had to add execlp("/usr/bin/objdump", "objdump", "-drwC", "-Mintel", argv[0], 0); to main to get the asm from TIO's gcc 7.2.1, which didn't exactly match my Arch Linux gcc 7.2.1. After turning that disassembly back into asm source for the calling function, I could repro it locally inside gdb and confirm exactly what was happening. Feb 7, 2018 at 4:03
• You might save bytes using a different mapping, like 1 for even, 2 for odd, 3 for mixed, so you can o|=1<<(A[j]%A[i]%2) without needing any fancy decoding for o. Feb 7, 2018 at 4:05
• @PeterCordes Thank you for noting, even though I still do not fully understand why the first array entry gets overwritten. I now chose to use global variables instead of local ones, removing the undefined behaviour. Feb 7, 2018 at 12:06
• @PeterCordes I also took your golfing suggestion and managed to save four bytes. However, I do not know if this really was what you were suggesting, as you wrote o|=1<<... instead of something along the lines of o|=1<<(t=.... Feb 7, 2018 at 12:08

Red, 101 bytes

g: func[b][foreach n b[a: copy[]foreach m b[append a m % n % 2]sort a a: copy next a print unique a]]


Try it online!

Returns 1 0 for mixed, 1 for odd and 0 for even

g: func[b] [
foreach n b [
a: copy []
foreach m b [
append a m % n % 2
]
sort a
a: copy next a
print unique a
]
]


JavaScript (ES6), 46 bytes

a=>a.map(A=>a.map(B=>d+=B%A%2,d=0)|!a[d+1]-!d)


Returns -1 (even), 1 (odd), and 0 (mixed).

How it works:

The d accumulator will be:

1. Zero if all even moduli. (!a[d+1] == false, !d == 1, false - 1 == -1)
2. One less * than the length of the array if all odd moduli. ( * The accumulator includes an element modulused against itself, resulting in one even modulus.) (!a[d+1] == true, !d == 0, true - 0 == 1)
3. Two or more less than the length of the array if a mix. (!a[d+1] == false, !d == 0, false - 0 == 0)

Test cases:

let f=

a=>a.map(A=>a.map(B=>d+=B%A%2,d=0)|!a[d+1]-!d)

console.log(f([ 1, 2 ] ) + ''); // [ -1, 1 ]
console.log(f([ 3, 4 ] ) + ''); // [ 1, 1 ]
console.log(f([ 1, 2, 3 ] ) + ''); // [ -1, 1, 0 ]
console.log(f([ 4, 4, 4 ] ) + ''); // [ -1, -1, -1 ]
console.log(f([ 73, 50, 61 ] ) + ''); // [ 0, 1, -1 ]
console.log(f([ 941, 459, 533 ] ) + ''); // [ 1, 0, 0 ]
console.log(f([ 817, 19, 928, 177 ] ) + ''); // [ 1, -1, 1, 1 ]
console.log(f([ 312, 463, 336, 729, 513 ] ) + ''); // [ 0, -1, 0, 0, 0 ]
console.log(f([ 53, 47, 33, 87, 81, 3, 17 ] ) + ''); // [ 0, 0, 0, 1, 0, -1, 0 ]

J, 27 20 bytes

[:<@~.@}:@\:"1~2||/~


Try it online!

Uses [1 0] [1] [0] instead of 0 1 2

Explanation:

|/~ - makes a table with remainders:

  |/~ 73 50 61
0 50 61
23  0 11
12 50  0


2| odd or even? :

   2||/~ 73 50 61
0 0 1
1 0 1
0 0 0


<@~.@}:@\:"1 - sort down, drop last element (always a zero), keep the ùnique elements and box each row:

   <@~.@}:@\:"1~2||/~ 73 50 61
┌───┬─┬─┐
│1 0│1│0│
└───┴─┴─┘

• 16 bytes with 2/:~@:|"1]|1]\.] returning a list of pairs. Feb 7, 2018 at 13:56
• @ miles Thank you! Is this output acceptable? Feb 7, 2018 at 14:41
• Actually no, I missed that part about distinct values. I'll get back to it in a bit. Feb 7, 2018 at 14:55

Ruby, 58 56 bytes

->r{r.map{m=r.shift;s=r.map{|e|e%m%2}.uniq.sort;r<<m;s}}


Returns [0, 1], [1], [0] instead of 0, 1, 2 (i.e. [0] for all even , [1] for all odd, and [0, 1] for mixed).

Try it online!

Perl, 38 bytes

Includes +3 for -p

#!/usr/bin/perl -p
s/\d+/$@|=$_%$&%2+1for<$$'>;$@/gee


Outputs 1 for all even, 2 for all odd, 3 for mixed

Clean, 9565 63 bytes

import StdEnv

\l=[sum(removeDup[-1^(j rem i)\\j<-l|j<>i])\\i<-l]


Try it online!

As a lambda, taking [Int] and returning [Int], mapping to:

• 0: mixed
• 1: all even
• -1: all odd

Perl 5, 71 69 + 1 (-a) = 70 bytes

map{//;$j=$s='';$j++-$i&&($s+=$_%$'&1)for@F;say$s?0|$s==$#F:2;\$i++}@F


Try it online!

Pari/GP, 42 bytes

a->[[!s=vecsum([x%y%2|x<-a]),s>#a-2]|y<-a]


Returns [0, 0], [0, 1], [1, 0] instead of 0, 1, 2.

Try it online!

Java 8, 91 89 bytes

a->{for(int z:a){int s=1;for(int y:a)s+=y%z%2;System.out.print(" "+(s<a.length)+(s<2));}}

• Using truetrue instead of 2 for even
• Using falsefalse instead of 1 for odd
• Using truefalse instead of 0 for mixed

Explanation:

Try it online.

a->{                      // Method with integer-array parameter and no return-type
for(int z:a){           //  Loop over the array
int s=1;              //   Sum-integer, starting at 1
for(int y:a)          //   Inner loop over the array again
s+=y%z%2;           //    Increase the sum by y modulo-z modulo-2
System.out.print(" "  //   Print a space
+(s<a.length)       //    + "true" if the sum is smaller than the length of the array
//      (this means there is at least one even)
+(s<2));}}          //    + "true" if the sum is still 1
//      (this means all are even)


Clojure, 82 bytes

#(for[R[(range(count %))]i R](set(for[j R :when(not= i j)](odd?(mod(% j)(% i))))))


A complete example with output conversion:

(def f #(for[R[(range(count %))]i R](set(for[j R :when(not= i j)](odd?(mod(% j)(% i)))))))
(->> [ 53, 47, 33, 87, 81, 3, 17] f
(map {#{true} 1, #{false} 2, #{true false} 0}))
; (0 0 0 1 0 2 0)
`