Skip to content

Commit 5be1f21

Browse files
committed
Add "new" method and SubAssign implementation
1 parent ae95eb2 commit 5be1f21

File tree

11 files changed

+112
-108
lines changed

11 files changed

+112
-108
lines changed

src/util/grid.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
//! # use aoc::util::point::Point;
88
//!
99
//! let mut grid = Grid::parse("1");
10-
//! let point = Point { x: 0, y: 0 };
10+
//! let point = Point::new(0, 0);
1111
//!
1212
//! let foo = grid[point];
1313
//! assert_eq!(foo, b'1');
@@ -58,7 +58,7 @@ impl<T: Copy + PartialEq> Grid<T> {
5858
let to_point = |index| {
5959
let x = (index as i32) % self.width;
6060
let y = (index as i32) / self.width;
61-
Point { x, y }
61+
Point::new(x, y)
6262
};
6363
self.bytes.iter().position(|&h| h == needle).map(to_point)
6464
}

src/util/point.rs

+60-47
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,13 @@
88
//! ```
99
//! # use aoc::util::point::Point;
1010
//!
11-
//! let a = Point { x: 1, y: 2 };
12-
//! let b = Point { x: 3, y: 4 };
11+
//! let a = Point::new(1, 2);
12+
//! let b = Point::new(3, 4);
1313
//! let k = 2;
1414
//!
15-
//! assert_eq!(a + b, Point { x: 4, y: 6 });
16-
//! assert_eq!(a - b, Point { x: -2, y: -2 });
17-
//! assert_eq!(a * k, Point { x: 2, y: 4 });
15+
//! assert_eq!(a + b, Point::new(4, 6));
16+
//! assert_eq!(a - b, Point::new(-2, -2));
17+
//! assert_eq!(a * k, Point::new(2, 4));
1818
//! ```
1919
//!
2020
//! Additionally there are [`clockwise`] and [`counter_clockwise`] functions for 90 degree rotations
@@ -26,13 +26,13 @@
2626
//! [`manhattan`]: Point::manhattan
2727
//! [`Grid`]: crate::util::grid
2828
use std::hash::{Hash, Hasher};
29-
use std::ops::{Add, AddAssign, Mul, Sub};
29+
use std::ops::{Add, AddAssign, Mul, Sub, SubAssign};
3030

31-
pub const ORIGIN: Point = Point { x: 0, y: 0 };
32-
pub const UP: Point = Point { x: 0, y: -1 };
33-
pub const DOWN: Point = Point { x: 0, y: 1 };
34-
pub const LEFT: Point = Point { x: -1, y: 0 };
35-
pub const RIGHT: Point = Point { x: 1, y: 0 };
31+
pub const ORIGIN: Point = Point::new(0, 0);
32+
pub const UP: Point = Point::new(0, -1);
33+
pub const DOWN: Point = Point::new(0, 1);
34+
pub const LEFT: Point = Point::new(-1, 0);
35+
pub const RIGHT: Point = Point::new(1, 0);
3636
pub const ORTHOGONAL: [Point; 4] = [UP, DOWN, LEFT, RIGHT];
3737

3838
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
@@ -41,46 +41,30 @@ pub struct Point {
4141
pub y: i32,
4242
}
4343

44-
impl Add for Point {
45-
type Output = Point;
46-
44+
impl Point {
4745
#[inline]
48-
fn add(self, rhs: Point) -> Point {
49-
Point { x: self.x + rhs.x, y: self.y + rhs.y }
46+
pub const fn new(x: i32, y: i32) -> Self {
47+
Point { x, y }
5048
}
51-
}
52-
53-
impl Sub for Point {
54-
type Output = Point;
5549

5650
#[inline]
57-
fn sub(self, rhs: Point) -> Point {
58-
Point { x: self.x - rhs.x, y: self.y - rhs.y }
51+
pub fn clockwise(self) -> Point {
52+
Point::new(-self.y, self.x)
5953
}
60-
}
61-
62-
impl Mul<i32> for Point {
63-
type Output = Point;
6454

6555
#[inline]
66-
fn mul(self, rhs: i32) -> Self::Output {
67-
Point { x: self.x * rhs, y: self.y * rhs }
56+
pub fn counter_clockwise(self) -> Point {
57+
Point::new(self.y, -self.x)
6858
}
69-
}
7059

71-
impl AddAssign for Point {
7260
#[inline]
73-
fn add_assign(&mut self, rhs: Point) {
74-
self.x += rhs.x;
75-
self.y += rhs.y;
61+
pub fn manhattan(self, other: Point) -> i32 {
62+
(self.x - other.x).abs() + (self.y - other.y).abs()
7663
}
77-
}
7864

79-
impl Hash for Point {
8065
#[inline]
81-
fn hash<H: Hasher>(&self, hasher: &mut H) {
82-
hasher.write_u32(self.x as u32);
83-
hasher.write_u32(self.y as u32);
66+
pub fn signum(self, other: Point) -> Point {
67+
Point::new((self.x - other.x).signum(), (self.y - other.y).signum())
8468
}
8569
}
8670

@@ -97,24 +81,53 @@ impl From<u8> for Point {
9781
}
9882
}
9983

100-
impl Point {
84+
impl Hash for Point {
10185
#[inline]
102-
pub fn clockwise(self) -> Point {
103-
Point { x: -self.y, y: self.x }
86+
fn hash<H: Hasher>(&self, hasher: &mut H) {
87+
hasher.write_u32(self.x as u32);
88+
hasher.write_u32(self.y as u32);
10489
}
90+
}
91+
92+
impl Add for Point {
93+
type Output = Point;
10594

10695
#[inline]
107-
pub fn counter_clockwise(self) -> Point {
108-
Point { x: self.y, y: -self.x }
96+
fn add(self, rhs: Point) -> Point {
97+
Point::new(self.x + rhs.x, self.y + rhs.y)
10998
}
99+
}
110100

101+
impl AddAssign for Point {
111102
#[inline]
112-
pub fn manhattan(self, other: Point) -> i32 {
113-
(self.x - other.x).abs() + (self.y - other.y).abs()
103+
fn add_assign(&mut self, rhs: Point) {
104+
self.x += rhs.x;
105+
self.y += rhs.y;
114106
}
107+
}
108+
109+
impl Mul<i32> for Point {
110+
type Output = Point;
115111

116112
#[inline]
117-
pub fn signum(self, other: Point) -> Point {
118-
Point { x: (self.x - other.x).signum(), y: (self.y - other.y).signum() }
113+
fn mul(self, rhs: i32) -> Self::Output {
114+
Point::new(self.x * rhs, self.y * rhs)
115+
}
116+
}
117+
118+
impl Sub for Point {
119+
type Output = Point;
120+
121+
#[inline]
122+
fn sub(self, rhs: Point) -> Point {
123+
Point::new(self.x - rhs.x, self.y - rhs.y)
124+
}
125+
}
126+
127+
impl SubAssign for Point {
128+
#[inline]
129+
fn sub_assign(&mut self, rhs: Point) {
130+
self.x -= rhs.x;
131+
self.y -= rhs.y;
119132
}
120133
}

src/year2019/day03.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -90,22 +90,22 @@ pub fn parse(input: &str) -> Input {
9090
match direction {
9191
b'U' => {
9292
for (&y, line) in horizontal.range(end.y..=start.y) {
93-
update(line, Point { x: start.x, y });
93+
update(line, Point::new(start.x, y));
9494
}
9595
}
9696
b'D' => {
9797
for (&y, line) in horizontal.range(start.y..=end.y) {
98-
update(line, Point { x: start.x, y });
98+
update(line, Point::new(start.x, y));
9999
}
100100
}
101101
b'L' => {
102102
for (&x, line) in vertical.range(end.x..=start.x) {
103-
update(line, Point { x, y: start.y });
103+
update(line, Point::new(x, start.y));
104104
}
105105
}
106106
b'R' => {
107107
for (&x, line) in vertical.range(start.x..=end.x) {
108-
update(line, Point { x, y: start.y });
108+
update(line, Point::new(x, start.y));
109109
}
110110
}
111111
_ => unreachable!(),

src/year2020/day11.rs

+9-9
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,14 @@ use std::mem::swap;
1212

1313
const FLOOR: u8 = b'.';
1414
const DIRECTIONS: [Point; 8] = [
15-
Point { x: -1, y: -1 },
16-
Point { x: 0, y: -1 },
17-
Point { x: 1, y: -1 },
18-
Point { x: -1, y: 0 },
19-
Point { x: 1, y: 0 },
20-
Point { x: -1, y: 1 },
21-
Point { x: 0, y: 1 },
22-
Point { x: 1, y: 1 },
15+
Point::new(-1, -1),
16+
Point::new(0, -1),
17+
Point::new(1, -1),
18+
Point::new(-1, 0),
19+
Point::new(1, 0),
20+
Point::new(-1, 1),
21+
Point::new(0, 1),
22+
Point::new(1, 1),
2323
];
2424

2525
struct Seat {
@@ -55,7 +55,7 @@ pub fn simulate(input: &Grid<u8>, part_one: bool, limit: u8) -> u32 {
5555

5656
for y in 0..height {
5757
for x in 0..width {
58-
let point = Point { x, y };
58+
let point = Point::new(x, y);
5959
if input[point] == FLOOR {
6060
continue;
6161
}

src/year2020/day12.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ pub fn parse(input: &str) -> Vec<Command> {
1414

1515
pub fn part1(input: &[Command]) -> i32 {
1616
let mut position = ORIGIN;
17-
let mut direction = Point { x: 1, y: 0 };
17+
let mut direction = Point::new(1, 0);
1818

1919
for &(command, amount) in input {
2020
match command {
@@ -34,7 +34,7 @@ pub fn part1(input: &[Command]) -> i32 {
3434

3535
pub fn part2(input: &[Command]) -> i32 {
3636
let mut position = ORIGIN;
37-
let mut waypoint = Point { x: 10, y: -1 };
37+
let mut waypoint = Point::new(10, -1);
3838

3939
for &(command, amount) in input {
4040
match command {

src/year2020/day17.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ fn boot_process(input: &Grid<u8>, size: i32, base: i32, fourth_dimension: &[i32]
8383
// dimension. This allows six for growth, plus one for padding to prevent needing edge checks.
8484
for x in 0..input.width {
8585
for y in 0..input.height {
86-
if input[Point { x, y }] == b'#' {
86+
if input[Point::new(x, y)] == b'#' {
8787
let index = 7 * base + x + y * stride::Y;
8888
active.push(index as usize);
8989
}

src/year2021/day09.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ pub fn part1(grid: &Grid<u8>) -> u32 {
2626

2727
for x in 0..grid.width {
2828
for y in 0..grid.height {
29-
let point = Point { x, y };
29+
let point = Point::new(x, y);
3030
let cur = grid[point];
3131
let low_point = ORTHOGONAL
3232
.iter()
@@ -49,7 +49,7 @@ pub fn part2(input: &Grid<u8>) -> u32 {
4949

5050
for x in 0..grid.width {
5151
for y in 0..grid.height {
52-
let next = Point { x, y };
52+
let next = Point::new(x, y);
5353
if grid[next] < b'9' {
5454
basins.push(flood_fill(&mut grid, next));
5555
}

src/year2021/day13.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ pub struct Input {
2929
pub fn parse(input: &str) -> Input {
3030
let (prefix, suffix) = input.split_once("\n\n").unwrap();
3131

32-
let points: Vec<_> = prefix.iter_signed().chunk::<2>().map(|[x, y]| Point { x, y }).collect();
32+
let points: Vec<_> = prefix.iter_signed().chunk::<2>().map(|[x, y]| Point::new(x, y)).collect();
3333

3434
let folds: Vec<_> = suffix
3535
.lines()
@@ -103,7 +103,7 @@ fn fold_horizontal(x: i32, p: Point) -> Point {
103103
if p.x < x {
104104
p
105105
} else {
106-
Point { x: 2 * x - p.x, y: p.y }
106+
Point::new(2 * x - p.x, p.y)
107107
}
108108
}
109109

@@ -113,6 +113,6 @@ fn fold_vertical(y: i32, p: Point) -> Point {
113113
if p.y < y {
114114
p
115115
} else {
116-
Point { x: p.x, y: 2 * y - p.y }
116+
Point::new(p.x, 2 * y - p.y)
117117
}
118118
}

src/year2022/day09.rs

+2-11
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ fn simulate<const N: usize>(input: &Input) -> u32 {
5757
let ([x1, y1, x2, y2], pairs) = input;
5858
let width = x2 - x1 + 1;
5959
let height = y2 - y1 + 1;
60-
let start = Point { x: -x1, y: -y1 };
60+
let start = Point::new(-x1, -y1);
6161

6262
let mut distinct = 0;
6363
let mut rope = [start; N];
@@ -70,8 +70,7 @@ fn simulate<const N: usize>(input: &Input) -> u32 {
7070
if !apart(rope[i - 1], rope[i]) {
7171
break;
7272
}
73-
let next = delta(rope[i - 1], rope[i]);
74-
rope[i] += next;
73+
rope[i] += rope[i - 1].signum(rope[i]);
7574
}
7675

7776
let tail = rope[N - 1];
@@ -93,11 +92,3 @@ fn simulate<const N: usize>(input: &Input) -> u32 {
9392
fn apart(a: Point, b: Point) -> bool {
9493
(a.x - b.x).abs() > 1 || (a.y - b.y).abs() > 1
9594
}
96-
97-
/// The [`signum`] function comes in handy to figure out the direction that knots should move.
98-
///
99-
/// [`signum`]: i32::signum
100-
#[inline]
101-
fn delta(a: Point, b: Point) -> Point {
102-
Point { x: (a.x - b.x).signum(), y: (a.y - b.y).signum() }
103-
}

src/year2022/day15.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ pub struct Input {
1313

1414
pub fn parse(input: &str) -> Vec<Input> {
1515
fn helper([x1, y1, x2, y2]: [i32; 4]) -> Input {
16-
let sensor = Point { x: x1, y: y1 };
17-
let beacon = Point { x: x2, y: y2 };
16+
let sensor = Point::new(x1, y1);
17+
let beacon = Point::new(x2, y2);
1818
let manhattan = sensor.manhattan(beacon);
1919
Input { sensor, beacon, manhattan }
2020
}
@@ -112,7 +112,7 @@ pub fn part2_testable(input: &[Input], size: i32) -> u64 {
112112
for &&y in &horizontal {
113113
// Rotate intersection point counter clockwise and scale by 1 / √2
114114
// to return to original coordinates.
115-
let point = Point { x: (x + y) / 2, y: (y - x) / 2 };
115+
let point = Point::new((x + y) / 2, (y - x) / 2);
116116
// As we're mixing overlaps from different boxes there may some spurious false
117117
// positives, so double check all points are within the specified area
118118
// and outside the range of all scanners.

0 commit comments

Comments
 (0)