#![allow(dead_code)] #![allow(unused_variables)] #![allow(unused_mut)] use std::fs::File; use std::io::Read; fn hash(s: &str) -> usize { let mut h: usize = 0; for b in s.bytes() { h = ((h + (b as usize)) * 17) % 256; } h } #[derive(Debug, PartialEq, Clone)] struct Lens { name: String, h: usize, f: Option, } fn main() { // let filename = "in/day15.ref"; let filename = "in/day15.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 token = content.trim_end().split(','); let mut ls: Vec = Vec::new(); let mut res1: usize = 0; for t in token { res1 += hash(t); if t.contains('=') { let (n, f) = t.split_once('=').unwrap(); ls.push(Lens { name: n.to_owned(), h: hash(n), f: Some(f.parse().unwrap()), }); } else { let n = t.trim_end_matches('-'); ls.push(Lens { name: n.to_owned(), h: hash(n), f: None, }); } } let mut hm: Vec> = vec![[].to_vec(); 256]; for l in ls { if let Some(f) = l.f { let mut found = false; for ll in 0..hm[l.h].len() { if hm[l.h][ll].name == l.name { hm[l.h][ll].f = l.f; found = true; break; } } if !found { hm[l.h].push(l); } } else { hm[l.h].retain(|x| x.name != l.name); } } let mut res2 = 0; for b in 0..hm.len() { for l in 0..hm[b].len() { res2 += (b + 1) * (l + 1) * hm[b][l].f.unwrap(); } } println!("res1: {}", res1); println!("res2: {}", res2); assert_eq!(res1, 506437); assert_eq!(res2, 288521); }