#![allow(dead_code)] #![allow(unused_variables)] #![allow(unused_mut)] use std::collections::HashSet; use std::env; use std::fs::File; use std::io::Read; fn run( mut pos: (i32, i32), m: &Vec>, ) -> (bool, HashSet<(i32, i32)>, HashSet<((i32, i32), (i32, i32))>) { let mut hs: HashSet<(i32, i32)> = HashSet::new(); let mut hs2: HashSet<((i32, i32), (i32, i32))> = HashSet::new(); let mut circ = false; let mut dir = [(0, -1), (1, 0), (0, 1), (-1, 0)]; loop { hs.insert(pos); hs2.insert((pos, dir[0])); let new_pos = (pos.0 + dir[0].0, pos.1 + dir[0].1); if hs2.contains(&(new_pos, dir[0])) { circ = true; break; } if new_pos.0 < 0 || new_pos.1 < 0 || new_pos.0 >= m[0].len().try_into().unwrap() || new_pos.1 >= m.len().try_into().unwrap() { break; } if m[new_pos.1 as usize][new_pos.0 as usize] { pos = new_pos; continue; } else { dir.rotate_left(1); } } return (circ, hs, hs2); } fn main() { let args: Vec = env::args().collect(); let filename = if args.len() == 1 { "in/".to_owned() + args[0].split('/').last().unwrap() + ".pzl" } else { args[1].clone() }; let mut f = File::open(filename).expect("cannot open file"); let mut content = String::new(); f.read_to_string(&mut content).expect("cannot read file"); let lines = content.trim_end().split("\n"); let mut pos: (i32, i32) = (0, 0); let mut m: Vec> = Vec::new(); for (y, line) in lines.enumerate() { let mut row = Vec::new(); for (x, c) in line.chars().enumerate() { row.push(if c == '#' { false } else { true }); if c == '^' { pos = (x.try_into().unwrap(), y.try_into().unwrap()); } } m.push(row); } let (circ, hs, hs2) = run(pos, &m); let res1 = hs.len(); let mut res2 = 0; for (x, y) in hs { let mut m2 = m.clone(); m2[y as usize][x as usize] = false; let (circ, hs, hs2) = run(pos, &m2); if circ { res2 += 1; } } println!("res1: {}", res1); println!("res2: {}", res2); assert_eq!(res1, 5531); assert_eq!(res2, 2165); }