aoc-2023/d03t1/src/main.rs

90 lines
3 KiB
Rust

use std::{
collections::{HashSet, VecDeque},
fs::read_to_string,
};
fn dec_if_pos(input: usize) -> usize {
if input > 0 {
input - 1
} else {
input
}
}
fn inc_if_lt(input: usize, max: usize) -> usize {
if input < max {
input + 1
} else {
input
}
}
fn main() {
let input = read_to_string("input.txt").unwrap();
println!("d03t1: {}", d03t1(&input));
}
fn d03t1(input: &str) -> usize {
let mut result = 0;
let lines = input.lines().collect::<Vec<_>>();
let total_lines = lines.len();
let mut checked_fields: HashSet<(usize, usize)> = HashSet::new();
for (line_idx, line) in input.lines().enumerate() {
for (char_idx, _char) in line
.chars()
.enumerate()
.filter(|(_, char)| !char.is_ascii_digit() && *char != '.')
{
for x in dec_if_pos(char_idx)..=inc_if_lt(char_idx, line.len()) {
for (y, &cur_line) in lines
.iter()
.enumerate()
.take(inc_if_lt(line_idx, total_lines) + 1)
.skip(dec_if_pos(line_idx))
{
let line_chars = cur_line.chars().collect::<Vec<_>>();
let mut cur_num_str = VecDeque::<char>::new();
if line_chars[x].is_ascii_digit() {
if checked_fields.contains(&(x, y)) {
continue;
}
checked_fields.insert((x, y));
cur_num_str.push_back(line_chars[x]);
if x > 0 {
for i in (0..x).rev() {
if line_chars[i].is_ascii_digit() {
cur_num_str.push_front(line_chars[i]);
checked_fields.insert((i, y));
} else {
break;
}
}
}
if x < line.len() {
for (i, item) in line_chars
.iter()
.enumerate()
.take((line.len() - 1) + 1)
.skip(x + 1)
{
if item.is_ascii_digit() {
cur_num_str.push_back(*item);
checked_fields.insert((i, y));
} else {
break;
}
}
}
result += cur_num_str
.into_iter()
.collect::<String>()
.parse::<usize>()
.unwrap();
}
}
}
}
}
result
}