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
|
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
|
day_01_bench fastest │ slowest │ median │ mean │ samples │ iters
|
||||||
├─ part1 52.85 µs │ 149.3 µs │ 53.19 µs │ 65.21 µs │ 100 │ 100
|
├─ part1 54.79 µs │ 195.1 µs │ 56.06 µs │ 70.49 µs │ 100 │ 100
|
||||||
╰─ part2 154.8 µs │ 507.2 µs │ 157.5 µs │ 199.9 µs │ 100 │ 100
|
╰─ part2 156.2 µs │ 202.6 µs │ 157.3 µs │ 160.7 µs │ 100 │ 100
|
||||||
|
|
||||||
|
|
||||||
running 2 tests
|
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
|
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
|
day_02_bench fastest │ slowest │ median │ mean │ samples │ iters
|
||||||
├─ part1 82.71 µs │ 142.8 µs │ 92.24 µs │ 97 µs │ 100 │ 100
|
├─ part1 81.18 µs │ 325.1 µs │ 83.12 µs │ 122.7 µs │ 100 │ 100
|
||||||
╰─ part2 128.9 µs │ 170.9 µs │ 131.4 µs │ 133.2 µs │ 100 │ 100
|
╰─ part2 130.1 µs │ 172.9 µs │ 131.2 µs │ 134.1 µs │ 100 │ 100
|
||||||
|
|
||||||
|
|
||||||
running 2 tests
|
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
|
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
|
day_03_bench fastest │ slowest │ median │ mean │ samples │ iters
|
||||||
├─ part1 253 µs │ 1.206 ms │ 289.4 µs │ 350.7 µs │ 100 │ 100
|
├─ part1 253.9 µs │ 796.2 µs │ 279.8 µs │ 305.1 µs │ 100 │ 100
|
||||||
╰─ part2 363.5 µs │ 1.285 ms │ 411.9 µs │ 508.2 µ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 part1;
|
||||||
pub mod part2;
|
pub mod part2;
|
||||||
|
mod vec;
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
use miette::{Diagnostic, Result};
|
use miette::Result;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use thiserror::Error;
|
|
||||||
|
use crate::{grid::Grid, vec::Vec2};
|
||||||
|
|
||||||
enum Direction {
|
enum Direction {
|
||||||
Right, // (1, 0)
|
Right, // (1, 0)
|
||||||
@ -14,16 +15,16 @@ enum Direction {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Direction {
|
impl Direction {
|
||||||
const fn get_vector(&self) -> (i32, i32) {
|
const fn get_vector(&self) -> Vec2 {
|
||||||
match self {
|
match self {
|
||||||
Direction::Right => (1, 0),
|
Direction::Right => Vec2::new(1, 0),
|
||||||
Direction::Left => (-1, 0),
|
Direction::Left => Vec2::new(-1, 0),
|
||||||
Direction::Up => (0, -1),
|
Direction::Up => Vec2::new(0, -1),
|
||||||
Direction::Down => (0, 1),
|
Direction::Down => Vec2::new(0, 1),
|
||||||
Direction::UpRight => (1, -1),
|
Direction::UpRight => Vec2::new(1, -1),
|
||||||
Direction::UpLeft => (-1, -1),
|
Direction::UpLeft => Vec2::new(-1, -1),
|
||||||
Direction::DownRight => (1, 1),
|
Direction::DownRight => Vec2::new(1, 1),
|
||||||
Direction::DownLeft => (-1, 1),
|
Direction::DownLeft => Vec2::new(-1, 1),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -41,42 +42,30 @@ impl Direction {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Error, Diagnostic)]
|
trait Part1 {
|
||||||
enum GridError {
|
fn check_direction(&self, pos: Vec2, direction: &Direction, word: &str) -> bool;
|
||||||
#[error("Error parsing")]
|
fn count_word(&self, word: &str) -> usize;
|
||||||
ParseError,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
impl Part1 for Grid {
|
||||||
struct Grid {
|
fn check_direction(&self, pos: Vec2, direction: &Direction, word: &str) -> bool {
|
||||||
data: Vec<Vec<char>>,
|
let dir_vec = direction.get_vector();
|
||||||
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();
|
|
||||||
word.chars().enumerate().all(|(idx, char)| {
|
word.chars().enumerate().all(|(idx, char)| {
|
||||||
let new_row = row + dy * idx as i32;
|
let new_pos = pos + dir_vec.scale(idx as i32);
|
||||||
let new_col = col + dx * idx as i32;
|
self.is_valid_position(&new_pos)
|
||||||
self.is_valid_position(new_row, new_col)
|
&& self.0[new_pos.y as usize][new_pos.x as usize] == char
|
||||||
&& self.data[new_row as usize][new_col 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 {
|
fn count_word(&self, word: &str) -> usize {
|
||||||
(0..self.rows)
|
(0..self.rows())
|
||||||
.flat_map(|row| {
|
.flat_map(|row| {
|
||||||
(0..self.cols).flat_map(move |col| {
|
(0..self.cols()).flat_map(move |col| {
|
||||||
Direction::all_directions()
|
Direction::all_directions()
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.filter(move |direction| {
|
.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]
|
#[tracing::instrument]
|
||||||
pub fn process(input: &str) -> Result<usize> {
|
pub fn process(input: &str) -> Result<usize> {
|
||||||
let grid = Grid::from_str(input)?;
|
let grid = Grid::from_str(input)?;
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
|
use crate::{grid::Grid, vec::Vec2};
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use miette::{Diagnostic, Result};
|
use miette::Result;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use thiserror::Error;
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
enum Direction {
|
enum Direction {
|
||||||
@ -12,12 +12,12 @@ enum Direction {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Direction {
|
impl Direction {
|
||||||
const fn get_vector(&self) -> (i32, i32) {
|
const fn get_vector(&self) -> Vec2 {
|
||||||
match self {
|
match self {
|
||||||
Direction::UpRight => (1, -1),
|
Direction::UpRight => Vec2::new(1, -1),
|
||||||
Direction::UpLeft => (-1, -1),
|
Direction::UpLeft => Vec2::new(-1, -1),
|
||||||
Direction::DownRight => (1, 1),
|
Direction::DownRight => Vec2::new(1, 1),
|
||||||
Direction::DownLeft => (-1, 1),
|
Direction::DownLeft => Vec2::new(-1, 1),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -29,46 +29,33 @@ impl Direction {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Error, Diagnostic)]
|
trait Part2 {
|
||||||
enum GridError {
|
fn check_direction(&self, pos: Vec2, direction: &Direction, word: &str) -> bool;
|
||||||
#[error("Error parsing")]
|
fn count_word(&self, word: &str) -> usize;
|
||||||
ParseError,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
impl Part2 for Grid {
|
||||||
struct Grid {
|
fn check_direction(&self, pos: Vec2, direction: &Direction, word: &str) -> bool {
|
||||||
data: Vec<Vec<char>>,
|
let dir_vec = direction.get_vector();
|
||||||
rows: usize,
|
let start_pos = pos + dir_vec.scale(-1); // Move back one position
|
||||||
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;
|
|
||||||
word.chars().enumerate().all(|(idx, char)| {
|
word.chars().enumerate().all(|(idx, char)| {
|
||||||
let new_row = start_row + dy * idx as i32;
|
let new_pos = start_pos + dir_vec.scale(idx as i32);
|
||||||
let new_col = start_col + dx * idx as i32;
|
self.is_valid_position(&new_pos)
|
||||||
self.is_valid_position(new_row, new_col)
|
&& self.0[new_pos.y as usize][new_pos.x as usize] == char
|
||||||
&& self.data[new_row as usize][new_col 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 {
|
fn count_word(&self, word: &str) -> usize {
|
||||||
(0..self.rows)
|
(0..self.rows())
|
||||||
.flat_map(|row| {
|
.flat_map(|row| {
|
||||||
(0..self.cols).filter(move |&col| {
|
(0..self.cols()).filter(move |&col| {
|
||||||
if self.data[row][col] != 'A' {
|
let pos = Vec2::new(col as i32, row as i32);
|
||||||
|
if self.0[row][col] != 'A' {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
Direction::pairs().any(|(dir1, dir2)| {
|
Direction::pairs().any(|(dir1, dir2)| {
|
||||||
self.check_direction(row as i32, col as i32, &dir1, word)
|
self.check_direction(pos, &dir1, word)
|
||||||
&& self.check_direction(row as i32, col as i32, &dir2, 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]
|
#[tracing::instrument]
|
||||||
pub fn process(input: &str) -> Result<usize> {
|
pub fn process(input: &str) -> Result<usize> {
|
||||||
let grid = Grid::from_str(input)?;
|
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