#![allow(dead_code)] #![allow(unused_variables)] #![allow(unused_mut)] use std::collections::HashMap; use std::fs::File; use std::io::Read; fn is_symbol(c: char) -> bool { if c.is_digit(10) || c == '.' { false } else { true } } fn dydx() -> Vec<(i32, i32)> { let mut ret = Vec::new(); for y in -1i32..=1 { for x in -1i32..=1 { ret.push((y, x)); } } ret } fn main() { // let filename = "in/day03.ref"; let filename = "in/day03.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 lines: Vec<_> = content.trim_end().split('\n').collect(); // println!("{:?}", lines); let mut res1 = 0; let mut res2 = 0; let mut m: Vec> = Vec::new(); let pad: Vec<_> = (0..lines[0].bytes().len() + 2).map(|_| '.').collect(); m.push(pad.clone()); for line in &lines { let mut l: Vec = Vec::new(); l.push('.'); for c in line.bytes() { l.push(c as char) } l.push('.'); m.push(l) } m.push(pad.clone()); let mut hm: HashMap<(usize, usize), (u32, u32)> = HashMap::new(); let mut id: u32 = 0; for y in 1..m.len() - 1 { let mut have_num = false; let mut num_valid = false; let mut start_x = 0; for x in 1..m[0].len() { if have_num { if m[y][x].is_digit(10) == false { if num_valid { let num: u32 = String::from_iter(m[y][start_x..x].iter()).parse().unwrap(); for xx in start_x..x { hm.insert((xx, y), (id, num)); } id += 1; res1 += num; } have_num = false; num_valid = false; } } else if m[y][x].is_digit(10) { have_num = true; start_x = x; } if x == m[0].len() - 1 { continue; } if have_num { num_valid = num_valid || dydx() .into_iter() .map(|(dy, dx)| { is_symbol(m[((y as i32) + dy) as usize][((x as i32) + dx) as usize]) }) .any(|x| x); } } } for y in 0..m.len() { for x in 0..m[0].len() { if m[y][x] == '*' { let mut neighbour: HashMap = HashMap::new(); for (dy, dx) in dydx().into_iter() { let xx = ((x as i32) + dx) as usize; let yy = ((y as i32) + dy) as usize; if let Some((id, val)) = hm.get(&(xx, yy)) { neighbour.insert(*id, *val); } } if neighbour.len() == 2 { res2 += neighbour .iter() .map(|(_, val)| *val) .reduce(|a, b| a * b) .unwrap(); } } } } println!("res1: {}", res1); println!("res2: {}", res2); assert_eq!(res1, 532445); assert_eq!(res2, 79842967); }