This commit is contained in:
kageru 2023-12-18 15:34:51 +01:00
parent 2141df8612
commit 3d75d43136

View File

@ -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
} }
}, },