90 lines
3 KiB
Rust
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
|
|
}
|