my solutions to advent of code
aoc advent-of-code
at main 3.1 kB view raw
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}