diff --git a/rs/src/y2022/d03.rs b/rs/src/y2022/d03.rs index 756baba..979797a 100644 --- a/rs/src/y2022/d03.rs +++ b/rs/src/y2022/d03.rs @@ -1,30 +1,48 @@ -use std::collections::HashSet; - -fn score(c: char) -> u32 { - match c { - 'a'..='z' => c as u32 - 'a' as u32 + 1, - 'A'..='Z' => c as u32 - 'A' as u32 + 27, +fn parse_item(c: char) -> u64 { + let n = match c { + 'a'..='z' => c as u64 - 'a' as u64, + 'A'..='Z' => c as u64 - 'A' as u64 + 26, _ => panic!(), - } + }; + 1 << n +} + +fn parse_items(s: &str) -> u64 { + s.chars().map(parse_item).reduce(|a, b| a | b).unwrap_or(0) +} + +// Returns the score of the item with the highest score +fn calc_score(i: u64) -> u32 { + 64 - i.leading_zeros() } pub fn solve(input: String) -> anyhow::Result<()> { - let backpacks = input - .lines() - .map(|l| l.trim()) - .map(|l| l.split_at(l.len() / 2)) - .collect::>(); + let backpacks = input.lines().map(|l| l.trim()).collect::>(); // Part 1 let score = backpacks .iter() - .map(|(l, r)| { - let l = l.chars().collect::>(); - let r = r.chars().collect::>(); - l.intersection(&r).map(|c| score(*c)).sum::() + .map(|backpack| { + let (l, r) = backpack.split_at(backpack.len() / 2); + calc_score(parse_items(l) & parse_items(r)) }) .sum::(); println!("Part 1: {score}"); + // Part 2 + let score = backpacks + .chunks(3) + .map(|chunk| { + calc_score( + chunk + .iter() + .map(|i| parse_items(i)) + .reduce(|a, b| a & b) + .unwrap(), + ) + }) + .sum::(); + println!("Part 2: {score}"); + Ok(()) }