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, HashSet) { (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) } }