year2015/
day20.rs
1use utils::prelude::*;
2
3#[derive(Clone, Debug)]
5pub struct Day20 {
6 part1: u32,
7 part2: u32,
8}
9
10impl Day20 {
11 pub fn new(input: &str, _: InputType) -> Result<Self, InputError> {
12 let threshold: u32 = input
13 .trim_ascii_end()
14 .parse()
15 .map_err(|_| InputError::new(input, 0, "expected u32"))?;
16
17 for max_bound in [
20 threshold.div_ceil(40) + 1,
21 threshold.div_ceil(20) + 1,
22 threshold.div_ceil(10) + 1,
23 ] {
24 if let Some((part1, part2)) = Self::try_solve(threshold, max_bound) {
25 return Ok(Day20 { part1, part2 });
26 }
27 }
28
29 unreachable!();
30 }
31
32 fn try_solve(threshold: u32, len: u32) -> Option<(u32, u32)> {
33 let mut houses = vec![0; len as usize];
34
35 for elf in 1..len / 50 {
37 for house in (elf..len).step_by(elf as usize).take(50) {
38 houses[house as usize] += elf;
39 }
40 }
41
42 for elf in (len / 50).max(1)..len / 2 {
44 for house in (elf..len).step_by(elf as usize) {
45 houses[house as usize] += elf;
46 }
47 }
48
49 for elf in (len / 2).max(1)..len {
51 houses[elf as usize] += elf;
52 }
53
54 let part2_threshold = threshold.div_ceil(11);
55 let part2 = houses.iter().position(|&c| c >= part2_threshold)?;
56
57 for elf in 1..len / 50 {
59 for house in (elf * 51..len).step_by(elf as usize) {
60 houses[house as usize] += elf;
61 }
62 }
63
64 let part1_threshold = threshold.div_ceil(10);
65 let part1 = houses.iter().position(|&c| c >= part1_threshold)?;
66
67 Some((part1 as u32, part2 as u32))
68 }
69
70 #[must_use]
71 pub fn part1(&self) -> u32 {
72 self.part1
73 }
74
75 #[must_use]
76 pub fn part2(&self) -> u32 {
77 self.part2
78 }
79}
80
81examples!(Day20 -> (usize, usize) []);