#![allow(dead_code)] #![allow(unused_variables)] #![allow(unused_mut)] use std::collections::HashMap; use std::env; use std::fs::File; use std::io::Read; fn evolve(s: &Vec) -> Vec { let mut sn: Vec = Vec::new(); for n in s { if *n == 0 { sn.push(1); } else if n.checked_ilog(10).unwrap() % 2 == 1 { let pow = 10_u64.pow(n.checked_ilog(10).unwrap() / 2 + 1); sn.push(n / pow); sn.push(n % pow); } else { sn.push(n * 2024); } } return sn; } fn evolve_fast(n: u64, depth: u64, lut: &mut HashMap<(u64, u64), u64>) -> u64 { if depth == 0 { return 1; } if let Some(val) = lut.get(&(n, depth)) { return *val; } let val = if n == 0 { evolve_fast(1, depth - 1, lut) } else if n.checked_ilog(10).unwrap() % 2 == 1 { let pow = 10_u64.pow(n.checked_ilog(10).unwrap() / 2 + 1); let a = evolve_fast(n / pow, depth - 1, lut); let b = evolve_fast(n % pow, depth - 1, lut); a + b } else { evolve_fast(n * 2024, depth - 1, lut) }; lut.insert((n, depth), val); return val; } 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 line = content.trim_end().split("\n").next().unwrap(); let stones: Vec = line.split(" ").map(|a| a.parse().unwrap()).collect(); let mut s = stones.clone(); for i in 0..25 { s = evolve(&s); } let res1 = s.len(); let mut s2 = stones.clone(); let mut res2 = 0; let mut lut = HashMap::new(); for n in s2 { res2 += evolve_fast(n, 75, &mut lut); } println!("res1: {}", res1); println!("res2: {}", res2); assert_eq!(res1, 220722); assert_eq!(res2, 261952051690787); }