fn solve_part1(input: &str) -> u32 { let (report, bit_len) = parse_input(input); let mut gamma: u32 = 0; for i in 0..bit_len { let count = report.iter().filter(|v| **v >> i & 0x01 == 0x01).count(); if count > report.len() - count { gamma |= 1 << i } else { gamma &= !(1 << i) } } gamma * (!gamma & ((1 << bit_len) - 1)) } fn solve_part2(input: &str) -> u32 { let (oxy_gen, bit_len) = parse_input(input); let co2_gen = oxy_gen.clone(); let left = part2_logic(oxy_gen, bit_len, true); let right = part2_logic(co2_gen, bit_len, false); left * right } fn part2_logic(mut gen: Vec, bit_len: usize, is_oxy: bool) -> u32 { for i in 0..bit_len { if gen.len() < 2 { break; } let count = gen .iter() .filter(|v| **v >> (bit_len - 1 - i) & 0x01 == 0x01) .count(); let common = (count >= gen.len() - count) as u16; let needle = if is_oxy { 1 - common } else { common }; gen.retain(|v| *v >> (bit_len - 1 - i) & 0x01 == needle); } gen[0] as u32 } fn parse_input(input: &str) -> (Vec, usize) { let mut it = input.lines().peekable(); let size = it.peek().expect("1 > &str exists").len(); let report = it.flat_map(|s| u16::from_str_radix(s, 2).ok()).collect(); (report, size) } pub fn run(input: String) { println!("--- Part 1 ---"); println!("Answer: {}", solve_part1(&input)); println!(); println!("--- Part 2 ---"); println!("Answer: {}", solve_part2(&input)) } #[cfg(test)] mod tests { const EXAMPLE_INPUT: &str = "00100\n11110\n10110\n10111\n10101\n01111\n00111\n11100\n10000\n11001\n00010\n01010"; #[test] fn part1() { assert_eq!(super::solve_part1(EXAMPLE_INPUT), 198); } #[test] fn part2() { assert_eq!(super::solve_part2(EXAMPLE_INPUT), 230); } }