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