Complete 2023 Day 3 Part 1
This commit is contained in:
parent
da5f674811
commit
979d241bb8
@ -3,7 +3,7 @@ use std::ops::Range;
|
||||
|
||||
const FILE_STR: &'static str = include_str!("input.txt");
|
||||
|
||||
#[derive(Debug, Default, Clone)]
|
||||
#[derive(Debug, Default, Clone, Eq, PartialEq)]
|
||||
struct NumberLocation {
|
||||
start: usize,
|
||||
end: usize,
|
||||
@ -33,7 +33,6 @@ impl NumberLocation {
|
||||
enum ValueType {
|
||||
Number(usize),
|
||||
Symbol(char),
|
||||
Err(char),
|
||||
Empty,
|
||||
}
|
||||
|
||||
@ -49,35 +48,37 @@ impl Grid {
|
||||
use ValueType::*;
|
||||
|
||||
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 numbers: Vec<NumberLocation> = Vec::new();
|
||||
let mut prev = Empty;
|
||||
|
||||
let symbols = vec!['%', '&', '/', '*', '=', '+', '#', '@', '-', '$'];
|
||||
input_str
|
||||
.split('\n')
|
||||
.map(|row| row.chars())
|
||||
.enumerate()
|
||||
.for_each(|(r, char_row)| {
|
||||
let mut prev = Empty;
|
||||
char_row.enumerate().for_each(|(c, ch)| {
|
||||
let n = len * r + c;
|
||||
if ch.is_digit(10) {
|
||||
if let Number(_) = prev {
|
||||
let final_num = { numbers.len() - 1 };
|
||||
numbers.get_mut(final_num).unwrap().add_digit(ch);
|
||||
} else {
|
||||
let nl = NumberLocation::new(n, ch);
|
||||
numbers.push(nl);
|
||||
}
|
||||
|
||||
chars.iter().enumerate().for_each(|(i, ch)| {
|
||||
if ch.is_digit(10) {
|
||||
if let Number(_) = prev {
|
||||
let final_num = { numbers.len() - 1 };
|
||||
numbers.get_mut(final_num).unwrap().add_digit(*ch);
|
||||
} else {
|
||||
let nl = NumberLocation::new(i, *ch);
|
||||
numbers.push(nl);
|
||||
}
|
||||
prev = Number(numbers.len() - 1);
|
||||
} else if ch == '.' {
|
||||
prev = Empty;
|
||||
} else {
|
||||
prev = Symbol(ch);
|
||||
}
|
||||
|
||||
prev = Number(numbers.len() - 1);
|
||||
} else if *ch == '.' {
|
||||
prev = Empty;
|
||||
} else if symbols.contains(ch) {
|
||||
prev = Symbol(*ch);
|
||||
} else {
|
||||
prev = Err(*ch);
|
||||
}
|
||||
|
||||
values.push(prev);
|
||||
});
|
||||
values.push(prev);
|
||||
});
|
||||
});
|
||||
|
||||
Grid {
|
||||
line_size: len,
|
||||
@ -104,57 +105,60 @@ impl Grid {
|
||||
(idx % self.num_cols(), idx / self.num_cols())
|
||||
}
|
||||
|
||||
fn adjacent_ind(&self, i: usize) -> HashSet<usize> {
|
||||
fn adjacent_ind(&self, r: Range<usize>) -> HashSet<usize> {
|
||||
let min = r.start;
|
||||
let max = r.end - 1;
|
||||
let mut ind = HashSet::new();
|
||||
if i >= self.values.len() {
|
||||
if max >= self.values.len() {
|
||||
return ind;
|
||||
}
|
||||
|
||||
let (col, row) = self.idx_xy(i);
|
||||
let (min_col, row) = self.idx_xy(min);
|
||||
let (max_col, erow) = self.idx_xy(max);
|
||||
assert_eq!(row, erow, "All the digits should be in the same row");
|
||||
|
||||
// Forwards/backwards
|
||||
if col > 0 {
|
||||
ind.insert(self.xy_idx(col - 1, row));
|
||||
if min_col > 0 {
|
||||
ind.insert(self.xy_idx(min_col - 1, row));
|
||||
}
|
||||
if col + 1 < self.num_cols() {
|
||||
ind.insert(self.xy_idx(col + 1, row));
|
||||
if max_col + 1 < self.num_cols() {
|
||||
ind.insert(self.xy_idx(max_col + 1, row));
|
||||
}
|
||||
|
||||
// Row above/below
|
||||
if row + 1 < self.num_rows() {
|
||||
ind.insert(self.xy_idx(col, row + 1));
|
||||
}
|
||||
if row > 0 {
|
||||
ind.insert(self.xy_idx(col, row - 1));
|
||||
for x in r {
|
||||
let (col, row) = self.idx_xy(x);
|
||||
|
||||
if row + 1 < self.num_rows() {
|
||||
ind.insert(self.xy_idx(col, row + 1));
|
||||
}
|
||||
if row > 0 {
|
||||
ind.insert(self.xy_idx(col, row - 1));
|
||||
}
|
||||
}
|
||||
|
||||
// Diagonals (x+1, y-1),(x-1, y-1),(x+1, y+1),(x-1,y+1)
|
||||
if col > 0 && row > 0 {
|
||||
ind.insert(self.xy_idx(col - 1, row - 1));
|
||||
// Diagonals (min-1, y-1),(min-1,y+1),(max+1, y-1),(max+1, y+1)
|
||||
if min_col > 0 && row > 0 {
|
||||
ind.insert(self.xy_idx(min_col - 1, row - 1));
|
||||
}
|
||||
if col > 0 && row + 1 < self.num_rows() {
|
||||
ind.insert(self.xy_idx(col - 1, row + 1));
|
||||
if min_col > 0 && row + 1 < self.num_rows() {
|
||||
ind.insert(self.xy_idx(min_col - 1, row + 1));
|
||||
}
|
||||
if col + 1 < self.num_cols() && row > 0 {
|
||||
ind.insert(self.xy_idx(col + 1, row - 1));
|
||||
if max_col + 1 < self.num_cols() && row > 0 {
|
||||
ind.insert(self.xy_idx(max_col + 1, row - 1));
|
||||
}
|
||||
if col + 1 < self.num_cols() && row + 1 < self.num_rows() {
|
||||
ind.insert(self.xy_idx(col + 1, row + 1));
|
||||
if max_col + 1 < self.num_cols() && row + 1 < self.num_rows() {
|
||||
ind.insert(self.xy_idx(max_col + 1, row + 1));
|
||||
}
|
||||
|
||||
ind
|
||||
}
|
||||
|
||||
fn find_adjacent(&self, r: Range<usize>) -> Vec<ValueType> {
|
||||
let mut adj = Vec::new();
|
||||
|
||||
for i in r {
|
||||
self.adjacent_ind(i)
|
||||
.into_iter()
|
||||
.for_each(|ind| adj.push(self.values[ind]));
|
||||
}
|
||||
|
||||
adj
|
||||
self.adjacent_ind(r)
|
||||
.into_iter()
|
||||
.map(|ind| self.values[ind])
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn is_part_number(&self, r: Range<usize>) -> bool {
|
||||
@ -181,7 +185,7 @@ impl Grid {
|
||||
}
|
||||
|
||||
fn get_part_number_sum(&self) -> usize {
|
||||
self.get_unique_part_numbers().iter().sum()
|
||||
self.get_part_numbers().iter().sum()
|
||||
}
|
||||
}
|
||||
|
||||
@ -201,33 +205,30 @@ fn main() {
|
||||
mod tests {
|
||||
const EXAMPLE_FILE_STR: &'static str = include_str!("example_input.txt");
|
||||
use super::*;
|
||||
use std::iter::FromIterator;
|
||||
use 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);
|
||||
assert_eq!(grid.get_part_number_sum(), 525181);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_adjacent_index() {
|
||||
let grid = Grid::parse(EXAMPLE_FILE_STR);
|
||||
assert_eq!(grid.adjacent_ind(5), HashSet::from([4, 6, 14, 15, 16]));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_find_adjacent() {
|
||||
let grid = Grid::parse(EXAMPLE_FILE_STR);
|
||||
let adjacent = grid.find_adjacent(5..6);
|
||||
let hadj = HashSet::from_iter(adjacent.iter().cloned());
|
||||
assert_eq!(hadj, HashSet::from([Empty, Number(1)]));
|
||||
let actual = grid.adjacent_ind(62..65);
|
||||
assert_eq!(12, actual.len());
|
||||
assert_eq!(
|
||||
HashSet::from_iter(actual.iter().cloned()),
|
||||
HashSet::from([51, 52, 53, 54, 55, 61, 65, 71, 72, 73, 74, 75])
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_get_part_numbers() {
|
||||
let grid = Grid::parse(EXAMPLE_FILE_STR);
|
||||
let expected = [467, 35, 633, 617, 592, 755, 664, 598];
|
||||
let expected = [467usize, 35, 633, 617, 592, 755, 664, 598];
|
||||
assert_eq!(grid.get_part_numbers(), expected);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user