cleanup
This commit is contained in:
parent
2141df8612
commit
3d75d43136
|
@ -4,13 +4,12 @@ use aoc2023::{
|
||||||
boilerplate,
|
boilerplate,
|
||||||
common::*,
|
common::*,
|
||||||
direction::Direction::{self, *},
|
direction::Direction::{self, *},
|
||||||
position::{Position2D, PositionND},
|
|
||||||
};
|
};
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
|
|
||||||
const DAY: usize = 18;
|
const DAY: usize = 18;
|
||||||
type I = isize;
|
type I = isize;
|
||||||
type Pos = Position2D<I>;
|
type Pos = [I; 2];
|
||||||
type Parsed = Vec<((Direction, I), (Direction, I))>;
|
type Parsed = Vec<((Direction, I), (Direction, I))>;
|
||||||
|
|
||||||
fn parse_dir(c: u8) -> Direction {
|
fn parse_dir(c: u8) -> Direction {
|
||||||
|
@ -41,26 +40,27 @@ fn part2(instructions: &Parsed) -> isize {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn solve<'a>(instructions: impl Iterator<Item = &'a (Direction, I)> + Clone) -> isize {
|
fn solve<'a>(instructions: impl Iterator<Item = &'a (Direction, I)> + Clone) -> isize {
|
||||||
let n_points: I = instructions.clone().map(|(_, len)| len).sum();
|
let n_points: isize = instructions.clone().map(|(_, i)| i).sum();
|
||||||
let points: Vec<_> = instructions
|
let points: Vec<_> = instructions.scan([0, 0], |pos, ins| Some(*mov(pos, ins))).collect();
|
||||||
.scan(PositionND([0, 0]), |pos, &(dir, len)| {
|
|
||||||
let movement = PositionND(match dir {
|
|
||||||
Up => [len, 0],
|
|
||||||
Down => [-len, 0],
|
|
||||||
Right => [0, len],
|
|
||||||
Left => [0, -len],
|
|
||||||
});
|
|
||||||
*pos += movement;
|
|
||||||
Some(*pos)
|
|
||||||
})
|
|
||||||
.collect();
|
|
||||||
(2 * area(&points) - n_points + 2) / 2 + n_points
|
(2 * area(&points) - n_points + 2) / 2 + n_points
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline] // I don’t understand why, but inlining this makes a 5% difference
|
||||||
fn area(polygon: &[Pos]) -> isize {
|
fn area(polygon: &[Pos]) -> isize {
|
||||||
polygon.iter().zip(polygon.iter().cycle().skip(1)).map(|(p1, p2)| p1[0] * p2[1] - p1[1] * p2[0]).sum::<I>().abs() >> 1
|
polygon.iter().zip(polygon.iter().cycle().skip(1)).map(|(p1, p2)| p1[0] * p2[1] - p1[1] * p2[0]).sum::<I>().abs() >> 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn mov<'a>(pos: &'a mut Pos, (dir, len): &(Direction, I)) -> &'a Pos {
|
||||||
|
match dir {
|
||||||
|
Up => pos[0] += len,
|
||||||
|
Down => pos[0] -= len,
|
||||||
|
Right => pos[1] += len,
|
||||||
|
Left => pos[1] -= len,
|
||||||
|
};
|
||||||
|
pos
|
||||||
|
}
|
||||||
|
|
||||||
boilerplate! {
|
boilerplate! {
|
||||||
TEST_INPUT == "\
|
TEST_INPUT == "\
|
||||||
R 6 (#70c710)
|
R 6 (#70c710)
|
||||||
|
@ -84,10 +84,10 @@ U 2 (#7a21e3)"
|
||||||
unittests: {
|
unittests: {
|
||||||
area: {
|
area: {
|
||||||
&[
|
&[
|
||||||
PositionND([0, 0]),
|
[0, 0],
|
||||||
PositionND([0, 2]),
|
[0, 2],
|
||||||
PositionND([2, 2]),
|
[2, 2],
|
||||||
PositionND([2, 0]),
|
[2, 0],
|
||||||
] => 4
|
] => 4
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
Loading…
Reference in New Issue
Block a user