Skip to content

Commit 2b7dfaa

Browse files
committed
2017 day 3
1 parent 32fa300 commit 2b7dfaa

File tree

2 files changed

+97
-0
lines changed

2 files changed

+97
-0
lines changed

crates/year2017/src/day03.rs

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
use utils::prelude::*;
2+
3+
/// Calculating spiral patterns.
4+
#[derive(Clone, Debug)]
5+
pub struct Day03 {
6+
input: u32,
7+
}
8+
9+
impl 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
23+
bottom_right - (ring * 3), // Left
24+
bottom_right - (ring * 5), // Top
25+
bottom_right - (ring * 7), // Right
26+
];
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+
// To cover 0..=u32::MAX only the first 150 values in the sequence are necessary. The 150th
38+
// value is in the 6th ring, meaning a grid of 13x13 is required, or 15x15 with an extra
39+
// ring around the edge to avoid needing bounds checks.
40+
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+
// Store the number of turns and remaining steps until the next turn. The number of previous
47+
// turns gives you the current direction and next number of steps by following the pattern:
48+
// 1x Right
49+
// 1x Up
50+
// 2x Left
51+
// 2x Down
52+
// 3x Right
53+
// 3x Up
54+
// 4x Left
55+
// ...
56+
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+
87+
examples!(Day03 -> (u32, u64) [
88+
{input: "1", part1: 0},
89+
{input: "12", part1: 3},
90+
{input: "23", part1: 2},
91+
{input: "1024", part1: 31},
92+
// Custom examples
93+
{input: "100", part2: 122},
94+
{input: "200", part2: 304},
95+
{input: "4294967295", part2: 4429173742},
96+
]);

crates/year2017/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,5 @@
44
utils::year!(2017 => year2017, ${
55
1 => day01::Day01<'_>,
66
2 => day02::Day02,
7+
3 => day03::Day03,
78
});

0 commit comments

Comments
 (0)