my solutions to advent of code
aoc
advent-of-code
1use std::mem::swap;
2
3fn generations(times: u32, mut world: Vec<u8>, size: usize, stuck: bool) -> Vec<u8> {
4 let pos = |x, y| y * (size + 2) + x;
5
6 let sizep = size + 1;
7
8 let mut new_world = vec![0_u8; (size + 2).pow(2)];
9
10 unsafe {
11 if stuck {
12 *world.get_unchecked_mut(pos(1, 1)) = 1;
13 *world.get_unchecked_mut(pos(size, 1)) = 1;
14 *world.get_unchecked_mut(pos(1, size)) = 1;
15 *world.get_unchecked_mut(pos(size, size)) = 1;
16 }
17 }
18
19 for _ in 0..times {
20 for yo in 1..sizep {
21 let ym = yo - 1;
22 let yp = yo + 1;
23 for xo in 1..sizep {
24 let xm = xo - 1;
25 let xp = xo + 1;
26
27 unsafe {
28 let was = *world.get_unchecked(pos(xo, yo)) == 1_u8;
29 let neighbours = world.get_unchecked(pos(xm, ym))
30 + world.get_unchecked(pos(xo, ym))
31 + world.get_unchecked(pos(xp, ym))
32 + world.get_unchecked(pos(xm, yo))
33 + world.get_unchecked(pos(xp, yo))
34 + world.get_unchecked(pos(xm, yp))
35 + world.get_unchecked(pos(xo, yp))
36 + world.get_unchecked(pos(xp, yp));
37 *new_world.get_unchecked_mut(pos(xo, yo)) =
38 (neighbours == 3 || (neighbours == 2 && was)) as u8;
39 }
40 }
41 }
42
43 swap(&mut world, &mut new_world);
44
45 // i hate the duplication here :(
46 unsafe {
47 if stuck {
48 *world.get_unchecked_mut(pos(1, 1)) = 1;
49 *world.get_unchecked_mut(pos(size, 1)) = 1;
50 *world.get_unchecked_mut(pos(1, size)) = 1;
51 *world.get_unchecked_mut(pos(size, size)) = 1;
52 }
53 }
54 }
55 world
56}
57
58fn main() {
59 let input = include_str!("../../input.txt").trim();
60 let size = input.split_once("\n").expect("invalid input").0.len();
61 // reads the input but adds a line of buffer on the sides
62 let buffer_line = ".".repeat(size);
63 let input: Vec<u8> = format!("{buffer_line}\n{input}\n{buffer_line}")
64 .split("\n")
65 .map(|line| -> Vec<u8> {
66 format!(".{}.", line)
67 .chars()
68 .map(|v| (v == '#') as u8)
69 .collect()
70 })
71 .flatten()
72 .collect();
73
74 let part_1 = generations(100, input.clone(), size, false)
75 .iter()
76 .filter(|v| **v == 1)
77 .count();
78 println!("Part 1: {}", part_1);
79
80 let part_2 = generations(100, input.clone(), size, true)
81 .iter()
82 .filter(|v| **v == 1)
83 .count();
84 println!("Part 2: {}", part_2);
85}