diff options
Diffstat (limited to '2024/day11.rs')
| -rw-r--r-- | 2024/day11.rs | 82 |
1 files changed, 82 insertions, 0 deletions
diff --git a/2024/day11.rs b/2024/day11.rs new file mode 100644 index 0000000..0730c5f --- /dev/null +++ b/2024/day11.rs @@ -0,0 +1,82 @@ +#![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<u64>) -> Vec<u64> { + let mut sn: Vec<u64> = 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, depth_end: u64, lut: &mut HashMap<(u64, u64), u64>) -> u64 { + if depth == depth_end { + return 1; + } + + if let Some(val) = lut.get(&(n, depth)) { + return *val; + } + + let sum = if n == 0 { + evolve_fast(1, depth + 1, depth_end, 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, depth_end, lut); + let b = evolve_fast(n % pow, depth + 1, depth_end, lut); + a + b + } else { + evolve_fast(n * 2024, depth + 1, depth_end, lut) + }; + + lut.insert((n, depth), sum); + + return sum; +} + +fn main() { + let args: Vec<String> = 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<u64> = 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 hm = HashMap::new(); + for n in s2 { + res2 += evolve_fast(n, 0, 75, &mut hm); + } + + println!("res1: {}", res1); + println!("res2: {}", res2); + assert_eq!(res1, 220722); + assert_eq!(res2, 261952051690787); +} |
