/** Solution for Advent of Code 2022 day 3. * https://adventofcode.com/2022/day/3 */ use aoc2022::StdError; use std::collections::HashSet; use std::fs::File; use std::io::{BufRead, BufReader}; fn main() -> StdError<()> { // Open the input file and split all the lines. let lines: Vec<_> = BufReader::new(File::open("input/day3.txt")?) .lines() .collect::>()?; // "Short circuit" any Errors in the iterator let sum: u32 = lines .iter() .map(|l| { assert!(l.len() % 2 == 0); // We won't be able to evenly split a odd-length line! let (one, two) = (&l[0..l.len() / 2], &l[l.len() / 2..]); // Make sets out of the characters in each compartment... HashSet::::from_iter(one.chars()) // ... then calculate the intersection, giving us the "items" (chars) in common .intersection(&HashSet::from_iter(two.chars())) .map(|c| match c { // Now, we map our "items" to their "priorities". // Fortunately we can cast all chars to u32, which makes this a matter of some // simple arithmetic. 'a'..='z' => (*c as u32) - 'a' as u32 + 1, 'A'..='Z' => (*c as u32) - 'A' as u32 + 27, _ => panic!("Got non-ascii alphabetic char!"), }) .sum::() // Sum the priorities of items in common in each "rucksack" }) .sum(); // Sum all the rucksacks' priorities println!("Part 1: {}", sum); Ok(()) }