2022/22/1, except it doesn’t work
This commit is contained in:
parent
5a8c34ccf8
commit
1b75458f75
|
@ -1,19 +1,36 @@
|
||||||
#![feature(test)]
|
#![feature(test)]
|
||||||
extern crate test;
|
extern crate test;
|
||||||
|
use std::fmt;
|
||||||
|
|
||||||
use aoc2022::{
|
use aoc2022::{
|
||||||
boilerplate,
|
boilerplate,
|
||||||
common::*,
|
common::*,
|
||||||
grid::{Grid, HashGrid, PositionND},
|
grid::{draw_ascii, Direction, Grid, HashGrid, PositionND},
|
||||||
};
|
};
|
||||||
|
|
||||||
const DAY: usize = 22;
|
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)]
|
#[derive(Copy, Clone, Debug)]
|
||||||
enum Instruction {
|
enum Turn {
|
||||||
TurnLeft,
|
Left,
|
||||||
TurnRight,
|
Right,
|
||||||
Step(usize),
|
None,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_input(raw: &str) -> Parsed {
|
fn parse_input(raw: &str) -> Parsed {
|
||||||
|
@ -21,17 +38,66 @@ fn parse_input(raw: &str) -> Parsed {
|
||||||
let grid = maze
|
let grid = maze
|
||||||
.lines()
|
.lines()
|
||||||
.zip(1..)
|
.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();
|
.collect();
|
||||||
let moves = moves
|
let moves = moves
|
||||||
.split_inclusive(['L', 'R'])
|
.split_inclusive(['L', 'R'])
|
||||||
.map(|s| s.split_at(s.len() - 1))
|
.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();
|
.collect();
|
||||||
(grid, moves)
|
(grid, moves)
|
||||||
}
|
}
|
||||||
fn part1(parsed: &Parsed) -> usize {
|
fn part1((grid, instructions): &Parsed) -> i64 {
|
||||||
unimplemented!()
|
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 {
|
fn part2(parsed: &Parsed) -> usize {
|
||||||
|
@ -39,8 +105,7 @@ fn part2(parsed: &Parsed) -> usize {
|
||||||
}
|
}
|
||||||
|
|
||||||
boilerplate! {
|
boilerplate! {
|
||||||
TEST_INPUT == "\
|
TEST_INPUT == " ...#
|
||||||
...#
|
|
||||||
.#..
|
.#..
|
||||||
#...
|
#...
|
||||||
....
|
....
|
||||||
|
@ -55,10 +120,10 @@ boilerplate! {
|
||||||
|
|
||||||
10R5L5R10L4R5L5",
|
10R5L5R10L4R5L5",
|
||||||
tests: {
|
tests: {
|
||||||
part1: { TEST_INPUT => 0 },
|
part1: { TEST_INPUT => 6032 },
|
||||||
part2: { TEST_INPUT => 0 },
|
part2: { TEST_INPUT => 0 },
|
||||||
},
|
},
|
||||||
bench1 == 0,
|
bench1 == 0, // 123047 too high
|
||||||
bench2 == 0,
|
bench2 == 0,
|
||||||
bench_parse: |(g, i): &Parsed| g.len() + i.len() => 19002,
|
bench_parse: |(g, i): &Parsed| g.len() + i.len() => 17001,
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,11 @@
|
||||||
pub mod direction;
|
pub mod direction;
|
||||||
pub mod position;
|
pub mod position;
|
||||||
pub use direction::*;
|
pub use direction::*;
|
||||||
|
use fnv::FnvHashMap as HashMap;
|
||||||
use itertools::{join, Itertools, MinMaxResult};
|
use itertools::{join, Itertools, MinMaxResult};
|
||||||
pub use position::*;
|
pub use position::*;
|
||||||
use std::{
|
use std::{
|
||||||
collections::HashMap,
|
|
||||||
fmt::Display,
|
fmt::Display,
|
||||||
hash::BuildHasher,
|
|
||||||
ops::{Index, IndexMut},
|
ops::{Index, IndexMut},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -126,7 +125,7 @@ pub fn get_boundaries(input: &[&PositionND<2>]) -> Boundaries {
|
||||||
Boundaries { x_min, x_max, y_min, y_max }
|
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<_>>());
|
let b = get_boundaries(&coordinates.keys().collect::<Vec<_>>());
|
||||||
join(
|
join(
|
||||||
(b.y_min..=b.y_max).rev().map(|y| {
|
(b.y_min..=b.y_max).rev().map(|y| {
|
||||||
|
|
|
@ -5,10 +5,10 @@ pub const ALL_DIRECTIONS: [Direction; 4] = [Direction::Up, Direction::Down, Dire
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug)]
|
#[derive(Clone, Copy, Debug)]
|
||||||
pub enum Direction {
|
pub enum Direction {
|
||||||
Up,
|
Right = 0,
|
||||||
Down,
|
Down = 1,
|
||||||
Left,
|
Left = 2,
|
||||||
Right,
|
Up = 3,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AddAssign<i8> for Direction {
|
impl AddAssign<i8> for Direction {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user