forked from maneatingape/advent-of-code-rust
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathday21.rs
79 lines (64 loc) · 2.04 KB
/
day21.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
use crate::util::grid::*;
use crate::util::point::*;
use std::collections::VecDeque;
const CENTER: Point = Point::new(65, 65);
const CORNERS: [Point; 4] =
[Point::new(0, 0), Point::new(130, 0), Point::new(0, 130), Point::new(130, 130)];
type Input = (u64, u64);
pub fn parse(input: &str) -> Input {
let grid = Grid::parse(input);
let (even_inner, even_outer, odd_inner, odd_outer) = bfs(&grid, &[CENTER], 130);
let part_one = even_inner;
let even_full = even_inner + even_outer;
let odd_full = odd_inner + odd_outer;
let remove_corners = odd_outer;
let (even_inner, ..) = bfs(&grid, &CORNERS, 64);
let add_corners = even_inner;
let n = 202300;
let first = n * n * even_full;
let second = (n + 1) * (n + 1) * odd_full;
let third = n * add_corners;
let fourth = (n + 1) * remove_corners;
let part_two = first + second + third - fourth;
(part_one, part_two)
}
pub fn part1(input: &Input) -> u64 {
input.0
}
pub fn part2(input: &Input) -> u64 {
input.1
}
fn bfs(grid: &Grid<u8>, starts: &[Point], limit: u32) -> (u64, u64, u64, u64) {
let mut grid = grid.clone();
let mut todo = VecDeque::new();
let mut even_inner = 0;
let mut even_outer = 0;
let mut odd_inner = 0;
let mut odd_outer = 0;
for &start in starts {
grid[start] = b'#';
todo.push_back((start, 0));
}
while let Some((position, cost)) = todo.pop_front() {
if cost % 2 == 1 {
if position.manhattan(CENTER) <= 65 {
odd_inner += 1;
} else {
odd_outer += 1;
}
} else if cost <= 64 {
even_inner += 1;
} else {
even_outer += 1;
}
if cost < limit {
for next in ORTHOGONAL.map(|o| position + o) {
if grid.contains(next) && grid[next] != b'#' {
grid[next] = b'#';
todo.push_back((next, cost + 1));
}
}
}
}
(even_inner, even_outer, odd_inner, odd_outer)
}