days 1-3
This commit is contained in:
Generated
+7
@@ -0,0 +1,7 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "day03"
|
||||
version = "0.1.0"
|
||||
@@ -0,0 +1,8 @@
|
||||
[package]
|
||||
name = "day03"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
@@ -0,0 +1,114 @@
|
||||
use std::collections::HashMap;
|
||||
use std::io::{stdin, BufRead};
|
||||
|
||||
type Point = (usize, usize);
|
||||
const EMPTY_SYMBOL: char = '.';
|
||||
const GEAR_SYMBOL: char = '*';
|
||||
const DEFAULT_POINT: Point = (usize::MAX, usize::MAX);
|
||||
|
||||
fn main() {
|
||||
let input = stdin()
|
||||
.lock()
|
||||
.lines()
|
||||
.map(|l| l.unwrap().chars().collect::<Vec<_>>())
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let mut sum = 0;
|
||||
let mut gear_surrounding_nums: HashMap<Point, Vec<usize>> = HashMap::new();
|
||||
|
||||
for (y, row) in input.iter().enumerate() {
|
||||
let mut current_num = String::new();
|
||||
let mut valid = false;
|
||||
let mut gear_pos = DEFAULT_POINT;
|
||||
|
||||
for (x, col) in row.iter().enumerate() {
|
||||
if col.is_ascii_digit() {
|
||||
current_num.push(*col);
|
||||
let points = points_around(x, y);
|
||||
|
||||
for point in points {
|
||||
if let Some(adjacent_symbol) = get_at_point(point.0, point.1, &input) {
|
||||
if !adjacent_symbol.is_ascii_digit() && adjacent_symbol != &EMPTY_SYMBOL {
|
||||
valid = true;
|
||||
}
|
||||
if adjacent_symbol == &GEAR_SYMBOL {
|
||||
gear_pos = point;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if !current_num.is_empty() {
|
||||
check_and_update_point(
|
||||
valid,
|
||||
¤t_num,
|
||||
&mut sum,
|
||||
&gear_pos,
|
||||
&mut gear_surrounding_nums,
|
||||
);
|
||||
gear_pos = DEFAULT_POINT;
|
||||
valid = false;
|
||||
current_num.clear();
|
||||
}
|
||||
}
|
||||
check_and_update_point(
|
||||
valid,
|
||||
¤t_num,
|
||||
&mut sum,
|
||||
&gear_pos,
|
||||
&mut gear_surrounding_nums,
|
||||
);
|
||||
}
|
||||
|
||||
let part2 = gear_surrounding_nums
|
||||
.iter()
|
||||
.filter_map(|gear| match gear.1.len() == 2 {
|
||||
true => Some(gear.1),
|
||||
_ => None,
|
||||
})
|
||||
.fold(0, |total, gear_vals| {
|
||||
total + gear_vals.iter().product::<usize>()
|
||||
});
|
||||
|
||||
println!("P1: {} P2: {}", sum, part2);
|
||||
}
|
||||
|
||||
fn check_and_update_point(
|
||||
valid: bool,
|
||||
current_num: &str,
|
||||
sum: &mut usize,
|
||||
gear_pos: &Point,
|
||||
gear_surrounding_nums: &mut HashMap<Point, Vec<usize>>,
|
||||
) {
|
||||
if valid {
|
||||
let numeric_val = current_num.parse::<usize>().unwrap();
|
||||
|
||||
*sum += numeric_val;
|
||||
if *gear_pos != DEFAULT_POINT {
|
||||
let gears = gear_surrounding_nums.get_mut(gear_pos);
|
||||
if let Some(gear_vec) = gears {
|
||||
gear_vec.push(numeric_val);
|
||||
} else {
|
||||
gear_surrounding_nums.insert(*gear_pos, vec![numeric_val]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn get_at_point(x: usize, y: usize, grid: &[Vec<char>]) -> Option<&char> {
|
||||
if let Some(row) = grid.get(y) {
|
||||
return row.get(x);
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
fn points_around(x: usize, y: usize) -> Vec<Point> {
|
||||
let mut points = Vec::new();
|
||||
for i in x.saturating_sub(1)..(x + 2) {
|
||||
for j in y.saturating_sub(1)..(y + 2) {
|
||||
if (i, j) == (x, y) {
|
||||
continue;
|
||||
}
|
||||
points.push((i, j));
|
||||
}
|
||||
}
|
||||
points
|
||||
}
|
||||
Reference in New Issue
Block a user