add 2023/16/2

This commit is contained in:
kageru 2023-12-18 17:06:42 +01:00
parent 07972e3029
commit 2d506e3799
2 changed files with 47 additions and 44 deletions

View File

@ -14,7 +14,7 @@ type Parsed<'a> = Vec<&'a [Tile]>;
#[repr(u8)] #[repr(u8)]
#[allow(dead_code)] #[allow(dead_code)]
#[derive(Debug, PartialEq, Eq)] #[derive(Debug, PartialEq, Eq, Clone, Copy)]
enum Tile { enum Tile {
Empty = b'.', Empty = b'.',
HSplit = b'|', HSplit = b'|',
@ -28,30 +28,49 @@ fn parse_input(raw: &str) -> Parsed {
} }
fn part1(grid: &Parsed) -> usize { fn part1(grid: &Parsed) -> usize {
start(grid, 0, 0, Right)
}
fn part2(grid: &Parsed) -> usize {
(0..grid.len())
.map(|y| (0, y, Right))
.chain((0..grid.len()).map(|y| (grid[0].len() - 1, y, Left)))
.chain((0..grid[0].len()).map(|x| (x, 0, Down)))
.chain((0..grid[0].len()).map(|x| (x, grid.len() - 1, Up)))
.map(|(x, y, dir)| start(grid, x, y, dir))
.max()
.unwrap()
}
fn start(grid: &Parsed, x: usize, y: usize, dir: Direction) -> usize {
let mut points = FnvHashSet::default(); let mut points = FnvHashSet::default();
points.insert((0, 0)); points.insert((x, y));
let mut known = FnvHashSet::default(); let mut known = FnvHashSet::default();
// my real input starts with a mirror, match turn(dir, grid[y][x]) {
// and I don’t want to rewrite the code to not blindly make the first step. (d1, Some(d2)) => {
energized(grid, &mut points, &mut known, 0, 0, if grid[0][0] == Empty { Right } else { Down }); energized(grid, &mut points, &mut known, x, y, d1);
energized(grid, &mut points, &mut known, x, y, d2);
}
(d1, None) => energized(grid, &mut points, &mut known, x, y, d1),
}
points.len() points.len()
} }
fn angle1(dir: Direction) -> Direction { fn turn(dir: Direction, tile: Tile) -> (Direction, Option<Direction>) {
match dir { match (dir, tile) {
Up => Right, (dir, Empty) => (dir, None),
Right => Up, (Up, Angle1) => (Right, None),
Down => Left, (Right, Angle1) => (Up, None),
Left => Down, (Down, Angle1) => (Left, None),
} (Left, Angle1) => (Down, None),
} (Up, Angle2) => (Left, None),
(Left, Angle2) => (Up, None),
fn angle2(dir: Direction) -> Direction { (Down, Angle2) => (Right, None),
match dir { (Right, Angle2) => (Down, None),
Up => Left, (Left | Right, HSplit) => (Up, Some(Down)),
Left => Up, (dir, HSplit) => (dir, None),
Down => Right, (Up | Down, VSplit) => (Right, Some(Left)),
Right => Down, (dir, VSplit) => (dir, None),
} }
} }
@ -66,36 +85,20 @@ fn energized(
if !known.insert((x, y, dir)) { if !known.insert((x, y, dir)) {
return; return;
} }
if let Some(tile) = try { if let Some(&tile) = try {
y = y.checked_sub((dir == Up) as usize)? + (dir == Down) as usize; y = y.checked_sub((dir == Up) as usize)? + (dir == Down) as usize;
x = x.checked_sub((dir == Left) as usize)? + (dir == Right) as usize; x = x.checked_sub((dir == Left) as usize)? + (dir == Right) as usize;
grid.get(y)?.get(x)? grid.get(y)?.get(x)?
} { } {
points.insert((x, y)); points.insert((x, y));
match (tile, dir) { let (d1, d2) = turn(dir, tile);
(Empty, _) => { energized(grid, points, known, x, y, d1);
energized(grid, points, known, x, y, dir); if let Some(d2) = d2 {
} energized(grid, points, known, x, y, d2);
(Angle1, _) => energized(grid, points, known, x, y, angle1(dir)),
(Angle2, _) => energized(grid, points, known, x, y, angle2(dir)),
(HSplit, Up | Down) => energized(grid, points, known, x, y, dir),
(HSplit, Left | Right) => {
energized(grid, points, known, x, y, Up);
energized(grid, points, known, x, y, Down);
}
(VSplit, Up | Down) => {
energized(grid, points, known, x, y, Right);
energized(grid, points, known, x, y, Left);
}
(VSplit, Left | Right) => energized(grid, points, known, x, y, dir),
} }
} }
} }
fn part2(parsed: &Parsed) -> usize {
unimplemented!()
}
boilerplate! { boilerplate! {
TEST_INPUT == r".|...\.... TEST_INPUT == r".|...\....
|.-.\..... |.-.\.....
@ -109,9 +112,9 @@ boilerplate! {
..//.|...." ..//.|...."
for tests: { for tests: {
part1: { TEST_INPUT => 46 }, part1: { TEST_INPUT => 46 },
part2: { TEST_INPUT => 0 }, part2: { TEST_INPUT => 51 },
}, },
bench1 == 7517, bench1 == 7517,
bench2 == 0, bench2 == 7741,
bench_parse: Vec::len => 110, bench_parse: Vec::len => 110,
} }

View File

@ -3,7 +3,7 @@ use std::{
fmt::Display, fmt::Display,
iter::Step, iter::Step,
ops::{Add, Mul}, ops::{Add, Mul},
str::FromStr, mem::transmute, str::FromStr,
}; };
pub fn read_file(day: usize) -> String { pub fn read_file(day: usize) -> String {