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::>(); 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::>(); let mut cur_num_str = VecDeque::::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::() .parse::() .unwrap(); } } } } } result }