@ -5,8 +5,9 @@ use std::fmt;
use aoc2022 ::{
boilerplate ,
common ::* ,
grid ::{ draw_ascii, Direction, Grid , HashGrid , PositionND } ,
grid ::{ Direction, Grid , HashGrid , PositionND } ,
} ;
use itertools ::Itertools ;
const DAY : usize = 22 ;
type Parsed = ( HashGrid < Field , 2 > , Vec < ( i64 , Turn ) > ) ;
@ -15,7 +16,6 @@ type Parsed = (HashGrid<Field, 2>, Vec<(i64, Turn)>);
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 ,
}
@ -52,16 +52,21 @@ fn parse_input(raw: &str) -> Parsed {
let moves = moves
. split_inclusive ( [ 'L' , 'R' ] )
. map ( | s | s . split_at ( s . len ( ) - 1 ) )
. map ( | ( n , d ) | if n = = "" { ( parse_num ( d ) , Turn ::None ) } else { ( parse_num ( n ) , if d = = "L" { Turn ::Left } else { Turn ::Right } ) } )
. collect ( ) ;
. map ( | ( n , d ) | {
let d = match d {
"L" = > Turn ::Left ,
"R" = > Turn ::Right ,
_ = > Turn ::None ,
} ;
( parse_num ( n ) , d )
} )
. collect_vec ( ) ;
debug_assert_eq! ( moves . iter ( ) . filter ( | ( _ , d ) | matches! ( d , Turn ::None ) ) . count ( ) , 1 , "Only the last entry should have no turn" ) ;
( grid , moves )
}
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 {
@ -70,12 +75,10 @@ fn part1((grid, instructions): &Parsed) -> i64 {
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 ] ) ,
@ -97,6 +100,7 @@ fn part1((grid, instructions): &Parsed) -> i64 {
( d , Turn ::Left ) = > d + - 1 ,
} ;
}
println! ( "{pos:?}, {dir:?}" ) ;
pos . 0 [ 0 ] * 1000 + pos . 0 [ 1 ] * 4 + ( dir as i64 )
}
@ -118,12 +122,13 @@ boilerplate! {
. #.. .. ..
.. .. .. #.
10 R5L5R10L4R5L5 " ,
10 R5L5R10L4R5L5
" ,
tests : {
part1 : { TEST_INPUT = > 6032 } ,
part2 : { TEST_INPUT = > 0 } ,
} ,
bench1 = = 0, // 123047 too high
bench1 = = 123046,
bench2 = = 0 ,
bench_parse : | ( g , i ) : & Parsed | g . len ( ) + i . len ( ) = > 17001 ,
}