1use utils::prelude::*;
2
3#[derive(Clone, Debug)]
5pub struct Day01 {
6 present: [bool; TARGET as usize + 1],
7 values: Vec<u32>,
8}
9
10const TARGET: u32 = 2020;
11
12impl Day01 {
13 pub fn new(input: &str, _: InputType) -> Result<Self, InputError> {
14 let mut present = [false; TARGET as usize + 1];
15 let mut values = Vec::with_capacity(1024);
16
17 for entry in parser::number_range(0..=TARGET)
18 .with_consumed()
19 .with_eol()
20 .parse_iterator(input)
21 {
22 let (num, line) = entry?;
23
24 if present[num as usize] {
25 return Err(InputError::new(input, line, "duplicate number"));
26 }
27 present[num as usize] = true;
28
29 if num < TARGET / 2 {
30 values.push(num);
31 }
32 }
33 values.sort_unstable();
34
35 Ok(Self { present, values })
36 }
37
38 #[must_use]
39 pub fn part1(&self) -> u64 {
40 for &a in &self.values {
41 let b = TARGET - a;
42 if self.present[b as usize] {
43 return u64::from(a) * u64::from(b);
44 }
45 }
46 panic!("no solution found")
47 }
48
49 #[must_use]
50 pub fn part2(&self) -> u64 {
51 for (i, &a) in self.values.iter().enumerate() {
52 for &b in &self.values[i + 1..] {
53 let c = TARGET - a - b;
54 if c <= b {
55 break;
56 }
57 if self.present[c as usize] {
58 return u64::from(a) * u64::from(b) * u64::from(c);
59 }
60 }
61 }
62 panic!("no solution found")
63 }
64}
65
66examples!(Day01 -> (u64, u64) [
67 {input: "1721\n979\n366\n299\n675\n1456", part1: 514579, part2: 241861950},
68]);