Skip to content

Instantly share code, notes, and snippets.

@neofight78
Last active December 20, 2021 09:27
Show Gist options
  • Save neofight78/3e62e7501508bb77c5575a7eaf3f7acc to your computer and use it in GitHub Desktop.
Save neofight78/3e62e7501508bb77c5575a7eaf3f7acc to your computer and use it in GitHub Desktop.
Advent of Code 2021 - Day 20: Trench Map
fn main() {
let (algorithm, mut image) = parse_input(INPUT);
let mut infinite_pixels = false;
for _ in 0..50 {
image = step(&algorithm, &image, &mut infinite_pixels);
}
println!("Pixels lit: {}", image.len());
}
fn parse_input(input: &str) -> (Vec<bool>, HashSet<(i64, i64)>) {
let (algorithm, image) = input.split_once("\n\n").unwrap();
let algorithm = algorithm.chars().map(|c| c == '#').collect();
let image = image
.lines()
.enumerate()
.flat_map(|(y, row)| {
row.chars()
.enumerate()
.filter(|(_, pixel)| *pixel == '#')
.map(move |(x, _)| (x as i64, y as i64))
})
.collect();
(algorithm, image)
}
fn step(
algorithm: &[bool],
image: &HashSet<(i64, i64)>,
infinite_pixels: &mut bool,
) -> HashSet<(i64, i64)> {
const VECTORS: [(i64, i64); 9] = [
(1, 1),
(0, 1),
(-1, 1),
(1, 0),
(0, 0),
(-1, 0),
(1, -1),
(0, -1),
(-1, -1),
];
let mut next = HashSet::new();
let min_x = image.iter().map(|c| c.0).min().unwrap();
let max_x = image.iter().map(|c| c.0).max().unwrap();
let min_y = image.iter().map(|c| c.1).min().unwrap();
let max_y = image.iter().map(|c| c.1).max().unwrap();
let get_pixel = |x: i64, y: i64| -> bool {
if x < min_x || x > max_x || y < min_y || y > max_y {
return *infinite_pixels;
}
image.contains(&(x, y))
};
for y in (min_y - 2)..=(max_y + 2) {
for x in (min_x - 2)..=(max_x + 2) {
let mut index = 0;
for (bit, vector) in VECTORS.iter().enumerate() {
if get_pixel(x + vector.0, y + vector.1) {
index |= 1 << bit;
}
}
if algorithm[index] {
next.insert((x, y));
}
}
}
*infinite_pixels = if *infinite_pixels {
algorithm[511]
} else {
algorithm[0]
};
next
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment