/ Rust / 2023 / 04.rs
04.rs
 1  #![feature(test)]
 2  
 3  use std::collections::VecDeque;
 4  
 5  use rustc_hash::FxHashSet;
 6  
 7  type Input = Vec<Card>;
 8  
 9  #[derive(Debug)]
10  struct Card {
11      winning: FxHashSet<u32>,
12      mine: FxHashSet<u32>,
13  }
14  
15  impl Card {
16      fn matches(&self) -> usize {
17          self.winning.intersection(&self.mine).count()
18      }
19  
20      fn points(&self) -> usize {
21          let matches = self.matches();
22          if matches >= 1 {
23              2usize.pow(matches as u32 - 1)
24          } else {
25              0
26          }
27      }
28  }
29  
30  fn setup(input: &str) -> Input {
31      input
32          .lines()
33          .map(|line| {
34              let mut line = line.split(':').nth(1).unwrap().split('|');
35              let mut nums = || {
36                  line.next()
37                      .unwrap()
38                      .split_whitespace()
39                      .map(|n| n.parse().unwrap())
40                      .collect()
41              };
42              Card {
43                  winning: nums(),
44                  mine: nums(),
45              }
46          })
47          .collect()
48  }
49  
50  fn part1(input: &Input) -> usize {
51      input.iter().map(Card::points).sum()
52  }
53  
54  fn part2(input: &Input) -> usize {
55      let mut counts = VecDeque::from(vec![1; input.len()]);
56      input
57          .iter()
58          .map(|card| {
59              let n = counts.pop_front().unwrap();
60              counts
61                  .iter_mut()
62                  .take(card.matches())
63                  .for_each(|cnt| *cnt += n);
64              n
65          })
66          .sum()
67  }
68  
69  aoc::main!(2023, 4, ex: 1);