Get slightly closer to the answer for day3 part 1

This commit is contained in:
Timothy Warren 2023-12-06 20:14:04 -05:00
parent 161b80fae0
commit da5f674811
1 changed files with 41 additions and 25 deletions

View File

@ -1,10 +1,9 @@
use crate::ValueType::Number;
use std::collections::HashSet; use std::collections::HashSet;
use std::ops::Range; use std::ops::Range;
const FILE_STR: &'static str = include_str!("input.txt"); const FILE_STR: &'static str = include_str!("input.txt");
#[derive(Debug, Default)] #[derive(Debug, Default, Clone)]
struct NumberLocation { struct NumberLocation {
start: usize, start: usize,
end: usize, end: usize,
@ -33,11 +32,12 @@ impl NumberLocation {
#[derive(Debug, Copy, Clone, PartialOrd, PartialEq, Eq, Hash)] #[derive(Debug, Copy, Clone, PartialOrd, PartialEq, Eq, Hash)]
enum ValueType { enum ValueType {
Number(usize), Number(usize),
Symbol, Symbol(char),
Err(char),
Empty, Empty,
} }
#[derive(Debug, Default)] #[derive(Debug, Default, Clone)]
struct Grid { struct Grid {
line_size: usize, line_size: usize,
numbers: Vec<NumberLocation>, numbers: Vec<NumberLocation>,
@ -46,11 +46,17 @@ struct Grid {
impl Grid { impl Grid {
pub fn parse(input_str: &str) -> Self { pub fn parse(input_str: &str) -> Self {
use ValueType::*;
let len = input_str.split('\n').next().unwrap().len(); let len = input_str.split('\n').next().unwrap().len();
let chars: Vec<char> = input_str.replace("\n", "").chars().collect();
let mut values: Vec<ValueType> = Vec::new(); let mut values: Vec<ValueType> = Vec::new();
let mut numbers: Vec<NumberLocation> = Vec::new(); let mut numbers: Vec<NumberLocation> = Vec::new();
let chars: Vec<char> = input_str.replace("\n", "").chars().collect(); let mut prev = Empty;
let mut prev = ValueType::Empty;
let symbols = vec!['%', '&', '/', '*', '=', '+', '#', '@', '-', '$'];
chars.iter().enumerate().for_each(|(i, ch)| { chars.iter().enumerate().for_each(|(i, ch)| {
if ch.is_digit(10) { if ch.is_digit(10) {
if let Number(_) = prev { if let Number(_) = prev {
@ -63,9 +69,11 @@ impl Grid {
prev = Number(numbers.len() - 1); prev = Number(numbers.len() - 1);
} else if *ch == '.' { } else if *ch == '.' {
prev = ValueType::Empty; prev = Empty;
} else if symbols.contains(ch) {
prev = Symbol(*ch);
} else { } else {
prev = ValueType::Symbol; prev = Err(*ch);
} }
values.push(prev); values.push(prev);
@ -102,16 +110,17 @@ impl Grid {
return ind; return ind;
} }
let (col, row) = self.idx_xy(i);
// Forwards/backwards // Forwards/backwards
if i > 0 { if col > 0 {
ind.insert(i - 1); ind.insert(self.xy_idx(col - 1, row));
} }
if i + 1 < self.values.len() { if col + 1 < self.num_cols() {
ind.insert(i + 1); ind.insert(self.xy_idx(col + 1, row));
} }
// Row above/below // Row above/below
let (col, row) = self.idx_xy(i);
if row + 1 < self.num_rows() { if row + 1 < self.num_rows() {
ind.insert(self.xy_idx(col, row + 1)); ind.insert(self.xy_idx(col, row + 1));
} }
@ -149,7 +158,11 @@ impl Grid {
} }
fn is_part_number(&self, r: Range<usize>) -> bool { fn is_part_number(&self, r: Range<usize>) -> bool {
self.find_adjacent(r).contains(&ValueType::Symbol) use ValueType::*;
self.find_adjacent(r).into_iter().any(|t| match t {
Symbol(_) => true,
_ => false,
})
} }
fn get_part_numbers(&self) -> Vec<usize> { fn get_part_numbers(&self) -> Vec<usize> {
@ -163,15 +176,12 @@ impl Grid {
.collect() .collect()
} }
fn get_unique_part_numbers(&self) -> HashSet<usize> {
HashSet::from_iter(self.get_part_numbers().iter().cloned())
}
fn get_part_number_sum(&self) -> usize { fn get_part_number_sum(&self) -> usize {
self.numbers self.get_unique_part_numbers().iter().sum()
.iter()
.filter(|nl| {
let range = nl.start..nl.end;
self.is_part_number(range)
})
.map(|nl| nl.to_number())
.sum()
} }
} }
@ -189,10 +199,16 @@ fn main() {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use std::iter::FromIterator;
const EXAMPLE_FILE_STR: &'static str = include_str!("example_input.txt"); const EXAMPLE_FILE_STR: &'static str = include_str!("example_input.txt");
use super::*; use super::*;
use std::iter::FromIterator;
use ValueType::*;
#[test]
fn test_get_part_number_sum_part_1() {
let grid = Grid::parse(FILE_STR);
assert!(grid.get_part_number_sum() < 1645975);
}
#[test] #[test]
fn test_adjacent_index() { fn test_adjacent_index() {
@ -205,7 +221,7 @@ mod tests {
let grid = Grid::parse(EXAMPLE_FILE_STR); let grid = Grid::parse(EXAMPLE_FILE_STR);
let adjacent = grid.find_adjacent(5..6); let adjacent = grid.find_adjacent(5..6);
let hadj = HashSet::from_iter(adjacent.iter().cloned()); let hadj = HashSet::from_iter(adjacent.iter().cloned());
assert_eq!(hadj, HashSet::from([ValueType::Empty, Number(1)])); assert_eq!(hadj, HashSet::from([Empty, Number(1)]));
} }
#[test] #[test]