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