Friday, November 20, 2015

Binary parity

The fn odd_ones(x: u32) -> bool function should return true when x binary representation contains a odd number of 1s.
Assumption:
  1. x is 32 bit unsigned.
Restriction:
  1. The code should contain a total of at most 12 arithmetic, bitwise and logical operations.
Forbidden:
  1. Conditionals ,loops, function calls and macros.
  2. Division, modulus and multiplication.
  3. Relative comparison operators (<, >, <= and >=).
Allowed operations:
  1. All bit level and logic operations.
  2. Left and right shifts, but only with shift amounts between 0 and w - 1
  3. Addition and subtraction.
  4. Equality (==) and inequality (!=) tests.
  5. Casting between u32 and i32.

My code: (Rust playground)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
fn odd_ones(x: u32) -> bool { 
    let mid = (x >> 16) ^ x;
    let mid2 = (mid >> 8) ^ mid;
    let mid3 = (mid2 >> 4) ^ mid2;
    let mid4 = (mid3 >> 2) ^ mid3;
   
    (((mid4 >> 1) ^ mid4) & 1) == 1
}

fn alternative_odd_ones(x: u32) -> bool {
    const NUM_BITS_EXPONENT: u32 = 5;
    
    let bit = (0..NUM_BITS_EXPONENT).rev()
           .map(|y| 1 << y )
           .fold(x, |sum, y| (sum >> y) ^ sum );
    (bit & 1) == 1
}

fn odd_ones_test(x: u32) -> bool {    
    let sum = (0..32).map(|y| x >> y & 1)
                     .fold(0, |sum, y| sum + y);
    sum % 2 != 0
}

fn test (from: u32, to: u32) -> bool {
    (from..to).all(|x| odd_ones_test(x) == odd_ones(x))
}

fn main() {
    for x in (0..5).rev() { println!("{}", x);}
    println!("{}", test(!0 - 45345, !0));   
}