Day 2 part 1

This commit is contained in:
D. Scott Boggs 2023-12-03 06:51:30 -05:00
parent b2802d8f0a
commit 66728f862e
5 changed files with 265 additions and 0 deletions

109
day3/src/main.rs Normal file
View file

@ -0,0 +1,109 @@
use std::{
fs::File,
io::{BufRead, BufReader},
ops::Range,
};
fn main() {
let grid = read_grid();
let grid_ref: Vec<_> = grid.iter().map(AsRef::as_ref).collect();
let numbers = Number::discover(&grid_ref);
let part1_result = part1(&numbers, &grid_ref);
let part2_result = part2(&numbers, &grid_ref);
println!("part 1: {part1_result}\npart 2: {part2_result}");
}
fn part1(numbers: &[Number], grid: Grid) -> i32 {
let mut total = 0;
for number in numbers {
if number.is_part(grid) {
total += number.value;
}
}
total
}
fn part2(numbers: &[Number], grid: Grid) -> &'static str {
"unsolved"
}
type Grid<'a> = &'a [&'a [char]];
fn read_grid() -> Vec<Vec<char>> {
BufReader::new(File::open("input").expect("input"))
.lines()
.map(|line| line.expect("read").chars().collect::<Vec<_>>())
.collect()
}
#[derive(Debug, Default, Clone, PartialEq, Eq)]
struct Number {
value: i32,
line_number: usize,
location: Range<usize>,
}
impl Number {
fn discover(grid: Grid) -> Vec<Number> {
let mut numbers = vec![];
for (line_number, line) in grid.iter().enumerate() {
let mut i = 0;
while i < line.len() {
let mut chr = &line[i];
if chr.is_ascii_digit() {
let start = i;
let mut text_of_number = String::new();
while i < line.len() && line[i].is_ascii_digit() {
text_of_number.push(*chr);
i += 1;
if i == line.len() {
break;
}
chr = &line[i];
}
numbers.push(Number {
value: text_of_number.parse().expect("parse number"),
line_number,
location: start..i,
});
}
i += 1;
}
}
numbers
}
fn is_part(&self, grid: Grid) -> bool {
for digit_index in self.location.clone() {
for xoff in [-1_i32, 0, 1] {
for yoff in [-1_i32, 0, 1] {
if xoff == 0 && yoff == 0 {
// skip the actual number
continue;
}
let line_number: i32 = self
.line_number
.try_into()
.unwrap_or_else(|_| panic!("invalid line number {}", self.line_number));
let line_number: usize =
(line_number + yoff).max(0).try_into().unwrap_or_else(|_| {
panic!("bad yoff {yoff} at line_number {line_number})")
});
let y = line_number.min(grid.len() - 1);
let line = grid[y];
let digit_index: i32 = digit_index
.try_into()
.unwrap_or_else(|_| panic!("invalid digit {}", self.line_number));
let digit_index: usize = (digit_index + xoff)
.max(0)
.try_into()
.unwrap_or_else(|_| panic!("bad xoff {xoff} at digit index {digit_index}"));
let x = digit_index.min(line.len() - 1);
let chr = line[x];
if chr != '.' && !chr.is_ascii_digit() {
return true;
}
}
}
}
false
}
}