1use utils::prelude::*;
2
3#[derive(Clone, Debug)]
5pub struct Day03 {
6 input: u32,
7}
8
9impl Day03 {
10 pub fn new(input: &str, _: InputType) -> Result<Self, InputError> {
11 Ok(Self {
12 input: parser::u32().parse_complete(input)?,
13 })
14 }
15
16 #[must_use]
17 pub fn part1(&self) -> u32 {
18 let ring = (self.input as f64).sqrt().ceil() as u32 / 2;
19 let side_length = ring * 2 + 1;
20 let bottom_right = side_length * side_length;
21 let middles = [
22 bottom_right - ring, bottom_right - (ring * 3), bottom_right - (ring * 5), bottom_right - (ring * 7), ];
27 let offset = middles
28 .iter()
29 .map(|m| m.abs_diff(self.input))
30 .min()
31 .unwrap();
32 ring + offset
33 }
34
35 #[must_use]
36 pub fn part2(&self) -> u64 {
37 const LEN: usize = 15;
41
42 let mut grid = [[0; LEN]; LEN];
43 let (mut x, mut y) = (LEN / 2, LEN / 2);
44 grid[x][y] = 1;
45
46 let mut turns = 0;
57 let mut steps = 1;
58
59 while grid[x][y] < self.input as u64 {
60 if steps == 0 {
61 turns += 1;
62 steps = (turns / 2) + 1;
63 }
64 steps -= 1;
65 match turns % 4 {
66 0 => x += 1,
67 1 => y += 1,
68 2 => x -= 1,
69 3 => y -= 1,
70 _ => unreachable!(),
71 }
72
73 grid[x][y] = grid[x - 1][y - 1]
74 + grid[x - 1][y]
75 + grid[x - 1][y + 1]
76 + grid[x][y - 1]
77 + grid[x][y + 1]
78 + grid[x + 1][y - 1]
79 + grid[x + 1][y]
80 + grid[x + 1][y + 1];
81 }
82
83 grid[x][y]
84 }
85}
86
87examples!(Day03 -> (u32, u64) [
88 {input: "1", part1: 0},
89 {input: "12", part1: 3},
90 {input: "23", part1: 2},
91 {input: "1024", part1: 31},
92 {input: "100", part2: 122},
94 {input: "200", part2: 304},
95 {input: "4294967295", part2: 4429173742},
96]);