Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
epidemian
GitHub Repository: epidemian/advent-of-code-2021
Path: blob/main/src/day20.rs
97 views
1
pub fn run() {
2
let (enhancement_algo, input_image) = include_str!("inputs/day20").split_once("\n\n").unwrap();
3
let enhancement_algo: Vec<_> = enhancement_algo.chars().map(|ch| ch == '#').collect();
4
let input_image: Image = input_image
5
.lines()
6
.map(|l| l.chars().map(|ch| ch == '#').collect())
7
.collect();
8
9
let steps = 50;
10
let mut image = extend(&input_image, steps);
11
12
for n in 1..=steps {
13
image = enhance(&image, &enhancement_algo);
14
if n == 2 || n == 50 {
15
println!("{}", count_lit_pixels(&image));
16
}
17
}
18
}
19
20
type Image = Vec<Vec<bool>>;
21
22
fn extend(image: &Image, steps: usize) -> Image {
23
let size = image.len();
24
let extended_size = size + (steps + 1) * 2;
25
let mut extended_image = vec![vec![false; extended_size]; extended_size];
26
27
for y in 0..size {
28
for x in 0..size {
29
extended_image[y + steps + 1][x + steps + 1] = image[y][x];
30
}
31
}
32
extended_image
33
}
34
35
fn enhance(image: &Image, enhancement_algo: &Vec<bool>) -> Image {
36
let size = image.len();
37
let bit_at = |y: usize, x: usize| image[y][x] as usize;
38
39
let enhanced_border_value = enhancement_algo[if image[0][0] { 511 } else { 0 }];
40
let mut enhanced_image = vec![vec![enhanced_border_value; size]; size];
41
42
for y in 1..size - 1 {
43
for x in 1..size - 1 {
44
let index = 0
45
| bit_at(y - 1, x - 1) << 8
46
| bit_at(y - 1, x) << 7
47
| bit_at(y - 1, x + 1) << 6
48
| bit_at(y, x - 1) << 5
49
| bit_at(y, x) << 4
50
| bit_at(y, x + 1) << 3
51
| bit_at(y + 1, x - 1) << 2
52
| bit_at(y + 1, x) << 1
53
| bit_at(y + 1, x + 1);
54
enhanced_image[y][x] = enhancement_algo[index];
55
}
56
}
57
enhanced_image
58
}
59
60
fn count_lit_pixels(image: &Image) -> usize {
61
image
62
.iter()
63
.map(|line| line.iter().filter(|px| **px).count())
64
.sum()
65
}
66
67