use std::fs; fn solve_puzzle(first: &str, num_rows: usize) -> usize { let mut total = first.matches('.').count(); let mut tiles: Vec = first.chars().collect(); for _i in 1..num_rows { let mut next = Vec::new(); for j in 0..tiles.len() { let is_trap; // At left wall if j == 0 { is_trap = tiles[j + 1] == '^'; // rule 2 + 4 // At right wall } else if j == tiles.len() - 1 { is_trap = tiles[j - 1] == '^'; // rule 1 + 3 // Away from the walls } else { is_trap = tiles[j - 1] == '^' && tiles[j + 1] == '.' // rule 1 + 3 || tiles[j - 1] == '.' && tiles[j + 1] == '^'; // rule 2 + 4 } next.push(if is_trap { '^' } else { '.' }); } tiles = next; total += tiles.iter().filter(|&c| *c == '.').count(); } total } fn main() { // Read my personal puzzle input let input = fs::read_to_string("input.txt").unwrap(); let first = input.trim_end(); // Part 1 gives 1939 for me println!("Part 1 solution: {}", solve_puzzle(first, 40)); // Part 2 gives 19999535 for me println!("Part 1 solution: {}", solve_puzzle(first, 400000)); } #[cfg(test)] mod tests { use super::*; #[test] fn part1_example1() { let input = "..^^."; assert_eq!(solve_puzzle(input, 3), 6); } #[test] fn part1_example2() { let input = ".^^.^.^^^^"; assert_eq!(solve_puzzle(input, 10), 38); } }