vectors: return value instead of reference
There was no use-case for returning reference rather than a value and in majority of case the dereference was needed. When using 2D/3D vectors, they are mostly initialized with the numbers and it is contraproductive to pass around references to numbers as they are more expensive than the copies. Signed-off-by: Matej Focko <me@mfocko.xyz>
This commit is contained in:
parent
f151a9a785
commit
06243918fc
6 changed files with 57 additions and 55 deletions
|
@ -116,13 +116,13 @@ impl Solution<Input, Output> for Day14 {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn part_1(input: &Input) -> Output {
|
fn part_1(input: &Input) -> Output {
|
||||||
let max_y = *input
|
let max_y = input
|
||||||
.iter()
|
.iter()
|
||||||
.map(|l| max(l.from.y(), l.to.y()))
|
.map(|l| max(l.from.y(), l.to.y()))
|
||||||
.max()
|
.max()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let terminate = |grain: &Coord, _is_set: bool| *grain.y() >= max_y;
|
let terminate = |grain: &Coord, _is_set: bool| grain.y() >= max_y;
|
||||||
|
|
||||||
simulate_falling(input, terminate)
|
simulate_falling(input, terminate)
|
||||||
}
|
}
|
||||||
|
@ -140,8 +140,8 @@ impl Solution<Input, Output> for Day14 {
|
||||||
|
|
||||||
let mut lines = input.clone();
|
let mut lines = input.clone();
|
||||||
lines.push(Line {
|
lines.push(Line {
|
||||||
from: Coord::new(500 - (*y + 2), *y + 2),
|
from: Coord::new(500 - (y + 2), y + 2),
|
||||||
to: Coord::new(500 + (*y + 2), *y + 2),
|
to: Coord::new(500 + (y + 2), y + 2),
|
||||||
});
|
});
|
||||||
|
|
||||||
simulate_falling(&lines, terminate)
|
simulate_falling(&lines, terminate)
|
||||||
|
|
|
@ -15,7 +15,7 @@ type Coord = Vector2D<i32>;
|
||||||
|
|
||||||
fn manhattan(u: &Coord, v: &Coord) -> i32 {
|
fn manhattan(u: &Coord, v: &Coord) -> i32 {
|
||||||
let direction = *v - *u;
|
let direction = *v - *u;
|
||||||
(*direction.x()).abs() + (*direction.y()).abs()
|
(direction.x()).abs() + (direction.y()).abs()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq, Clone)]
|
#[derive(Debug, PartialEq, Eq, Clone)]
|
||||||
|
@ -27,12 +27,12 @@ struct Sensor {
|
||||||
impl Sensor {
|
impl Sensor {
|
||||||
fn bounds_at_y(&self, y: i32) -> Option<(Coord, Coord)> {
|
fn bounds_at_y(&self, y: i32) -> Option<(Coord, Coord)> {
|
||||||
let m = manhattan(&self.position, &self.beacon);
|
let m = manhattan(&self.position, &self.beacon);
|
||||||
if y < *self.position.y() - m || y > *self.position.y() + m {
|
if y < self.position.y() - m || y > self.position.y() + m {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
let x = *self.position.x();
|
let x = self.position.x();
|
||||||
let side_d = m - (*self.position.y() - y).abs();
|
let side_d = m - (self.position.y() - y).abs();
|
||||||
|
|
||||||
Some((Coord::new(x - side_d, y), Coord::new(x + side_d, y)))
|
Some((Coord::new(x - side_d, y), Coord::new(x + side_d, y)))
|
||||||
}
|
}
|
||||||
|
@ -79,7 +79,7 @@ fn cannot_contain(sensors: &Input, watched_y: i32) -> Output {
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(|s| s.bounds_at_y(watched_y))
|
.filter_map(|s| s.bounds_at_y(watched_y))
|
||||||
.for_each(|(l, r)| {
|
.for_each(|(l, r)| {
|
||||||
(*l.x()..=*r.x()).for_each(|x| {
|
(l.x()..=r.x()).for_each(|x| {
|
||||||
positions.insert(x, Status::Cannot);
|
positions.insert(x, Status::Cannot);
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
@ -87,14 +87,14 @@ fn cannot_contain(sensors: &Input, watched_y: i32) -> Output {
|
||||||
// rewrite beacons and sensors if needed
|
// rewrite beacons and sensors if needed
|
||||||
sensors
|
sensors
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|s| *s.position.y() == watched_y || *s.beacon.y() == watched_y)
|
.filter(|s| s.position.y() == watched_y || s.beacon.y() == watched_y)
|
||||||
.for_each(|s| {
|
.for_each(|s| {
|
||||||
if *s.beacon.y() == watched_y {
|
if s.beacon.y() == watched_y {
|
||||||
positions.insert(*s.beacon.x(), Status::Beacon);
|
positions.insert(s.beacon.x(), Status::Beacon);
|
||||||
}
|
}
|
||||||
|
|
||||||
if *s.position.y() == watched_y {
|
if s.position.y() == watched_y {
|
||||||
positions.insert(*s.beacon.x(), Status::Sensor);
|
positions.insert(s.beacon.x(), Status::Sensor);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -113,7 +113,7 @@ fn check_row(sensors: &Input, watched_y: i32, upper_bound: i32) -> Vec<(i32, i32
|
||||||
sensors
|
sensors
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(|s| s.bounds_at_y(watched_y))
|
.filter_map(|s| s.bounds_at_y(watched_y))
|
||||||
.map(|(l, r)| (max(0, *l.x()), min(*r.x(), upper_bound))),
|
.map(|(l, r)| (max(0, l.x()), min(r.x(), upper_bound))),
|
||||||
);
|
);
|
||||||
positions.sort();
|
positions.sort();
|
||||||
|
|
||||||
|
|
|
@ -25,9 +25,9 @@ fn get_bounding_box(droplets: &[Coord]) -> (Coord, Coord) {
|
||||||
.iter()
|
.iter()
|
||||||
.fold(Coord::new(i32::MAX, i32::MAX, i32::MAX), |acc, &droplet| {
|
.fold(Coord::new(i32::MAX, i32::MAX, i32::MAX), |acc, &droplet| {
|
||||||
Coord::new(
|
Coord::new(
|
||||||
min(*acc.x(), *droplet.x()),
|
min(acc.x(), droplet.x()),
|
||||||
min(*acc.y(), *droplet.y()),
|
min(acc.y(), droplet.y()),
|
||||||
min(*acc.z(), *droplet.z()),
|
min(acc.z(), droplet.z()),
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
let max_coord =
|
let max_coord =
|
||||||
|
@ -35,9 +35,9 @@ fn get_bounding_box(droplets: &[Coord]) -> (Coord, Coord) {
|
||||||
.iter()
|
.iter()
|
||||||
.fold(Coord::new(i32::MIN, i32::MIN, i32::MIN), |acc, &droplet| {
|
.fold(Coord::new(i32::MIN, i32::MIN, i32::MIN), |acc, &droplet| {
|
||||||
Coord::new(
|
Coord::new(
|
||||||
max(*acc.x(), *droplet.x()),
|
max(acc.x(), droplet.x()),
|
||||||
max(*acc.y(), *droplet.y()),
|
max(acc.y(), droplet.y()),
|
||||||
max(*acc.z(), *droplet.z()),
|
max(acc.z(), droplet.z()),
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -50,9 +50,9 @@ fn _check_bounding_box(droplets: &[Coord]) {
|
||||||
debug!("Bounding box: {:?} <-> {:?}", min_coord, max_coord);
|
debug!("Bounding box: {:?} <-> {:?}", min_coord, max_coord);
|
||||||
debug!(
|
debug!(
|
||||||
"Cubes in a bounding box: {:?}",
|
"Cubes in a bounding box: {:?}",
|
||||||
(*max_coord.x() - *min_coord.x() + 1)
|
(max_coord.x() - min_coord.x() + 1)
|
||||||
* (*max_coord.y() - *min_coord.y() + 1)
|
* (max_coord.y() - min_coord.y() + 1)
|
||||||
* (*max_coord.z() - *min_coord.z() + 1)
|
* (max_coord.z() - min_coord.z() + 1)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -123,9 +123,9 @@ impl Solution<Input, Output> for Day18 {
|
||||||
|
|
||||||
// lava everywhere
|
// lava everywhere
|
||||||
for cube in [
|
for cube in [
|
||||||
*min_coords.x()..=*max_coords.x(),
|
min_coords.x()..=max_coords.x(),
|
||||||
*min_coords.y()..=*max_coords.y(),
|
min_coords.y()..=max_coords.y(),
|
||||||
*min_coords.z()..=*max_coords.z(),
|
min_coords.z()..=max_coords.z(),
|
||||||
]
|
]
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.multi_cartesian_product()
|
.multi_cartesian_product()
|
||||||
|
@ -148,7 +148,7 @@ impl Solution<Input, Output> for Day18 {
|
||||||
// update the outside with the air using a BFS
|
// update the outside with the air using a BFS
|
||||||
aerate(
|
aerate(
|
||||||
&mut space,
|
&mut space,
|
||||||
Coord::new(*min_coords.x(), *min_coords.y(), *min_coords.z()),
|
Coord::new(min_coords.x(), min_coords.y(), min_coords.z()),
|
||||||
);
|
);
|
||||||
|
|
||||||
// count the faces touching the air
|
// count the faces touching the air
|
||||||
|
|
|
@ -146,20 +146,20 @@ fn _show_ground(positions: &Input) {
|
||||||
let min_pos = positions
|
let min_pos = positions
|
||||||
.iter()
|
.iter()
|
||||||
.fold(Vector2D::new(isize::MAX, isize::MAX), |acc, elf| {
|
.fold(Vector2D::new(isize::MAX, isize::MAX), |acc, elf| {
|
||||||
Vector2D::new(min(*acc.x(), *elf.x()), min(*acc.y(), *elf.y()))
|
Vector2D::new(min(acc.x(), elf.x()), min(acc.y(), elf.y()))
|
||||||
});
|
});
|
||||||
let max_pos = positions
|
let max_pos = positions
|
||||||
.iter()
|
.iter()
|
||||||
.fold(Vector2D::new(isize::MIN, isize::MIN), |acc, elf| {
|
.fold(Vector2D::new(isize::MIN, isize::MIN), |acc, elf| {
|
||||||
Vector2D::new(max(*acc.x(), *elf.x()), max(*acc.y(), *elf.y()))
|
Vector2D::new(max(acc.x(), elf.x()), max(acc.y(), elf.y()))
|
||||||
});
|
});
|
||||||
|
|
||||||
_show_ground_with_dimensions(
|
_show_ground_with_dimensions(
|
||||||
positions,
|
positions,
|
||||||
*min_pos.x(),
|
min_pos.x(),
|
||||||
*max_pos.x(),
|
max_pos.x(),
|
||||||
*min_pos.y(),
|
min_pos.y(),
|
||||||
*max_pos.y(),
|
max_pos.y(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -198,12 +198,12 @@ impl Solution<Input, Output> for Day23 {
|
||||||
let min_pos = positions
|
let min_pos = positions
|
||||||
.iter()
|
.iter()
|
||||||
.fold(Vector2D::new(isize::MAX, isize::MAX), |acc, elf| {
|
.fold(Vector2D::new(isize::MAX, isize::MAX), |acc, elf| {
|
||||||
Vector2D::new(min(*acc.x(), *elf.x()), min(*acc.y(), *elf.y()))
|
Vector2D::new(min(acc.x(), elf.x()), min(acc.y(), elf.y()))
|
||||||
});
|
});
|
||||||
let max_pos = positions
|
let max_pos = positions
|
||||||
.iter()
|
.iter()
|
||||||
.fold(Vector2D::new(isize::MIN, isize::MIN), |acc, elf| {
|
.fold(Vector2D::new(isize::MIN, isize::MIN), |acc, elf| {
|
||||||
Vector2D::new(max(*acc.x(), *elf.x()), max(*acc.y(), *elf.y()))
|
Vector2D::new(max(acc.x(), elf.x()), max(acc.y(), elf.y()))
|
||||||
});
|
});
|
||||||
|
|
||||||
(max_pos.x() - min_pos.x() + 1) * (max_pos.y() - min_pos.y() + 1)
|
(max_pos.x() - min_pos.x() + 1) * (max_pos.y() - min_pos.y() + 1)
|
||||||
|
|
|
@ -14,13 +14,22 @@ impl<T> Vector2D<T> {
|
||||||
pub fn new(x: T, y: T) -> Vector2D<T> {
|
pub fn new(x: T, y: T) -> Vector2D<T> {
|
||||||
Vector2D { x, y }
|
Vector2D { x, y }
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn x(&self) -> &T {
|
impl<T: Copy> Vector2D<T> {
|
||||||
&self.x
|
pub fn swap(&self) -> Self {
|
||||||
|
Self {
|
||||||
|
x: self.y,
|
||||||
|
y: self.x,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn y(&self) -> &T {
|
pub fn x(&self) -> T {
|
||||||
&self.y
|
self.x
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn y(&self) -> T {
|
||||||
|
self.y
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,15 +80,6 @@ where
|
||||||
.unwrap_or(false)
|
.unwrap_or(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Copy> Vector2D<T> {
|
|
||||||
pub fn swap(&self) -> Self {
|
|
||||||
Self {
|
|
||||||
x: self.y,
|
|
||||||
y: self.x,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// See: https://github.com/rust-lang/rust/issues/102731
|
// See: https://github.com/rust-lang/rust/issues/102731
|
||||||
// impl<U: From<T>, T> From<Vector2D<T>> for Vector2D<U> {
|
// impl<U: From<T>, T> From<Vector2D<T>> for Vector2D<U> {
|
||||||
// fn from(value: Vector2D<T>) -> Self {
|
// fn from(value: Vector2D<T>) -> Self {
|
||||||
|
|
|
@ -15,17 +15,19 @@ impl<T> Vector3D<T> {
|
||||||
pub fn new(x: T, y: T, z: T) -> Vector3D<T> {
|
pub fn new(x: T, y: T, z: T) -> Vector3D<T> {
|
||||||
Vector3D { x, y, z }
|
Vector3D { x, y, z }
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn x(&self) -> &T {
|
impl<T: Copy> Vector3D<T> {
|
||||||
&self.x
|
pub fn x(&self) -> T {
|
||||||
|
self.x
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn y(&self) -> &T {
|
pub fn y(&self) -> T {
|
||||||
&self.y
|
self.y
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn z(&self) -> &T {
|
pub fn z(&self) -> T {
|
||||||
&self.z
|
self.z
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue