-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path20.rs
77 lines (69 loc) · 1.86 KB
/
20.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
#![feature(test)]
use rustc_hash::FxHashSet;
struct Input {
algo: Vec<bool>,
width: usize,
height: usize,
grid: FxHashSet<(i32, i32)>,
}
fn setup(input: &str) -> Input {
let mut lines = input.lines();
let algo = lines.next().unwrap().chars().map(|c| c == '#').collect();
let grid = lines
.skip(1)
.enumerate()
.flat_map(|(i, line)| {
line.chars().enumerate().filter_map(move |(j, c)| {
if c == '#' {
Option::Some((j as i32, i as i32))
} else {
Option::None
}
})
})
.collect();
Input {
algo,
grid,
width: input.lines().nth(2).unwrap().len(),
height: input.lines().count() - 2,
}
}
fn get_neighbors(x: i32, y: i32) -> Vec<(i32, i32)> {
(-1..=1)
.flat_map(|dy| (-1..=1).map(move |dx| (x + dx, y + dy)))
.collect()
}
fn solve(input: &Input) -> (usize, usize) {
let mut grid = input.grid.clone();
let mut inf = false;
let mut part1 = 0;
let mut part2 = 0;
for i in 1..=50 {
let new_inf = inf != input.algo[0];
grid = (-i..=input.height as i32 + i)
.flat_map(|y| (-i..=input.width as i32 + i).map(move |x| (x, y)))
.filter(|(x, y)| {
let idx = get_neighbors(*x, *y).iter().fold(0, |acc, (p, q)| {
acc << 1 | (grid.contains(&(*p, *q)) != inf) as usize
});
input.algo[idx] != new_inf
})
.collect();
inf = new_inf;
if i == 2 {
part1 = grid.len();
}
if i == 50 {
part2 = grid.len();
}
}
(part1, part2)
}
fn part1(input: &Input) -> usize {
solve(input).0
}
fn part2(input: &Input) -> usize {
solve(input).1
}
aoc::main!(2021, 20, ex: 1);