From b746cad9ae3b5d94ab86c4c9e7433ac11fd55031 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20M=C3=BCller?= Date: Wed, 4 Feb 2026 16:59:55 +0100 Subject: [PATCH] Add FromStr trait to Point2 and Point3, and change to i64 --- src/common/geometry.rs | 61 +++++++++++++++++++++--------------- src/solvers/movie_theater.rs | 2 +- src/solvers/playground.rs | 2 +- 3 files changed, 38 insertions(+), 27 deletions(-) diff --git a/src/common/geometry.rs b/src/common/geometry.rs index 4c1cc34..ff3bd22 100644 --- a/src/common/geometry.rs +++ b/src/common/geometry.rs @@ -1,45 +1,56 @@ -#[derive(Hash, PartialEq, Eq, Debug)] -pub struct Point2(pub u64, pub u64); +use std::str::FromStr; + +#[derive(Hash, PartialEq, Eq, Debug, Copy, Clone)] +pub struct Point2(pub i64, pub i64); impl Point2 { const POINT_SPLIT_CHAR: char = ','; - pub fn from_line(line: &str) -> Self { - let p: Vec = line - .split(Self::POINT_SPLIT_CHAR) - .map(|s| { - s.parse() - .expect(&format!("could not create Point2 from line '{line}'")) - }) - .collect(); - Self(p[0], p[1]) - } - pub fn rect_area(&self, other: &Self) -> u64 { (self.0.abs_diff(other.0) + 1) * (self.1.abs_diff(other.1) + 1) } } +impl FromStr for Point2 { + type Err = ParsePointError; + + fn from_str(s: &str) -> Result { + let (x_str, y_str) = s + .split_once(Self::POINT_SPLIT_CHAR) + .ok_or(ParsePointError)?; + let x = x_str.parse::().map_err(|_| ParsePointError)?; + let y = y_str.parse::().map_err(|_| ParsePointError)?; + Ok(Self(x, y)) + } +} + #[derive(Hash, PartialEq, Eq, Debug)] -pub struct Point3(pub u64, pub u64, pub u64); +pub struct Point3(pub i64, pub i64, pub i64); impl Point3 { const POINT_SPLIT_CHAR: char = ','; - pub fn from_line(line: &str) -> Self { - let p: Vec = line - .split(Self::POINT_SPLIT_CHAR) - .map(|s| { - s.parse() - .expect(&format!("could not create Point3 from line '{line}'")) - }) - .collect(); - Self(p[0], p[1], p[2]) - } - pub fn distance_sqr(&self, other: &Self) -> u64 { self.0.abs_diff(other.0).pow(2) + self.1.abs_diff(other.1).pow(2) + self.2.abs_diff(other.2).pow(2) } } + +impl FromStr for Point3 { + type Err = ParsePointError; + + fn from_str(s: &str) -> Result { + let p = s + .split(Self::POINT_SPLIT_CHAR) + .map(|s| s.parse::().map_err(|_| ParsePointError)) + .collect::, Self::Err>>()?; + match p.as_slice() { + [x, y, z] => Ok(Self(*x, *y, *z)), + _ => Err(ParsePointError), + } + } +} + +#[derive(Debug, PartialEq, Eq)] +pub struct ParsePointError; diff --git a/src/solvers/movie_theater.rs b/src/solvers/movie_theater.rs index 9da11b9..dd77f8d 100644 --- a/src/solvers/movie_theater.rs +++ b/src/solvers/movie_theater.rs @@ -9,7 +9,7 @@ impl MovieTheater { fn red_tiles(reader: R) -> Vec { let mut red_tiles = Vec::new(); for line in reader.lines().map_while(Result::ok) { - red_tiles.push(Point2::from_line(&line)); + red_tiles.push(line.parse::().unwrap()); } red_tiles } diff --git a/src/solvers/playground.rs b/src/solvers/playground.rs index 8df16ff..7800639 100644 --- a/src/solvers/playground.rs +++ b/src/solvers/playground.rs @@ -20,7 +20,7 @@ impl Playground { fn junction_boxes(reader: R) -> Vec { let mut junction_boxes = Vec::new(); for line in reader.lines().map_while(Result::ok) { - junction_boxes.push(Point3::from_line(&line)); + junction_boxes.push(line.parse::().unwrap()); } junction_boxes }