diff options
Diffstat (limited to '2023/day15.rs')
| -rw-r--r-- | 2023/day15.rs | 84 |
1 files changed, 84 insertions, 0 deletions
diff --git a/2023/day15.rs b/2023/day15.rs new file mode 100644 index 0000000..5c6bde7 --- /dev/null +++ b/2023/day15.rs @@ -0,0 +1,84 @@ +#![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<usize>, +} + +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<Lens> = 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<Lens>> = 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); +} |
