You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

76 lines
1.5 KiB

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<Answers>,
}
impl Group {
fn parse(input: &str) -> Vec<Self> {
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::<u32>(),
);
println!(
"Sum of questions answered yes by everyone per group: {}",
groups.iter().map(|g| g.all_answered().count()).sum::<u32>(),
);
}