2022/22/1, except it doesn’t work

This commit is contained in:
kageru 2022-12-22 20:22:42 +01:00
parent 5a8c34ccf8
commit 1b75458f75
Signed by: kageru
GPG Key ID: 8282A2BEA4ADA3D2
3 changed files with 86 additions and 22 deletions

View File

@ -1,19 +1,36 @@
#![feature(test)]
extern crate test;
use std::fmt;
use aoc2022::{
boilerplate,
common::*,
grid::{Grid, HashGrid, PositionND},
grid::{draw_ascii, Direction, Grid, HashGrid, PositionND},
};
const DAY: usize = 22;
type Parsed = (HashGrid<bool, 2>, Vec<Instruction>);
type Parsed = (HashGrid<Field, 2>, Vec<(i64, Turn)>);
#[derive(Copy, Clone, Debug, Default, PartialEq, Eq)]
enum Field {
Empty = b'.' as isize,
Wall = b'#' as isize,
Me = b'O' as isize, // for debug printing the grid
#[default]
Missing = b' ' as isize,
}
impl fmt::Display for Field {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", *self as u8 as char)
}
}
#[derive(Copy, Clone, Debug)]
enum Instruction {
TurnLeft,
TurnRight,
Step(usize),
enum Turn {
Left,
Right,
None,
}
fn parse_input(raw: &str) -> Parsed {
@ -21,17 +38,66 @@ fn parse_input(raw: &str) -> Parsed {
let grid = maze
.lines()
.zip(1..)
.flat_map(|(line, x)| line.bytes().zip(1..).filter(|(b, _)| *b != b' ').map(move |(b, y)| (PositionND::from([x, y]), b == b'#')))
.flat_map(|(line, x)| {
line.bytes().zip(1..).filter(|(b, _)| *b != b' ').map(move |(b, y)| {
let f = match b {
b'.' => Field::Empty,
b'#' => Field::Wall,
_ => unreachable!(),
};
(PositionND::from([x, y]), f)
})
})
.collect();
let moves = moves
.split_inclusive(['L', 'R'])
.map(|s| s.split_at(s.len() - 1))
.flat_map(|(n, d)| [Instruction::Step(parse_num(n)), if d == "L" { Instruction::TurnLeft } else { Instruction::TurnRight }])
.map(|(n, d)| if n == "" { (parse_num(d), Turn::None) } else { (parse_num(n), if d == "L" { Turn::Left } else { Turn::Right }) })
.collect();
(grid, moves)
}
fn part1(parsed: &Parsed) -> usize {
unimplemented!()
fn part1((grid, instructions): &Parsed) -> i64 {
let mut pos = *grid.fields.keys().filter(|p| p.0[0] == 1).min_by_key(|p| p.0[1]).unwrap();
let mut dir = Direction::Right;
let mut grid2 = grid.clone();
grid2[pos] = Field::Me;
println!("{}", draw_ascii(&grid2.fields));
for &(steps, turn) in instructions {
for _ in 0..steps {
let next = PositionND::from(match dir {
Direction::Up => [-1, 0],
Direction::Down => [1, 0],
Direction::Left => [0, -1],
Direction::Right => [0, 1],
}) + pos;
// dbg!(steps, pos, dir, next);
pos = match grid.get(&next) {
Some(Field::Wall) => break,
Some(_) => next,
None => {
println!("Wrapping from {pos:?} in direction {dir:?}");
let (&new_pos, &wall) = match dir {
Direction::Up => grid.fields.iter().filter(|(p, _)| p.0[1] == pos.0[1]).max_by_key(|(p, _)| p.0[0]),
Direction::Down => grid.fields.iter().filter(|(p, _)| p.0[1] == pos.0[1]).min_by_key(|(p, _)| p.0[0]),
Direction::Left => grid.fields.iter().filter(|(p, _)| p.0[0] == pos.0[0]).max_by_key(|(p, _)| p.0[1]),
Direction::Right => grid.fields.iter().filter(|(p, _)| p.0[0] == pos.0[0]).min_by_key(|(p, _)| p.0[1]),
}
.unwrap();
if wall == Field::Wall {
break;
} else {
new_pos
}
}
}
}
dir = match (dir, turn) {
(_, Turn::None) => break,
(d, Turn::Right) => d + 1,
(d, Turn::Left) => d + -1,
};
}
pos.0[0] * 1000 + pos.0[1] * 4 + (dir as i64)
}
fn part2(parsed: &Parsed) -> usize {
@ -39,8 +105,7 @@ fn part2(parsed: &Parsed) -> usize {
}
boilerplate! {
TEST_INPUT == "\
...#
TEST_INPUT == " ...#
.#..
#...
....
@ -55,10 +120,10 @@ boilerplate! {
10R5L5R10L4R5L5",
tests: {
part1: { TEST_INPUT => 0 },
part1: { TEST_INPUT => 6032 },
part2: { TEST_INPUT => 0 },
},
bench1 == 0,
bench1 == 0, // 123047 too high
bench2 == 0,
bench_parse: |(g, i): &Parsed| g.len() + i.len() => 19002,
bench_parse: |(g, i): &Parsed| g.len() + i.len() => 17001,
}

View File

@ -1,12 +1,11 @@
pub mod direction;
pub mod position;
pub use direction::*;
use fnv::FnvHashMap as HashMap;
use itertools::{join, Itertools, MinMaxResult};
pub use position::*;
use std::{
collections::HashMap,
fmt::Display,
hash::BuildHasher,
ops::{Index, IndexMut},
};
@ -126,7 +125,7 @@ pub fn get_boundaries(input: &[&PositionND<2>]) -> Boundaries {
Boundaries { x_min, x_max, y_min, y_max }
}
pub fn draw_ascii<T: Display + Default, S: BuildHasher>(coordinates: &HashMap<PositionND<2>, T, S>) -> String {
pub fn draw_ascii<T: Display + Default>(coordinates: &HashMap<PositionND<2>, T>) -> String {
let b = get_boundaries(&coordinates.keys().collect::<Vec<_>>());
join(
(b.y_min..=b.y_max).rev().map(|y| {

View File

@ -5,10 +5,10 @@ pub const ALL_DIRECTIONS: [Direction; 4] = [Direction::Up, Direction::Down, Dire
#[derive(Clone, Copy, Debug)]
pub enum Direction {
Up,
Down,
Left,
Right,
Right = 0,
Down = 1,
Left = 2,
Up = 3,
}
impl AddAssign<i8> for Direction {