15
\$\begingroup\$

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

Your task is to map each entry Ai to:

  • 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 ]
\$\endgroup\$
  • \$\begingroup\$ Related \$\endgroup\$ – Arnauld Feb 6 '18 at 17:33
  • \$\begingroup\$ Do the output values have to be integers or would [1], [0, 1], and [1, 1] work? \$\endgroup\$ – Dennis Feb 6 '18 at 18:33
  • \$\begingroup\$ @Dennis Any consistent values are fine. So yes, that would work! \$\endgroup\$ – Arnauld Feb 6 '18 at 18:40

15 Answers 15

9
\$\begingroup\$

Python 2, 68 67 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.

\$\endgroup\$
  • \$\begingroup\$ replace (k<1) with 0**k for -1 byte. \$\endgroup\$ – ovs Feb 6 '18 at 18:16
4
\$\begingroup\$

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.
\$\endgroup\$
  • \$\begingroup\$ Could you replace ‘ṬUḄ with Q€Ḅ to save a byte? \$\endgroup\$ – Jonathan Allan Feb 6 '18 at 18:25
  • \$\begingroup\$ Sadly, no. Q€ could return [0, 1] or [1, 0]. \$\endgroup\$ – Dennis Feb 6 '18 at 18:30
  • \$\begingroup\$ 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 :) \$\endgroup\$ – Jonathan Allan Feb 6 '18 at 18:55
  • \$\begingroup\$ Another 9 byte alternative is ¹-Ƥ%"%2‘Ṭ \$\endgroup\$ – miles Feb 7 '18 at 13:53
3
\$\begingroup\$

MATL, 12 bytes

!G\o~tAws1=-

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

Try it online! Or verify all test cases.

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
\$\endgroup\$
3
\$\begingroup\$

C (gcc), 118 114 97 92 91 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....
i,j,r;f(A,n)int*A;{for(i=~0;++i<n;putchar(r)){for(j=r=0;j<n;j++)j-i&&(r|=1<<A[j]%A[i]%2);}}

Try it online!

\$\endgroup\$
  • \$\begingroup\$ 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. \$\endgroup\$ – Peter Cordes Feb 7 '18 at 4:02
  • \$\begingroup\$ 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. \$\endgroup\$ – Peter Cordes Feb 7 '18 at 4:03
  • \$\begingroup\$ 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. \$\endgroup\$ – Peter Cordes Feb 7 '18 at 4:05
  • \$\begingroup\$ @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. \$\endgroup\$ – Jonathan Frech Feb 7 '18 at 12:06
  • \$\begingroup\$ @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=.... \$\endgroup\$ – Jonathan Frech Feb 7 '18 at 12:08
3
\$\begingroup\$

Mathematica, 57 49 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!

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

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
    ]
]
\$\endgroup\$
2
\$\begingroup\$

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 ]

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

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│
└───┴─┴─┘
\$\endgroup\$
  • 1
    \$\begingroup\$ 16 bytes with 2/:~@:|"1]|1]\.] returning a list of pairs. \$\endgroup\$ – miles Feb 7 '18 at 13:56
  • \$\begingroup\$ @ miles Thank you! Is this output acceptable? \$\endgroup\$ – Galen Ivanov Feb 7 '18 at 14:41
  • \$\begingroup\$ Actually no, I missed that part about distinct values. I'll get back to it in a bit. \$\endgroup\$ – miles Feb 7 '18 at 14:55
1
\$\begingroup\$

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!

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

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

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

Clean, 95 65 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
\$\endgroup\$
1
\$\begingroup\$

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!

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

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!

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

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)
\$\endgroup\$
0
\$\begingroup\$

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