day 3 part 2

This commit is contained in:
Andy Teijelo 2023-12-03 01:30:57 -05:00
parent 51ca0433f8
commit 3c0e915760

View file

@ -1,49 +1,50 @@
use anyhow::Result; use anyhow::Result;
use fancy_regex::Regex; 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 { if x < 0 {
return true; return false;
} }
if y < 0 { if y < 0 {
return true; return false;
} }
if y as usize >= lines.len() { if y as usize >= lines.len() {
return true; return false;
} }
let line = &lines[y as usize]; let line = &lines[y as usize];
if x as usize >= line.len() { if x as usize >= line.len() {
return true; return false;
} }
if line[x as usize] == b'.' { if line[x as usize] == b'*' {
return true; return true;
} }
false false
} }
fn all_dots(x: i32, y: i32, len: i32, lines: &[&[u8]]) -> bool { fn find_gears(x: i32, y: i32, len: i32, lines: &[&[u8]]) -> Vec<(i32, i32)> {
for cx in (x - 1)..=(x + len) { let mut v = vec![];
if !is_dot(cx, y - 1, lines) { for cx in (x - 1)..(x + len) {
return false; if is_gear(cx, y - 1, lines) {
v.push((cx, y - 1));
} }
} }
for cx in (x - 1)..=(x + len) { for cy in (y - 1)..=y {
if !is_dot(cx, y + 1, lines) { if is_gear(x + len, cy, lines) {
return false; v.push((x + len, cy));
} }
} }
for cy in (y - 1)..=(y + 1) { for cx in x..=(x + len) {
if !is_dot(x - 1, cy, lines) { if is_gear(cx, y + 1, lines) {
return false; v.push((cx, y + 1));
} }
} }
for cy in (y - 1)..=(y + 1) { for cy in y..=(y + 1) {
if !is_dot(x + len, cy, lines) { if is_gear(x - 1, cy, lines) {
return false; v.push((x - 1, cy));
} }
} }
true v
} }
fn main() -> Result<()> { fn main() -> Result<()> {
@ -53,23 +54,31 @@ fn main() -> Result<()> {
let lines: Vec<String> = stdin().lines().map_while(Result::ok).collect(); let lines: Vec<String> = stdin().lines().map_while(Result::ok).collect();
let raw_lines: Vec<&[u8]> = lines.iter().map(|s| s.as_bytes()).collect(); let raw_lines: Vec<&[u8]> = lines.iter().map(|s| s.as_bytes()).collect();
let mut gear_map: HashMap<(i32, i32), Vec<i32>> = HashMap::new();
for (lineno, line) in lines.iter().enumerate() { for (lineno, line) in lines.iter().enumerate() {
for m in num_re.captures_iter(line) { for m in num_re.captures_iter(line) {
let m = m?; let m = m?;
let num_match = m.get(1).unwrap(); let num_match = m.get(1).unwrap();
let num_text = num_match.as_str(); let num_text = num_match.as_str();
let num: i32 = num_text.parse()?; let num: i32 = num_text.parse()?;
println!("{lineno} {num} {} {}", num_match.start(), num_text.len()); let gears = find_gears(
if !all_dots(
num_match.start() as i32, num_match.start() as i32,
lineno as i32, lineno as i32,
num_text.len() as i32, num_text.len() as i32,
&raw_lines, &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::<i32>();
}
}
println!("{sum}"); println!("{sum}");