From 3c0e91576018bc9fe1cae0b4516038b56afcd27a Mon Sep 17 00:00:00 2001 From: Andy Teijelo Date: Sun, 3 Dec 2023 01:30:57 -0500 Subject: [PATCH] day 3 part 2 --- src/main.rs | 59 ++++++++++++++++++++++++++++++----------------------- 1 file changed, 34 insertions(+), 25 deletions(-) diff --git a/src/main.rs b/src/main.rs index a8710c1..e328a79 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,49 +1,50 @@ use anyhow::Result; use fancy_regex::Regex; -use std::io::stdin; +use std::{collections::HashMap, io::stdin}; -fn is_dot(x: i32, y: i32, lines: &[&[u8]]) -> bool { +fn is_gear(x: i32, y: i32, lines: &[&[u8]]) -> bool { if x < 0 { - return true; + return false; } if y < 0 { - return true; + return false; } if y as usize >= lines.len() { - return true; + return false; } let line = &lines[y as usize]; if x as usize >= line.len() { - return true; + return false; } - if line[x as usize] == b'.' { + if line[x as usize] == b'*' { return true; } false } -fn all_dots(x: i32, y: i32, len: i32, lines: &[&[u8]]) -> bool { - for cx in (x - 1)..=(x + len) { - if !is_dot(cx, y - 1, lines) { - return false; +fn find_gears(x: i32, y: i32, len: i32, lines: &[&[u8]]) -> Vec<(i32, i32)> { + let mut v = vec![]; + for cx in (x - 1)..(x + len) { + if is_gear(cx, y - 1, lines) { + v.push((cx, y - 1)); } } - for cx in (x - 1)..=(x + len) { - if !is_dot(cx, y + 1, lines) { - return false; + for cy in (y - 1)..=y { + if is_gear(x + len, cy, lines) { + v.push((x + len, cy)); } } - for cy in (y - 1)..=(y + 1) { - if !is_dot(x - 1, cy, lines) { - return false; + for cx in x..=(x + len) { + if is_gear(cx, y + 1, lines) { + v.push((cx, y + 1)); } } - for cy in (y - 1)..=(y + 1) { - if !is_dot(x + len, cy, lines) { - return false; + for cy in y..=(y + 1) { + if is_gear(x - 1, cy, lines) { + v.push((x - 1, cy)); } } - true + v } fn main() -> Result<()> { @@ -53,23 +54,31 @@ fn main() -> Result<()> { let lines: Vec = stdin().lines().map_while(Result::ok).collect(); let raw_lines: Vec<&[u8]> = lines.iter().map(|s| s.as_bytes()).collect(); + let mut gear_map: HashMap<(i32, i32), Vec> = HashMap::new(); + for (lineno, line) in lines.iter().enumerate() { for m in num_re.captures_iter(line) { let m = m?; let num_match = m.get(1).unwrap(); let num_text = num_match.as_str(); let num: i32 = num_text.parse()?; - println!("{lineno} {num} {} {}", num_match.start(), num_text.len()); - if !all_dots( + let gears = find_gears( num_match.start() as i32, lineno as i32, num_text.len() as i32, &raw_lines, - ) { - sum += num; + ); + for gear in gears { + let e = gear_map.entry(gear).or_default(); + e.push(num); } } } + for v in gear_map.values() { + if v.len() == 2 { + sum += v.iter().product::(); + } + } println!("{sum}");