advent_of_code/year2020/
day06.rs1use crate::input::Input;
2use std::ops::{BitAnd, BitOr};
3
4type AnswersBitSet = u32;
5
6fn person_answers_to_bit_set(answers: &str) -> AnswersBitSet {
12 answers
13 .bytes()
14 .map(|question_identifier| 1 << (question_identifier - b'a'))
15 .sum::<AnswersBitSet>()
16}
17
18pub fn solve(input: &Input) -> Result<AnswersBitSet, String> {
19 const GROUP_SEPARATOR: &str = "\n\n";
20
21 if !input.text.bytes().all(|b| matches!(b, b'a'..=b'z' | b'\n')) {
22 return Err("Invalid input - only a-z, \\n expected".to_string());
23 }
24
25 let initial_bit_set = input.part_values(0, AnswersBitSet::MAX);
26
27 let bit_set_merger = if input.is_part_one() {
28 BitOr::bitor
29 } else {
30 BitAnd::bitand
31 };
32
33 let computer = |text: &str| {
34 Ok(text
35 .split(GROUP_SEPARATOR)
36 .map(|group_answers| {
37 group_answers
38 .lines()
39 .map(person_answers_to_bit_set)
40 .fold(initial_bit_set, bit_set_merger)
41 .count_ones()
42 })
43 .sum())
44 };
45
46 computer(input.text)
47}
48
49#[test]
50pub fn tests() {
51 test_part_one_no_allocations!("abc\n\nabc" => 6);
52
53 let real_input = include_str!("day06_input.txt");
54 test_part_one_no_allocations!(real_input => 6686);
55 test_part_two_no_allocations!(real_input => 3476);
56}