-
Notifications
You must be signed in to change notification settings - Fork 0
/
day24.rs
94 lines (84 loc) · 2.03 KB
/
day24.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
use std::fs;
use std::collections::HashSet;
enum Step {
E,
W,
SE,
SW,
NE,
NW,
}
fn parse_steps(s: &str) -> Vec<Step> {
let mut steps = vec![];
let mut it = s.chars();
while let Some(c) = it.next() {
match c {
'e' => steps.push(Step::E),
'w' => steps.push(Step::W),
_ => {
match (c,it.next()) {
('s',Some('e')) => steps.push(Step::SE),
('s',Some('w')) => steps.push(Step::SW),
('n',Some('e')) => steps.push(Step::NE),
('n',Some('w')) => steps.push(Step::NW),
_ => {
println!("Error: Unrecognised sequence");
}
}
}
}
}
steps
}
type Pos = (i32, i32);
fn step_dir(&(x, y): &Pos, dir: &Step) -> Pos {
match dir {
Step::E => (x+1, y),
Step::W => (x-1, y),
Step::NE => (x, y+1),
Step::SW => (x, y-1),
Step::NW => (x-1, y+1),
Step::SE => (x+1, y-1),
}
}
fn neighbours(pos: &Pos) -> Vec<Pos> {
let dirs = [Step::E, Step::W, Step::NE, Step::NW, Step::SE, Step::SW];
dirs.iter().map(|d| step_dir(pos, d)).collect()
}
fn get_blacks(xs: &Vec<Vec<Step>>) -> HashSet<Pos> {
let mut blacks = HashSet::new();
for steps in xs {
let mut pos = (0,0);
for s in steps { pos = step_dir(&pos, s) }
if !blacks.insert(pos) {
blacks.remove(&pos);
}
}
blacks
}
fn iter(blacks: &HashSet<Pos>) -> HashSet<Pos> {
blacks.iter()
.flat_map(neighbours)
.collect::<HashSet<_>>()
.into_iter()
.filter(|pos| {
let n = neighbours(&pos).into_iter()
.filter(|p| blacks.contains(p)).count();
if blacks.contains(&pos) { n == 1 || n == 2 }
else { n == 2 }
})
.collect()
}
fn part2(init: &HashSet<Pos>) -> usize {
let mut blacks = init.clone();
for _ in 0..100 { blacks = iter(&blacks); }
blacks.len()
}
fn main() {
let xs: Vec<Vec<Step>> =
fs::read_to_string("input/input24.txt").unwrap()
.lines().map(parse_steps).collect();
let blacks = get_blacks(&xs);
println!("Part 1: {}", blacks.len());
println!("Part 2: {}", part2(&blacks));
}