2022-12-22 15:10:00 +01:00
#![ feature(test) ]
extern crate test ;
2022-12-22 20:22:42 +01:00
use std ::fmt ;
2022-12-22 15:10:00 +01:00
use aoc2022 ::{
boilerplate ,
common ::* ,
2022-12-22 20:22:42 +01:00
grid ::{ draw_ascii , Direction , Grid , HashGrid , PositionND } ,
2022-12-22 15:10:00 +01:00
} ;
const DAY : usize = 22 ;
2022-12-22 20:22:42 +01:00
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 )
}
}
2022-12-22 15:10:00 +01:00
#[ derive(Copy, Clone, Debug) ]
2022-12-22 20:22:42 +01:00
enum Turn {
Left ,
Right ,
None ,
2022-12-22 15:10:00 +01:00
}
fn parse_input ( raw : & str ) -> Parsed {
let ( maze , moves ) = raw . split_once ( " \n \n " ) . unwrap ( ) ;
let grid = maze
. lines ( )
. zip ( 1 .. )
2022-12-22 20:22:42 +01:00
. 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 )
} )
} )
2022-12-22 15:10:00 +01:00
. collect ( ) ;
let moves = moves
. split_inclusive ( [ 'L' , 'R' ] )
. map ( | s | s . split_at ( s . len ( ) - 1 ) )
2022-12-22 20:22:42 +01:00
. map ( | ( n , d ) | if n = = " " { ( parse_num ( d ) , Turn ::None ) } else { ( parse_num ( n ) , if d = = " L " { Turn ::Left } else { Turn ::Right } ) } )
2022-12-22 15:10:00 +01:00
. collect ( ) ;
( grid , moves )
}
2022-12-22 20:22:42 +01:00
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 )
2022-12-22 15:10:00 +01:00
}
fn part2 ( parsed : & Parsed ) -> usize {
unimplemented! ( )
}
boilerplate! {
2022-12-22 20:22:42 +01:00
TEST_INPUT = = " ...#
2022-12-22 15:10:00 +01:00
. #..
#.. .
.. ..
.. . #.. .. .. . #
.. .. .. .. #.. .
.. #.. .. #.. ..
.. .. .. .. .. #.
.. . #.. ..
.. .. . #..
. #.. .. ..
.. .. .. #.
10 R5L5R10L4R5L5 " ,
tests : {
2022-12-22 20:22:42 +01:00
part1 : { TEST_INPUT = > 6032 } ,
2022-12-22 15:10:00 +01:00
part2 : { TEST_INPUT = > 0 } ,
} ,
2022-12-22 20:22:42 +01:00
bench1 = = 0 , // 123047 too high
2022-12-22 15:10:00 +01:00
bench2 = = 0 ,
2022-12-22 20:22:42 +01:00
bench_parse : | ( g , i ) : & Parsed | g . len ( ) + i . len ( ) = > 17001 ,
2022-12-22 15:10:00 +01:00
}