const INPUT: &str = include_str!("../../data/day6"); #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug)] struct Answers { mask: u32, } impl Answers { fn parse(data: &str) -> Self { let data = data.trim(); let mask = data.chars().map(|c| { let c = c as u32; assert!(c < 0x80); let c = c as u8; assert!(c >= b'a' && c <= b'z'); let c = c - b'a'; c }).fold(0, |mask, bit| { mask | 1 << bit }); Self { mask } } fn count(&self) -> u32 { self.mask.count_ones() } } impl std::ops::BitOr for Answers { type Output = Self; fn bitor(self, rhs: Self) -> Self::Output { Self { mask: self.mask | rhs.mask } } } impl std::ops::BitAnd for Answers { type Output = Self; fn bitand(self, rhs: Self) -> Self::Output { Self { mask: self.mask & rhs.mask } } } struct Group { answers: Vec, } impl Group { fn parse(input: &str) -> Vec { input.split("\n\n").map(|block| { let answers = block.lines().map(Answers::parse).collect(); Group { answers } }).collect() } fn any_answered(&self) -> Answers { self.answers.iter().fold(Answers { mask: 0 }, |a, &b| a | b) } fn all_answered(&self) -> Answers { self.answers[1..].iter().fold(self.answers[0], |a, &b| a & b) } } fn main() { let groups = Group::parse(INPUT); println!( "Sum of questions answered yes at least one per group: {}", groups.iter().map(|g| g.any_answered().count()).sum::(), ); println!( "Sum of questions answered yes by everyone per group: {}", groups.iter().map(|g| g.all_answered().count()).sum::(), ); }