#![allow(dead_code)] #![allow(unused_variables)] #![allow(unused_mut)] use std::cmp::min; use std::fs::File; use std::io::Read; #[derive(Debug)] struct SeedMap { dest: u64, src: u64, len: u64, } fn do_map(val: u64, sms: &Vec) -> u64 { for sm in sms.iter() { if (sm.src <= val) && (val < sm.src + sm.len) { return val + sm.dest - sm.src; } } return val; } fn do_reverse_map(val: u64, sms: &Vec) -> u64 { for sm in sms.iter() { if (sm.dest <= val) && (val < sm.dest + sm.len) { return val + sm.src - sm.dest; } } return val; } fn main() { // let filename = "in/day05.ref"; let filename = "in/day05.pzl"; 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 mut chunks = content.trim_end().split("\n\n"); // println!("{:?}", chunks); let mut seeds: Vec = chunks .next() .unwrap() .split_once(":") .unwrap() .1 .split(" ") .filter_map(|x| x.parse().ok()) .collect::>(); let mut all_maps: Vec> = Vec::new(); for chunk in chunks { let mut chunk = chunk.split('\n'); let line = chunk.next(); let mut map_vec: Vec = Vec::new(); for line in chunk { let vals = line .split(" ") .filter_map(|x| x.parse().ok()) .collect::>(); map_vec.push(SeedMap { dest: vals[0], src: vals[1], len: vals[2], }); } all_maps.push(map_vec); } let mut res1 = 999999999999; for seed in seeds.clone().into_iter() { res1 = min(res1, all_maps.iter().fold(seed, |s, m| do_map(s, m))); } let seed_pairs: Vec<_> = seeds .chunks_exact(2) .map(|x| (x[0] as u64, x[1] as u64)) .collect(); let mut res2 = 0; for i in 0.. { let a = all_maps.iter().rev().fold(i, |s, m| do_reverse_map(s, m)); if seed_pairs .clone() .into_iter() .filter(|&(start, len)| (start <= a) && (a < start + len)) .next() .is_some() { res2 = i; break; } } println!("res1: {}", res1); println!("res2: {}", res2); assert_eq!(res1, 196167384); assert_eq!(res2, 125742456); }