Leveraging code that other people wrote is always a great idea. In this case, there is count_ones:
fn odd_ones(x: u32) -> bool {
x.count_ones() % 2 == 1
}
This method is a shim for the LLVM intrinsic @llvm.ctpop.i32, which seems likely to become the very optimized SSE4.2 popcnt instruction when available.
Beyond that, you have some poor indentation habits. Rust uses 4-space indents, not the 3 (?!?) spaces you have in your odd_ones function.
There should not be a space between a function name and the arguments, whether in the function definition or the function call. Your test method should be fixed.
Be consistent with your spacing on commas. No space before, one space after. |sum ,y| is just wrong.
You should give names to magic constants. A rogue 32 laying around doesn't mean anything. Give it a name like BITS_IN_U32. There's an unstable constant that you might be able to use someday.
When mapping and folding over an iterator, you might as well put all the mapping into the map call. There's no reason to do the bitwise-and in the fold.
I have no idea what !0 - 45345 is supposed to mean or why those particular values are useful. That's bad news when you try to understand this code in the future.
const BITS_IN_U32: usize = 32;
fn odd_ones(x: u32) -> bool {
x.count_ones() % 2 == 1
}
fn odd_ones_test(x: u32) -> bool {
let sum =
(0..BITS_IN_U32)
.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() {
println!("{}", test(!0 - 45345, !0));
}