From 4a8c1d460df08d963059753e84d33067d8bb96b2 Mon Sep 17 00:00:00 2001 From: Rekai Musuka Date: Fri, 3 Dec 2021 04:59:44 -0400 Subject: [PATCH] feat: complete day 3 --- rust/2021/src/day_03.rs | 61 ++++++++++++++++++++++++++++++++++++----- 1 file changed, 54 insertions(+), 7 deletions(-) diff --git a/rust/2021/src/day_03.rs b/rust/2021/src/day_03.rs index 9c4c1ee..7e8639f 100644 --- a/rust/2021/src/day_03.rs +++ b/rust/2021/src/day_03.rs @@ -1,9 +1,55 @@ -fn solve_part1(input: &str) -> i32 { - todo!(); +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) -> i32 { - todo!(); +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) { @@ -16,15 +62,16 @@ pub fn run(input: String) { #[cfg(test)] mod tests { - const EXAMPLE_INPUT: &str = todo!(); + const EXAMPLE_INPUT: &str = + "00100\n11110\n10110\n10111\n10101\n01111\n00111\n11100\n10000\n11001\n00010\n01010"; #[test] fn part1() { - todo!(); + assert_eq!(super::solve_part1(EXAMPLE_INPUT), 198); } #[test] fn part2() { - todo!(); + assert_eq!(super::solve_part2(EXAMPLE_INPUT), 230); } }