day 3 part 2
This commit is contained in:
parent
51ca0433f8
commit
3c0e915760
1 changed files with 34 additions and 25 deletions
59
src/main.rs
59
src/main.rs
|
@ -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}");
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue