my solutions to advent of code
aoc
advent-of-code
1use std::{
2 fs::{self, File},
3 io::Write,
4 mem::swap,
5};
6
7fn to_img(warehouse: &Vec<u8>, size: usize, name: usize) {
8 let mut bytes: Vec<u8> = [].to_vec();
9 bytes.extend(format!("P5\n{size} {size}\n1\n").as_bytes());
10 let mut i = size + 3;
11 for _ in 0..size {
12 for _ in 0..size {
13 bytes.push(*warehouse.get(i).unwrap());
14 i += 1;
15 }
16 i += 2;
17 }
18 let mut file = File::create(format!("out/{name}.pgm")).unwrap();
19 file.write_all(&bytes).unwrap();
20}
21
22fn solve(
23 mut warehouse: Vec<u8>,
24 size: usize,
25 part_2: bool,
26 visualise: bool,
27) -> u32 {
28 if visualise {
29 fs::create_dir_all("out").unwrap();
30 }
31
32 let pos = |x, y| y * (size + 2) + x;
33
34 let sizep = size + 1;
35
36 let mut new_warehouse = vec![0_u8; (size + 2).pow(2)];
37
38 let mut rolls = 0;
39
40 let mut i = 0;
41 loop {
42 for yo in 1..sizep {
43 let ym = yo - 1;
44 let yp = yo + 1;
45 for xo in 1..sizep {
46 let xm = xo - 1;
47 let xp = xo + 1;
48
49 unsafe {
50 let was = *warehouse.get_unchecked(pos(xo, yo)) == 1;
51 let neighbours = warehouse.get_unchecked(pos(xm, ym))
52 + warehouse.get_unchecked(pos(xo, ym))
53 + warehouse.get_unchecked(pos(xp, ym))
54 + warehouse.get_unchecked(pos(xm, yo))
55 + warehouse.get_unchecked(pos(xp, yo))
56 + warehouse.get_unchecked(pos(xm, yp))
57 + warehouse.get_unchecked(pos(xo, yp))
58 + warehouse.get_unchecked(pos(xp, yp));
59 *new_warehouse.get_unchecked_mut(pos(xo, yo)) =
60 match (was, neighbours < 4) {
61 (true, true) => {
62 rolls += 1;
63 0
64 }
65 (true, false) => 1,
66 (_, _) => 0,
67 };
68 }
69 }
70 }
71
72 if !part_2 || warehouse == new_warehouse {
73 break;
74 }
75
76 swap(&mut warehouse, &mut new_warehouse);
77 i += 1;
78 if visualise {
79 to_img(&warehouse, size, i);
80 }
81 }
82 rolls
83}
84
85fn main() {
86 let input = include_str!("../../input.txt").trim();
87 let size = input.split_once("\n").expect("invalid input").0.len();
88 // reads the input but adds a line of buffer on the sides
89 let buffer_line = ".".repeat(size);
90 let input: Vec<u8> = format!("{buffer_line}\n{input}\n{buffer_line}")
91 .split("\n")
92 .map(|line| -> Vec<u8> {
93 format!(".{}.", line)
94 .chars()
95 .map(|v| (v == '@') as u8)
96 .collect()
97 })
98 .flatten()
99 .collect();
100
101 let part_1 = solve(input.clone(), size, false, false);
102 println!("Part 1: {}", part_1);
103
104 let part_2 = solve(input.clone(), size, true, true);
105 println!("Part 2: {}", part_2);
106}