use nom::{ character::complete::{line_ending, satisfy}, combinator::map, multi::{many1, separated_list1}, IResult, }; use std::{collections::BTreeSet, fs, iter::Iterator}; fn main() -> Result<(), Box> { let input = fs::read_to_string("inputs/day_3.txt")?; let rucksacks = Rucksacks::parser(&input).unwrap().1; dbg!(rucksacks.disorder_sum()); dbg!(rucksacks.groups_sum()); Ok(()) } #[derive(Debug, PartialEq, Eq, Clone)] struct Rucksacks(Vec); #[derive(Debug, PartialEq, Eq, Clone)] struct Rucksack { front: BTreeSet, back: BTreeSet, } #[derive(Debug, PartialEq, Eq, Clone, PartialOrd, Ord)] struct ItemType(char); impl Rucksacks { fn parser(input: &str) -> IResult<&str, Rucksacks> { map(separated_list1(line_ending, Rucksack::parser), Rucksacks)(input) } fn disorder_sum(&self) -> u32 { self.0.iter().map(|r| r.intersection_priority()).sum() } fn groups_sum(&self) -> u32 { self.0 .chunks(3) .map(|group| { let mut overlap = group[0].union(); for m in group.iter().skip(1) { overlap = overlap.intersection(&m.union()).cloned().collect(); } overlap.iter().map(|c| c.priority()).sum::() }) .sum() } } impl Rucksack { fn parser(input: &str) -> IResult<&str, Rucksack> { map(many1(ItemType::parser), Rucksack::new)(input) } fn new(contents: Vec) -> Rucksack { let mid = contents.len() / 2; let front_str = &contents[0..mid]; let back_str = &contents[mid..]; let mut front = BTreeSet::new(); for c in front_str { front.insert(c.clone()); } let mut back = BTreeSet::new(); for c in back_str { back.insert(c.clone()); } Rucksack { front, back } } fn intersection(&self) -> BTreeSet { self.front.intersection(&self.back).cloned().collect() } fn union(&self) -> BTreeSet { self.front.union(&self.back).cloned().collect() } fn intersection_priority(&self) -> u32 { self.intersection().iter().map(|c| c.priority()).sum() } } impl ItemType { fn parser(input: &str) -> IResult<&str, ItemType> { map(satisfy(|c| c.is_alphabetic()), ItemType)(input) } fn priority(&self) -> u32 { if self.0.is_uppercase() { (self.0 as u32 - 'A' as u32) + 27 } else { (self.0 as u32 - 'a' as u32) + 1 } } }