use std::{fs, env, vec}; fn read_input(path: &str) -> String { return fs::read_to_string(path).expect("Cannot read file."); } fn parse_input(s: &str) -> Vec> { return s.lines() .map(|l| l.chars().filter_map(|e| e.to_digit(10)).collect()) .collect(); } fn compute_octopus(v: &mut Vec>, l: usize, c: usize, f: &mut Vec<(usize, usize)>) { v[l][c] += 1; if v[l][c] > 9 && !f.contains(&(l, c)) { f.push((l, c)); flash_around(v, l, c, f); } } fn flash_around(v: &mut Vec>, l: usize, c: usize, f: &mut Vec<(usize, usize)>) { for i in (l as i32 - 1)..=(l as i32 + 1) { for j in (c as i32 - 1)..=(c as i32 + 1) { let x = i as usize; let y = j as usize; if i >= 0 && x < v.len() && j >= 0 && y < v[x].len() { compute_octopus(v, x, y, f); } } } } fn apply_one_day(v: &mut Vec>) -> u32 { let mut f = vec![]; for l in 0..v.len() { for c in 0..v[l].len() { compute_octopus(v, l, c, &mut f); } } for l in 0..v.len() { for c in 0..v[l].len() { if v[l][c] > 9 { v[l][c] = 0; } } } return f.len() as u32; } fn apply_x_days(mut v: Vec>, x: u32) -> u32 { let mut n = 0; for _i in 0..x { n += apply_one_day(&mut v); } return n; } fn is_uniform(v: &Vec>) -> bool { if v.is_empty() || v[0].is_empty() { return true; } let x = v[0][0]; for l in v { for i in l { if *i != x { return false; } } } return true; } fn apply_while_not_synced(mut v: Vec>) -> u32 { let mut i = 0; while !is_uniform(&v) { apply_one_day(&mut v); i += 1; } return i; } fn main() { let args: Vec = env::args().collect(); for arg in args.iter().skip(1) { let input = read_input(&arg); let vec_in = parse_input(&input); println!("[{}]", &arg); println!("\t[Part 1] => Answer is '{}'.", apply_x_days(vec_in.clone(), 100)); println!("\t[Part 2] => Answer is '{}'.", apply_while_not_synced(vec_in)); } }