Skip to content

Commit 812b3e0

Browse files
committed
feat: add extend, moved and direction methods to grid line
1 parent 2a2f9ae commit 812b3e0

File tree

11 files changed

+187
-45
lines changed

11 files changed

+187
-45
lines changed

src/solutions/year2023/day25.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,13 +88,12 @@ impl Graph {
8888
.push(to.to_string());
8989
}
9090

91-
#[allow(dead_code)]
91+
#[expect(dead_code)]
9292
fn remove_unidirectional_connection(&mut self, from: &String, to: &String) {
9393
self.remove_directional_connection(from, to);
9494
self.remove_directional_connection(to, from);
9595
}
9696

97-
#[allow(dead_code)]
9897
fn remove_directional_connection(&mut self, from: &String, to: &String) {
9998
let from_connections = self.connections.entry(from.to_string()).or_default();
10099
if let Some(index) = from_connections.iter().position(|f| f == to) {

src/solutions/year2024/day05.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,6 @@ impl From<&str> for Rule {
5858

5959
#[derive(Debug)]
6060
struct Update {
61-
#[allow(dead_code)]
6261
pages: Vec<usize>,
6362
}
6463

src/solutions/year2024/day21.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ impl Day21 {
105105
.iter()
106106
.collect_vec()
107107
.windows(2)
108-
.map(|pair| Dir(pair[0].direction(pair[1]).unwrap()))
108+
.map(|pair| Dir(pair[0].direction(pair[1])))
109109
.collect();
110110
directions.push(Activate);
111111

src/solutions/year2025/day07.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ impl Day07 {
8787
}
8888
}
8989

90-
#[allow(dead_code)]
90+
#[expect(dead_code)]
9191
fn print(grid: &Grid<char>, beams: &[Beam]) {
9292
let mut new = grid.clone();
9393
new.print(beams);

src/utils/deltoid_surface.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
use crate::utils::point::Point;
22

33
pub struct DeltoidSurface {
4-
#[allow(dead_code)]
54
point: Point,
6-
#[allow(dead_code)]
75
distance: usize,
86
}
97

src/utils/grid.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ where
4646
Self::new(cells)
4747
}
4848

49-
#[allow(dead_code)]
49+
#[expect(dead_code)]
5050
pub fn filled(surface_range: SurfaceRange, element: T) -> Self
5151
where
5252
T: Clone,
@@ -178,7 +178,7 @@ where
178178
*self.cells.get_mut(&point).unwrap() = new_value;
179179
}
180180

181-
#[allow(dead_code)]
181+
#[expect(dead_code)]
182182
pub fn modify_many(&mut self, points: Vec<Point>, new_value: T)
183183
where
184184
T: Clone,
@@ -188,7 +188,7 @@ where
188188
}
189189
}
190190

191-
#[allow(dead_code)]
191+
#[expect(dead_code)]
192192
pub fn modify_many_with<F>(&mut self, points: Vec<Point>, mut func: F)
193193
where
194194
F: FnMut(&mut T),
@@ -380,7 +380,7 @@ where
380380
printable.print(self)
381381
}
382382

383-
#[allow(dead_code)]
383+
#[expect(dead_code)]
384384
pub fn all(&self) -> HashMap<Point, T>
385385
where
386386
T: Clone,

src/utils/grid_line.rs

Lines changed: 152 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use crate::utils::direction::Direction;
12
use crate::utils::point::Point;
23
use crate::utils::range::Range;
34

@@ -53,7 +54,7 @@ impl GridLine {
5354
matches!(self, Self::Vertical { .. })
5455
}
5556

56-
#[allow(dead_code)]
57+
#[expect(dead_code)]
5758
pub fn is_horizontal(&self) -> bool {
5859
matches!(self, Self::Horizontal { .. })
5960
}
@@ -87,10 +88,60 @@ impl GridLine {
8788
}
8889
}
8990
}
91+
92+
/// It extends its size by 1 in the direction of orientation
93+
#[expect(dead_code)]
94+
pub fn extend(&self) -> Self {
95+
match self {
96+
GridLine::Horizontal {
97+
y: _,
98+
x_start,
99+
x_end,
100+
} => {
101+
if x_start < x_end {
102+
GridLine::new(self.start().west(), self.end().east()).unwrap()
103+
} else {
104+
GridLine::new(self.start().east(), self.end().west()).unwrap()
105+
}
106+
}
107+
GridLine::Vertical {
108+
x: _,
109+
y_start,
110+
y_end,
111+
} => {
112+
if y_start < y_end {
113+
GridLine::new(self.start().north(), self.end().south()).unwrap()
114+
} else {
115+
GridLine::new(self.start().south(), self.end().north()).unwrap()
116+
}
117+
}
118+
}
119+
}
120+
121+
/// Move line in direction by 1
122+
#[expect(dead_code)]
123+
pub fn moved(&self, direction: Direction) -> Option<Self> {
124+
let start = self.start();
125+
let end = self.end();
126+
127+
match direction {
128+
Direction::North => Self::new(start.north(), end.north()),
129+
Direction::East => Self::new(start.east(), end.east()),
130+
Direction::South => Self::new(start.south(), end.south()),
131+
Direction::West => Self::new(start.west(), end.west()),
132+
_ => unimplemented!("Direction {} unimplemented to move grid line", direction),
133+
}
134+
}
135+
136+
#[expect(dead_code)]
137+
pub fn direction(&self) -> Direction {
138+
self.start().direction(&self.end())
139+
}
90140
}
91141

92142
#[cfg(test)]
93143
mod tests {
144+
use crate::utils::direction::Direction;
94145
use crate::utils::grid_line::GridLine;
95146
use crate::utils::point::Point;
96147

@@ -183,4 +234,104 @@ mod tests {
183234
assert!(!line.is_on(&Point::new(2, 5)));
184235
assert!(!line.is_on(&Point::new(3, 2)));
185236
}
237+
238+
#[test]
239+
fn extend_vertical() {
240+
let line = GridLine::new(Point::new(1, 1), Point::new(4, 1)).unwrap();
241+
let extended = line.extend();
242+
243+
assert_eq!(Point::new(0, 1), extended.start());
244+
assert_eq!(Point::new(5, 1), extended.end());
245+
}
246+
247+
#[test]
248+
fn extend_vertical_reversed() {
249+
let line = GridLine::new(Point::new(5, 1), Point::new(0, 1)).unwrap();
250+
let extended = line.extend();
251+
252+
assert_eq!(Point::new(6, 1), extended.start());
253+
assert_eq!(Point::new(-1, 1), extended.end());
254+
}
255+
256+
#[test]
257+
fn extend_horizontal() {
258+
let line = GridLine::new(Point::new(5, 4), Point::new(5, 11)).unwrap();
259+
let extended = line.extend();
260+
261+
assert_eq!(Point::new(5, 3), extended.start());
262+
assert_eq!(Point::new(5, 12), extended.end());
263+
}
264+
265+
#[test]
266+
fn extend_horizontal_reversed() {
267+
let line = GridLine::new(Point::new(3, 8), Point::new(3, 2)).unwrap();
268+
let extended = line.extend();
269+
270+
assert_eq!(Point::new(3, 9), extended.start());
271+
assert_eq!(Point::new(3, 1), extended.end());
272+
}
273+
274+
#[test]
275+
fn moved_horizontal() {
276+
let line = GridLine::new(Point::new(3, 8), Point::new(3, 2)).unwrap();
277+
let east = line.moved(Direction::East);
278+
279+
assert!(east.is_some());
280+
assert_eq!(
281+
GridLine::new(Point::new(4, 8), Point::new(4, 2)).unwrap(),
282+
east.unwrap()
283+
);
284+
285+
let west = line.moved(Direction::West);
286+
287+
assert!(west.is_some());
288+
assert_eq!(
289+
GridLine::new(Point::new(2, 8), Point::new(2, 2)).unwrap(),
290+
west.unwrap()
291+
);
292+
}
293+
294+
#[test]
295+
fn moved_vertical() {
296+
let line = GridLine::new(Point::new(2, 7), Point::new(7, 7)).unwrap();
297+
let north = line.moved(Direction::North);
298+
299+
assert!(north.is_some());
300+
assert_eq!(
301+
GridLine::new(Point::new(2, 6), Point::new(7, 6)).unwrap(),
302+
north.unwrap()
303+
);
304+
305+
let south = line.moved(Direction::South);
306+
307+
assert!(south.is_some());
308+
assert_eq!(
309+
GridLine::new(Point::new(2, 8), Point::new(7, 8)).unwrap(),
310+
south.unwrap()
311+
);
312+
}
313+
314+
#[test]
315+
fn direction_horizontal_east() {
316+
let line = GridLine::new(Point::new(1, 3), Point::new(4, 3)).unwrap();
317+
assert_eq!(Direction::East, line.direction());
318+
}
319+
320+
#[test]
321+
fn direction_horizontal_west() {
322+
let line = GridLine::new(Point::new(4, 3), Point::new(1, 3)).unwrap();
323+
assert_eq!(Direction::West, line.direction());
324+
}
325+
326+
#[test]
327+
fn direction_vertical_south() {
328+
let line = GridLine::new(Point::new(2, 1), Point::new(2, 4)).unwrap();
329+
assert_eq!(Direction::South, line.direction());
330+
}
331+
332+
#[test]
333+
fn direction_vertical_north() {
334+
let line = GridLine::new(Point::new(2, 4), Point::new(2, 1)).unwrap();
335+
assert_eq!(Direction::North, line.direction());
336+
}
186337
}

src/utils/line.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ impl Line {
4646
Some(Point::new(x as isize, y as isize))
4747
}
4848

49-
#[allow(dead_code)]
49+
#[expect(dead_code)]
5050
pub fn is_on(&self, point: &Point) -> bool {
5151
let a = self.start;
5252
let b = self.end;

src/utils/point.rs

Lines changed: 23 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -115,25 +115,21 @@ impl Point {
115115
self.move_in(SouthWest)
116116
}
117117

118-
pub fn direction(&self, other: &Self) -> Result<Direction, String> {
119-
if !self.is_neighbour(other) {
120-
return Err(format!(
121-
"Point {} is not neighbour for point {}",
122-
self, other
123-
));
118+
pub fn direction(&self, other: &Self) -> Direction {
119+
let diff = *other - *self;
120+
121+
if diff.x == 0 {
122+
return if diff.y > 0 { South } else { North };
124123
}
125124

126-
let diff = *other - *self;
125+
if diff.y == 0 {
126+
return if diff.x > 0 { East } else { West };
127+
}
127128

128-
Ok(match (diff.x, diff.y) {
129-
(0, 1) => South,
130-
(0, -1) => North,
131-
(1, 0) => East,
132-
(-1, 0) => West,
133-
_ => todo!("Implement diagonal directions"),
134-
})
129+
unimplemented!("Diagonal directions are not implemented");
135130
}
136131

132+
#[expect(dead_code)]
137133
fn is_neighbour(&self, other: &Self) -> bool {
138134
let distance = self.distance(other);
139135

@@ -146,12 +142,12 @@ impl Point {
146142
((diff.x.abs().pow(2) + diff.y.abs().pow(2)) as f64).sqrt()
147143
}
148144

149-
#[allow(dead_code)]
145+
#[expect(dead_code)]
150146
pub fn with_y(self, y: isize) -> Self {
151147
Self::new(self.x, y)
152148
}
153149

154-
#[allow(dead_code)]
150+
#[expect(dead_code)]
155151
pub fn with_x(self, x: isize) -> Self {
156152
Self::new(x, self.y)
157153
}
@@ -279,17 +275,16 @@ mod tests {
279275
fn direction() {
280276
let point = Point::new(2, 2);
281277

282-
assert_eq!(
283-
Direction::South,
284-
point.direction(&Point::new(2, 3)).unwrap()
285-
);
286-
assert_eq!(
287-
Direction::North,
288-
point.direction(&Point::new(2, 1)).unwrap()
289-
);
290-
assert_eq!(Direction::West, point.direction(&Point::new(1, 2)).unwrap());
291-
assert_eq!(Direction::East, point.direction(&Point::new(3, 2)).unwrap());
292-
293-
assert!(point.direction(&Point::new(4, 3)).is_err());
278+
// adjacent
279+
assert_eq!(Direction::South, point.direction(&Point::new(2, 3)));
280+
assert_eq!(Direction::North, point.direction(&Point::new(2, 1)));
281+
assert_eq!(Direction::West, point.direction(&Point::new(1, 2)));
282+
assert_eq!(Direction::East, point.direction(&Point::new(3, 2)));
283+
284+
// further
285+
assert_eq!(Direction::South, point.direction(&Point::new(2, 5)));
286+
assert_eq!(Direction::North, point.direction(&Point::new(2, -1)));
287+
assert_eq!(Direction::West, point.direction(&Point::new(-5, 2)));
288+
assert_eq!(Direction::East, point.direction(&Point::new(7, 2)));
294289
}
295290
}

src/utils/range.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -136,12 +136,12 @@ impl Range {
136136
self.iter().collect::<Vec<isize>>().into_iter().rev()
137137
}
138138

139-
#[allow(dead_code)]
139+
#[expect(dead_code)]
140140
pub fn is_before(&self, value: isize) -> bool {
141141
self.start > value
142142
}
143143

144-
#[allow(dead_code)]
144+
#[expect(dead_code)]
145145
pub fn is_after(&self, value: isize) -> bool {
146146
self.end < value
147147
}

0 commit comments

Comments
 (0)