From b3df4b9246075876806ea922df7d53416458773b Mon Sep 17 00:00:00 2001
From: tom-anders <13141438+tom-anders@users.noreply.github.com>
Date: Thu, 12 Dec 2024 13:40:28 +0100
Subject: [PATCH] solve: day12
---
Cargo.toml | 2 +-
utils/src/lib.rs | 9 +++++
utils/src/math/vec2d.rs | 75 +++++++++++++++++++----------------------
3 files changed, 44 insertions(+), 42 deletions(-)
diff --git a/Cargo.toml b/Cargo.toml
index 90c4448..1ebf7b6 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -2,7 +2,7 @@
resolver = "2"
members = [
"utils",
- "aoc_derive", "day1", "day2", "day3", "day4", "day5", "day6", "day7", "day8", "day9", "day10", "day11",
+ "aoc_derive", "day1", "day2", "day3", "day4", "day5", "day6", "day7", "day8", "day9", "day10", "day11", "day12",
]
[workspace.dependencies]
diff --git a/utils/src/lib.rs b/utils/src/lib.rs
index 0c93990..98c7bf6 100644
--- a/utils/src/lib.rs
+++ b/utils/src/lib.rs
@@ -65,6 +65,15 @@ pub trait EvenMoreItertools: Iterator {
{
self.enumerate().filter_map(move |(i, x)| (i != skip).then_some(x))
}
+
+ fn unzip_vec(self) -> (Vec, Vec)
+ where
+ Self: Sized + Iterator- ,
+ {
+ let mut unzipped: (Vec, Vec) = Default::default();
+ unzipped.extend(self);
+ unzipped
+ }
}
impl EvenMoreItertools for T where T: Iterator {}
diff --git a/utils/src/math/vec2d.rs b/utils/src/math/vec2d.rs
index efa40b2..dee1aba 100644
--- a/utils/src/math/vec2d.rs
+++ b/utils/src/math/vec2d.rs
@@ -1,6 +1,7 @@
use parse_display::FromStr;
-#[derive(Copy, Clone, Debug, Eq, Hash, FromStr, PartialOrd, Ord)]
+#[derive(Copy, Clone, Debug, Eq, Hash, FromStr, PartialOrd, Ord, derive_more::Display)]
+#[display("({x}, {y})")]
// Parses [1, 2] or (1, 2) or {1, 2}
#[from_str(regex = r"[\[\(\{](?-?\d+),\s*(?-?\d+)[\]\)\}]")]
pub struct Vec2D {
@@ -8,7 +9,10 @@ pub struct Vec2D {
pub y: i64,
}
-impl PartialEq for Vec2D where T: Into + Copy {
+impl PartialEq for Vec2D
+where
+ T: Into + Copy,
+{
fn eq(&self, other: &T) -> bool {
let other: Vec2D = (*other).into();
self.x == other.x && self.y == other.y
@@ -70,25 +74,15 @@ impl Vec2D {
}
pub fn diagonal_neighbors(&self) -> impl Iterator
- + '_ {
- [
- Vec2D { x: 1, y: 1 },
- Vec2D { x: -1, y: 1 },
- Vec2D { x: 1, y: -1 },
- Vec2D { x: -1, y: -1 },
- ]
- .iter()
- .map(move |&dir| *self + dir)
+ [Vec2D { x: 1, y: 1 }, Vec2D { x: -1, y: 1 }, Vec2D { x: 1, y: -1 }, Vec2D { x: -1, y: -1 }]
+ .iter()
+ .map(move |&dir| *self + dir)
}
pub fn orthogonal_neighbors(&self) -> impl Iterator
- + '_ {
- [
- Vec2D { x: 1, y: 0 },
- Vec2D { x: -1, y: 0 },
- Vec2D { x: 0, y: 1 },
- Vec2D { x: 0, y: -1 },
- ]
- .iter()
- .map(move |&dir| *self + dir)
+ [Vec2D { x: 1, y: 0 }, Vec2D { x: -1, y: 0 }, Vec2D { x: 0, y: 1 }, Vec2D { x: 0, y: -1 }]
+ .iter()
+ .map(move |&dir| *self + dir)
}
pub fn all_neighbors(&self) -> impl Iterator
- + '_ {
@@ -128,14 +122,11 @@ where
type Output = Vec2D;
fn mul(self, rhs: T) -> Self::Output {
- Vec2D::new(
- self.x * rhs.to_i64().unwrap(),
- self.y * rhs.to_i64().unwrap(),
- )
+ Vec2D::new(self.x * rhs.to_i64().unwrap(), self.y * rhs.to_i64().unwrap())
}
}
-impl std::ops::MulAssign for Vec2D
+impl std::ops::MulAssign for Vec2D
where
T: num::ToPrimitive + num::Integer,
{
@@ -151,7 +142,7 @@ macro_rules! impl_left_mul {
$(
impl std::ops::Mul for $t {
type Output = Vec2D;
-
+
fn mul(self, rhs: Vec2D) -> Self::Output {
rhs * self
}
@@ -161,7 +152,10 @@ macro_rules! impl_left_mul {
}
impl_left_mul!(i8, i16, i32, i64, isize, u8, u16, u32, u64, usize);
-impl std::ops::Add for Vec2D where T: Into {
+impl std::ops::Add for Vec2D
+where
+ T: Into,
+{
type Output = Vec2D;
fn add(self, rhs: T) -> Self::Output {
@@ -170,13 +164,19 @@ impl std::ops::Add for Vec2D where T: Into {
}
}
-impl std::ops::AddAssign for Vec2D where T: Into {
+impl std::ops::AddAssign for Vec2D
+where
+ T: Into,
+{
fn add_assign(&mut self, rhs: T) {
*self = *self + rhs;
}
}
-impl std::ops::Sub for Vec2D where T: Into {
+impl std::ops::Sub for Vec2D
+where
+ T: Into,
+{
type Output = Vec2D;
fn sub(self, rhs: T) -> Self::Output {
@@ -185,7 +185,10 @@ impl std::ops::Sub for Vec2D where T: Into {
}
}
-impl std::ops::SubAssign for Vec2D where T: Into {
+impl std::ops::SubAssign for Vec2D
+where
+ T: Into,
+{
fn sub_assign(&mut self, rhs: T) {
*self = *self - rhs;
}
@@ -246,7 +249,7 @@ mod tests {
assert_eq!(Vec2D::new(1, -2).manhattan_dist(), 3);
}
- #[test]
+ #[test]
fn inside_box() {
assert!(Vec2D::new(1, 2).inside_box((0, 0), (2, 3)));
assert!(Vec2D::new(1, 2).inside_box((1, 2), (1, 2)));
@@ -275,21 +278,11 @@ mod tests {
#[test]
fn neighbors() {
assert_eq!(
- HashSet::from([
- Vec2D::new(2, 2),
- Vec2D::new(0, 2),
- Vec2D::new(1, 3),
- Vec2D::new(1, 1)
- ]),
+ HashSet::from([Vec2D::new(2, 2), Vec2D::new(0, 2), Vec2D::new(1, 3), Vec2D::new(1, 1)]),
Vec2D::new(1, 2).orthogonal_neighbors().collect(),
);
assert_eq!(
- HashSet::from([
- Vec2D::new(2, 3),
- Vec2D::new(0, 3),
- Vec2D::new(2, 1),
- Vec2D::new(0, 1)
- ]),
+ HashSet::from([Vec2D::new(2, 3), Vec2D::new(0, 3), Vec2D::new(2, 1), Vec2D::new(0, 1)]),
Vec2D::new(1, 2).diagonal_neighbors().collect(),
);
assert_eq!(