Day 2 part 1
This commit is contained in:
parent
b2802d8f0a
commit
66728f862e
5 changed files with 265 additions and 0 deletions
109
day3/src/main.rs
Normal file
109
day3/src/main.rs
Normal 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
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue