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