diff options
Diffstat (limited to '2022/src/day03.rs')
-rw-r--r-- | 2022/src/day03.rs | 62 |
1 files changed, 62 insertions, 0 deletions
diff --git a/2022/src/day03.rs b/2022/src/day03.rs new file mode 100644 index 0000000..7e245de --- /dev/null +++ b/2022/src/day03.rs @@ -0,0 +1,62 @@ +mod utils; + +use std::collections::HashSet; + +use utils::read_input; + +fn main() { + let input = read_input(); + + // Convert each line to a tuple of hashsets, one for each backpack pocket + let rucksack_items: Vec<_> = input + .lines() + .map(|line| (&line[..line.len() / 2], &line[line.len() / 2..])) + .map(|(a, b)| -> (HashSet<char>, HashSet<char>) { + (a.chars().collect(), b.chars().collect()) + }) + .collect(); + + let sum_error_priorities: u32 = rucksack_items + .iter() + .map(|(a, b)| { + *a.intersection(b) + .next() + .expect("no common item between two backpack segments!") + }) // Get common item + .map(priority) + .sum(); + + let sum_badge_priorities: u32 = rucksack_items // Construct chunked iterator + .iter() + .step_by(3) + .zip(rucksack_items.iter().skip(1).step_by(3)) + .zip(rucksack_items.iter().skip(2).step_by(3)) + .map(|(((e1l, e1r), (e2l, e2r)), (e3l, e3r))| { + for item in e1l.union(e1r) { + if (e2l.contains(item) || e2r.contains(item)) + && (e3l.contains(item) || e3r.contains(item)) + { + return *item; + } + } + panic!( + "group has no badge! {:?}", + ((e1l, e1r), (e2l, e2r), (e3l, e3r)) + ) + }) + .map(priority) + .sum(); + + println!("Part 1: {}", sum_error_priorities); + println!("Part 2: {}", sum_badge_priorities); +} + +fn priority(chr: char) -> u32 { + if chr.is_ascii_lowercase() { + chr as u32 - 96 + } else if chr.is_ascii_uppercase() { + chr as u32 - 38 + } else { + panic!("unrecognised item {}", chr) + } +} |