2022/22/1, except it doesn’t work
This commit is contained in:
parent
5a8c34ccf8
commit
1b75458f75
@ -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,
|
||||
}
|
||||
|
@ -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| {
|
||||
|
@ -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 {
|
||||
|
Loading…
Reference in New Issue
Block a user