1pub fn parse(input: &str) -> Vec<&[u8]> {
10 input.lines().map(str::as_bytes).collect()
11}
12
13pub fn part1(input: &[&[u8]]) -> u32 {
14 let mut gamma = 0;
15 let mut epsilon = 0;
16
17 for column in 0..input[0].len() {
18 let ones = ones(input, column);
19 let zeros = input.len() - ones;
20
21 gamma = (gamma << 1) | (ones > zeros) as u32;
22 epsilon = (epsilon << 1) | (zeros > ones) as u32;
23 }
24
25 gamma * epsilon
26}
27
28pub fn part2(input: &[&[u8]]) -> u32 {
29 let gamma = rating(input, |a, b| a >= b);
30 let epsilon = rating(input, |a, b| a < b);
31 gamma * epsilon
32}
33
34fn ones(numbers: &[&[u8]], i: usize) -> usize {
35 numbers.iter().filter(|b| b[i] == b'1').count()
36}
37
38fn rating(input: &[&[u8]], cmp: fn(usize, usize) -> bool) -> u32 {
39 let mut numbers = input.to_vec();
40 let mut column = 0;
41
42 while numbers.len() > 1 {
43 let ones = ones(&numbers, column);
44 let zeros = numbers.len() - ones;
45 let keep = if cmp(ones, zeros) { b'1' } else { b'0' };
46
47 numbers.retain(|n| n[column] == keep);
48 column += 1;
49 }
50
51 numbers[0].iter().fold(0, |acc, &n| (acc << 1) | (n == b'1') as u32)
52}