mirror of
https://github.com/kristoferssolo/Advent-of-Code.git
synced 2025-10-21 18:00:35 +00:00
refactor: day-04
This commit is contained in:
parent
2e1cd400da
commit
c28bd8a08a
@ -14,8 +14,8 @@ running 0 tests
|
||||
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
|
||||
|
||||
day_01_bench fastest │ slowest │ median │ mean │ samples │ iters
|
||||
├─ part1 52.85 µs │ 149.3 µs │ 53.19 µs │ 65.21 µs │ 100 │ 100
|
||||
╰─ part2 154.8 µs │ 507.2 µs │ 157.5 µs │ 199.9 µs │ 100 │ 100
|
||||
├─ part1 54.79 µs │ 195.1 µs │ 56.06 µs │ 70.49 µs │ 100 │ 100
|
||||
╰─ part2 156.2 µs │ 202.6 µs │ 157.3 µs │ 160.7 µs │ 100 │ 100
|
||||
|
||||
|
||||
running 2 tests
|
||||
@ -33,8 +33,8 @@ running 0 tests
|
||||
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
|
||||
|
||||
day_02_bench fastest │ slowest │ median │ mean │ samples │ iters
|
||||
├─ part1 82.71 µs │ 142.8 µs │ 92.24 µs │ 97 µs │ 100 │ 100
|
||||
╰─ part2 128.9 µs │ 170.9 µs │ 131.4 µs │ 133.2 µs │ 100 │ 100
|
||||
├─ part1 81.18 µs │ 325.1 µs │ 83.12 µs │ 122.7 µs │ 100 │ 100
|
||||
╰─ part2 130.1 µs │ 172.9 µs │ 131.2 µs │ 134.1 µs │ 100 │ 100
|
||||
|
||||
|
||||
running 2 tests
|
||||
@ -52,6 +52,25 @@ running 0 tests
|
||||
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
|
||||
|
||||
day_03_bench fastest │ slowest │ median │ mean │ samples │ iters
|
||||
├─ part1 253 µs │ 1.206 ms │ 289.4 µs │ 350.7 µs │ 100 │ 100
|
||||
╰─ part2 363.5 µs │ 1.285 ms │ 411.9 µs │ 508.2 µs │ 100 │ 100
|
||||
├─ part1 253.9 µs │ 796.2 µs │ 279.8 µs │ 305.1 µs │ 100 │ 100
|
||||
╰─ part2 363.1 µs │ 1.209 ms │ 417.6 µs │ 536.8 µs │ 100 │ 100
|
||||
|
||||
|
||||
running 2 tests
|
||||
ii
|
||||
test result: ok. 0 passed; 0 failed; 2 ignored; 0 measured; 0 filtered out; finished in 0.00s
|
||||
|
||||
|
||||
running 0 tests
|
||||
|
||||
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
|
||||
|
||||
|
||||
running 0 tests
|
||||
|
||||
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
|
||||
|
||||
day_04_bench fastest │ slowest │ median │ mean │ samples │ iters
|
||||
├─ part1 598 µs │ 2.157 ms │ 611 µs │ 800.4 µs │ 100 │ 100
|
||||
╰─ part2 632.9 µs │ 886 µs │ 640.8 µs │ 646.7 µs │ 100 │ 100
|
||||
|
||||
|
||||
4
2024/day-04/bench.txt
Normal file
4
2024/day-04/bench.txt
Normal file
@ -0,0 +1,4 @@
|
||||
day_04_bench fastest │ slowest │ median │ mean │ samples │ iters
|
||||
├─ part1 599.5 µs │ 2.275 ms │ 605.1 µs │ 770.3 µs │ 100 │ 100
|
||||
╰─ part2 648.7 µs │ 674.5 µs │ 657.9 µs │ 658.7 µs │ 100 │ 100
|
||||
|
||||
36
2024/day-04/src/grid.rs
Normal file
36
2024/day-04/src/grid.rs
Normal file
@ -0,0 +1,36 @@
|
||||
use crate::vec::Vec2;
|
||||
use miette::Diagnostic;
|
||||
use std::str::FromStr;
|
||||
use thiserror::Error;
|
||||
|
||||
#[derive(Debug, Error, Diagnostic)]
|
||||
pub(crate) enum GridError {}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub(crate) struct Grid(pub(crate) Vec<Vec<char>>);
|
||||
|
||||
impl Grid {
|
||||
pub(crate) fn is_valid_position(&self, pos: &Vec2) -> bool {
|
||||
pos.x >= 0 && pos.x < self.cols() as i32 && pos.y >= 0 && pos.y < self.rows() as i32
|
||||
}
|
||||
|
||||
pub(crate) fn rows(&self) -> usize {
|
||||
self.0.len()
|
||||
}
|
||||
pub(crate) fn cols(&self) -> usize {
|
||||
self.0[0].len()
|
||||
}
|
||||
}
|
||||
|
||||
impl FromStr for Grid {
|
||||
type Err = GridError;
|
||||
fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
|
||||
let data = s
|
||||
.lines()
|
||||
.filter(|line| !line.is_empty())
|
||||
.map(|line| line.chars().collect::<Vec<_>>())
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
Ok(Grid(data))
|
||||
}
|
||||
}
|
||||
@ -1,2 +1,4 @@
|
||||
mod grid;
|
||||
pub mod part1;
|
||||
pub mod part2;
|
||||
mod vec;
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
use miette::{Diagnostic, Result};
|
||||
use miette::Result;
|
||||
use std::str::FromStr;
|
||||
use thiserror::Error;
|
||||
|
||||
use crate::{grid::Grid, vec::Vec2};
|
||||
|
||||
enum Direction {
|
||||
Right, // (1, 0)
|
||||
@ -14,16 +15,16 @@ enum Direction {
|
||||
}
|
||||
|
||||
impl Direction {
|
||||
const fn get_vector(&self) -> (i32, i32) {
|
||||
const fn get_vector(&self) -> Vec2 {
|
||||
match self {
|
||||
Direction::Right => (1, 0),
|
||||
Direction::Left => (-1, 0),
|
||||
Direction::Up => (0, -1),
|
||||
Direction::Down => (0, 1),
|
||||
Direction::UpRight => (1, -1),
|
||||
Direction::UpLeft => (-1, -1),
|
||||
Direction::DownRight => (1, 1),
|
||||
Direction::DownLeft => (-1, 1),
|
||||
Direction::Right => Vec2::new(1, 0),
|
||||
Direction::Left => Vec2::new(-1, 0),
|
||||
Direction::Up => Vec2::new(0, -1),
|
||||
Direction::Down => Vec2::new(0, 1),
|
||||
Direction::UpRight => Vec2::new(1, -1),
|
||||
Direction::UpLeft => Vec2::new(-1, -1),
|
||||
Direction::DownRight => Vec2::new(1, 1),
|
||||
Direction::DownLeft => Vec2::new(-1, 1),
|
||||
}
|
||||
}
|
||||
|
||||
@ -41,42 +42,30 @@ impl Direction {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Error, Diagnostic)]
|
||||
enum GridError {
|
||||
#[error("Error parsing")]
|
||||
ParseError,
|
||||
trait Part1 {
|
||||
fn check_direction(&self, pos: Vec2, direction: &Direction, word: &str) -> bool;
|
||||
fn count_word(&self, word: &str) -> usize;
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct Grid {
|
||||
data: Vec<Vec<char>>,
|
||||
rows: usize,
|
||||
cols: usize,
|
||||
}
|
||||
|
||||
impl Grid {
|
||||
fn check_direction(&self, row: i32, col: i32, direction: &Direction, word: &str) -> bool {
|
||||
let (dx, dy) = direction.get_vector();
|
||||
impl Part1 for Grid {
|
||||
fn check_direction(&self, pos: Vec2, direction: &Direction, word: &str) -> bool {
|
||||
let dir_vec = direction.get_vector();
|
||||
word.chars().enumerate().all(|(idx, char)| {
|
||||
let new_row = row + dy * idx as i32;
|
||||
let new_col = col + dx * idx as i32;
|
||||
self.is_valid_position(new_row, new_col)
|
||||
&& self.data[new_row as usize][new_col as usize] == char
|
||||
let new_pos = pos + dir_vec.scale(idx as i32);
|
||||
self.is_valid_position(&new_pos)
|
||||
&& self.0[new_pos.y as usize][new_pos.x as usize] == char
|
||||
})
|
||||
}
|
||||
|
||||
fn is_valid_position(&self, row: i32, col: i32) -> bool {
|
||||
row >= 0 && row < self.rows as i32 && col >= 0 && col < self.cols as i32
|
||||
}
|
||||
|
||||
fn count_word(&self, word: &str) -> usize {
|
||||
(0..self.rows)
|
||||
(0..self.rows())
|
||||
.flat_map(|row| {
|
||||
(0..self.cols).flat_map(move |col| {
|
||||
(0..self.cols()).flat_map(move |col| {
|
||||
Direction::all_directions()
|
||||
.into_iter()
|
||||
.filter(move |direction| {
|
||||
self.check_direction(row as i32, col as i32, direction, word)
|
||||
let pos = Vec2::new(col as i32, row as i32);
|
||||
self.check_direction(pos, direction, word)
|
||||
})
|
||||
})
|
||||
})
|
||||
@ -84,28 +73,6 @@ impl Grid {
|
||||
}
|
||||
}
|
||||
|
||||
impl FromStr for Grid {
|
||||
type Err = GridError;
|
||||
fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
|
||||
let data = s
|
||||
.lines()
|
||||
.map(|line| line.chars().collect::<Vec<_>>())
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let rows = data.len();
|
||||
if rows == 0 {
|
||||
return Err(GridError::ParseError);
|
||||
}
|
||||
let cols = data[0].len();
|
||||
|
||||
if data.iter().any(|row| row.len() != cols) {
|
||||
return Err(GridError::ParseError);
|
||||
}
|
||||
|
||||
Ok(Grid { data, rows, cols })
|
||||
}
|
||||
}
|
||||
|
||||
#[tracing::instrument]
|
||||
pub fn process(input: &str) -> Result<usize> {
|
||||
let grid = Grid::from_str(input)?;
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
use crate::{grid::Grid, vec::Vec2};
|
||||
use itertools::Itertools;
|
||||
use miette::{Diagnostic, Result};
|
||||
use miette::Result;
|
||||
use std::str::FromStr;
|
||||
use thiserror::Error;
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
enum Direction {
|
||||
@ -12,12 +12,12 @@ enum Direction {
|
||||
}
|
||||
|
||||
impl Direction {
|
||||
const fn get_vector(&self) -> (i32, i32) {
|
||||
const fn get_vector(&self) -> Vec2 {
|
||||
match self {
|
||||
Direction::UpRight => (1, -1),
|
||||
Direction::UpLeft => (-1, -1),
|
||||
Direction::DownRight => (1, 1),
|
||||
Direction::DownLeft => (-1, 1),
|
||||
Direction::UpRight => Vec2::new(1, -1),
|
||||
Direction::UpLeft => Vec2::new(-1, -1),
|
||||
Direction::DownRight => Vec2::new(1, 1),
|
||||
Direction::DownLeft => Vec2::new(-1, 1),
|
||||
}
|
||||
}
|
||||
|
||||
@ -29,46 +29,33 @@ impl Direction {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Error, Diagnostic)]
|
||||
enum GridError {
|
||||
#[error("Error parsing")]
|
||||
ParseError,
|
||||
trait Part2 {
|
||||
fn check_direction(&self, pos: Vec2, direction: &Direction, word: &str) -> bool;
|
||||
fn count_word(&self, word: &str) -> usize;
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct Grid {
|
||||
data: Vec<Vec<char>>,
|
||||
rows: usize,
|
||||
cols: usize,
|
||||
}
|
||||
|
||||
impl Grid {
|
||||
fn check_direction(&self, row: i32, col: i32, direction: &Direction, word: &str) -> bool {
|
||||
let (dx, dy) = direction.get_vector();
|
||||
let start_row = row - dy;
|
||||
let start_col = col - dx;
|
||||
impl Part2 for Grid {
|
||||
fn check_direction(&self, pos: Vec2, direction: &Direction, word: &str) -> bool {
|
||||
let dir_vec = direction.get_vector();
|
||||
let start_pos = pos + dir_vec.scale(-1); // Move back one position
|
||||
word.chars().enumerate().all(|(idx, char)| {
|
||||
let new_row = start_row + dy * idx as i32;
|
||||
let new_col = start_col + dx * idx as i32;
|
||||
self.is_valid_position(new_row, new_col)
|
||||
&& self.data[new_row as usize][new_col as usize] == char
|
||||
let new_pos = start_pos + dir_vec.scale(idx as i32);
|
||||
self.is_valid_position(&new_pos)
|
||||
&& self.0[new_pos.y as usize][new_pos.x as usize] == char
|
||||
})
|
||||
}
|
||||
|
||||
fn is_valid_position(&self, row: i32, col: i32) -> bool {
|
||||
row >= 0 && row < self.rows as i32 && col >= 0 && col < self.cols as i32
|
||||
}
|
||||
|
||||
fn count_word(&self, word: &str) -> usize {
|
||||
(0..self.rows)
|
||||
(0..self.rows())
|
||||
.flat_map(|row| {
|
||||
(0..self.cols).filter(move |&col| {
|
||||
if self.data[row][col] != 'A' {
|
||||
(0..self.cols()).filter(move |&col| {
|
||||
let pos = Vec2::new(col as i32, row as i32);
|
||||
if self.0[row][col] != 'A' {
|
||||
return false;
|
||||
}
|
||||
Direction::pairs().any(|(dir1, dir2)| {
|
||||
self.check_direction(row as i32, col as i32, &dir1, word)
|
||||
&& self.check_direction(row as i32, col as i32, &dir2, word)
|
||||
self.check_direction(pos, &dir1, word)
|
||||
&& self.check_direction(pos, &dir2, word)
|
||||
})
|
||||
})
|
||||
})
|
||||
@ -76,29 +63,6 @@ impl Grid {
|
||||
}
|
||||
}
|
||||
|
||||
impl FromStr for Grid {
|
||||
type Err = GridError;
|
||||
fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
|
||||
let data = s
|
||||
.lines()
|
||||
.filter(|line| !line.is_empty())
|
||||
.map(|line| line.chars().collect::<Vec<_>>())
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let rows = data.len();
|
||||
if rows == 0 {
|
||||
return Err(GridError::ParseError);
|
||||
}
|
||||
let cols = data[0].len();
|
||||
|
||||
if data.iter().any(|row| row.len() != cols) {
|
||||
return Err(GridError::ParseError);
|
||||
}
|
||||
|
||||
Ok(Grid { data, rows, cols })
|
||||
}
|
||||
}
|
||||
|
||||
#[tracing::instrument]
|
||||
pub fn process(input: &str) -> Result<usize> {
|
||||
let grid = Grid::from_str(input)?;
|
||||
|
||||
24
2024/day-04/src/vec.rs
Normal file
24
2024/day-04/src/vec.rs
Normal file
@ -0,0 +1,24 @@
|
||||
use std::ops::Add;
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub(crate) struct Vec2 {
|
||||
pub(crate) x: i32,
|
||||
pub(crate) y: i32,
|
||||
}
|
||||
|
||||
impl Vec2 {
|
||||
pub(crate) const fn new(x: i32, y: i32) -> Self {
|
||||
Self { x, y }
|
||||
}
|
||||
|
||||
pub(crate) fn scale(&self, factor: i32) -> Self {
|
||||
Self::new(self.x * factor, self.y * factor)
|
||||
}
|
||||
}
|
||||
|
||||
impl Add for Vec2 {
|
||||
type Output = Vec2;
|
||||
fn add(self, rhs: Self) -> Self::Output {
|
||||
Vec2::new(self.x + rhs.x, self.y + rhs.y)
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user