use std::collections::HashSet; use std::error::Error; use std::fs::File; use std::io::{self, BufRead}; use std::vec::Vec; fn prio(c: &char) -> u32 { if *c >= 'a' && *c <= 'z' { 1 + *c as u32 - 'a' as u32 } else if *c >= 'A' && *c <= 'Z' { 27 + *c as u32 - 'A' as u32 } else { 0u32 } } fn main() -> Result<(), Box> { let file = File::open("inputs/day3.txt")?; let lines = io::BufReader::new(file).lines().map(|l| l.unwrap()); let backpacks: Vec<(HashSet, HashSet)> = lines .map(|l| { let middle = l.len() / 2; let compartment1: HashSet = l[0..middle].chars().collect(); let compartment2: HashSet = l[middle..].chars().collect(); (compartment1, compartment2) }) .collect(); let mut answer1 = 0; for (comp1, comp2) in backpacks.iter() { let in_both = comp1.intersection(&comp2).nth(0).unwrap(); answer1 += prio(in_both); } println!("Answer Part1: {}", answer1); let mut answer2 = 0; for group in backpacks.chunks(3) { let backpack1: HashSet = group[0] .0 .union(&group[0].1) .map(|c| c.to_owned()) .collect(); let backpack2: HashSet = group[1] .0 .union(&group[1].1) .map(|c| c.to_owned()) .collect(); let backpack3: HashSet = group[2] .0 .union(&group[2].1) .map(|c| c.to_owned()) .collect(); let in_both: HashSet = backpack1 .intersection(&backpack2) .map(|c| c.to_owned()) .collect(); let in_all = backpack3.intersection(&in_both).nth(0).unwrap(); answer2 += prio(in_all); } println!("Answer Part2: {}", answer2); Ok(()) }