-
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path18.rs
96 lines (86 loc) · 2.55 KB
/
18.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
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
/*
* Day 18: Boiling Boulders
* See [https://adventofcode.com/2022/day/18]
*/
use std::{collections::HashSet, ops::RangeInclusive};
fn parse_line(l: &str) -> (i32, i32, i32) {
let mut it = l.split(',').map(|x| x.parse::<i32>().unwrap());
(it.next().unwrap(), it.next().unwrap(), it.next().unwrap())
}
fn pt_neighbors(x: i32, y: i32, z: i32) -> [(i32, i32, i32); 6] {
[
(x + 1, y, z), (x - 1, y, z),
(x, y + 1, z), (x, y - 1, z),
(x, y, z + 1), (x, y, z - 1)
]
}
pub fn part_1(input: &str) -> Option<usize> {
let pts = input.lines().map(parse_line).collect::<Vec<_>>();
let mut cbs = HashSet::new();
for i in 0..pts.len() {
let (x1, y1, z1) = pts[i];
for j in i..pts.len() {
let (x2, y2, z2) = pts[j];
let a = match (x1 - x2, y1 - y2, z1 - z2) {
(1, 0, 0) => 0,
(0, 1, 0) => 1,
(0, 0, 1) => 2,
(-1, 0, 0) => 3,
(0, -1, 0) => 4,
(0, 0, -1) => 5,
_ => continue
};
cbs.insert((x1, y1, z1, a));
cbs.insert((x2, y2, z2, (a + 3) % 6));
}
}
Some(pts.len() * 6 - cbs.len())
}
// MANUALLY SET VALUES
const PT_RANGE: RangeInclusive<i32> = -1..=20;
pub fn part_2(input: &str) -> Option<u32> {
let ptset = input.lines().map(parse_line).collect::<HashSet<_>>();
let mut chpt = HashSet::from([(20, 20, 20)]);
let mut update = HashSet::new();
loop {
update.clear();
for cp in chpt.iter() {
let (x, y, z) = *cp;
for np in &pt_neighbors(x, y, z) {
if !ptset.contains(np) && !chpt.contains(np) {
let (nx, ny, nz) = *np;
if PT_RANGE.contains(&nx)
&& PT_RANGE.contains(&ny)
&& PT_RANGE.contains(&nz) {
update.insert(*np);
}
}
}
}
if update.is_empty() {
break;
}
chpt.extend(&update);
}
let mut cnt = 0;
for p in &ptset {
let (x, y, z) = *p;
for np in &pt_neighbors(x, y, z) {
if chpt.contains(np) {
cnt += 1;
}
}
}
println!("PTS: {}, CH: {}", ptset.len()*6, chpt.len());
Some(cnt)
}
aoc2022::solve!(part_1, part_2);
#[cfg(test)]
mod tests {
use aoc2022::assert_ex;
use super::*;
#[test]
fn test_part_1() { assert_ex!(part_1, 64); }
#[test]
fn test_part_2() { assert_ex!(part_2, 58); }
}