Get slightly closer to the answer for day3 part 1
This commit is contained in:
parent
161b80fae0
commit
da5f674811
@ -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]
|
||||||
|
Loading…
Reference in New Issue
Block a user