@@ -66,6 +66,8 @@ pub fn solve_small(task: Task) -> Vec<Command> {
6666 Point :: new( 0 , 1 ) ,
6767 ] ) ;
6868 let mut hand_count = 0 ;
69+ let mut fast_wheel_count = 0 ;
70+ let mut fast_wheel_turns = 0 ;
6971
7072 while remaining > 0 {
7173 while hand_count > 0 && !new_bodies. is_empty ( ) {
@@ -74,16 +76,26 @@ pub fn solve_small(task: Task) -> Vec<Command> {
7476 bodies_diff. push ( new_hand) ;
7577 res. push ( Command :: NewHand ( new_hand) ) ;
7678 }
79+ if fast_wheel_count > 0 && fast_wheel_turns == 0 {
80+ fast_wheel_count -= 1 ;
81+ res. push ( Command :: FastWheel ) ;
82+ fast_wheel_turns = 50 ;
83+ }
7784
78- let mut data: Matrix < Option < Move > > = Matrix :: new ( width, height, None ) ;
85+ let mut data: Matrix < Option < ( Move , usize ) > > = Matrix :: new ( width, height, None ) ;
7986 let mut queue = VecDeque :: new ( ) ;
8087 queue. push_back ( cp) ;
81- data. set ( cp, Some ( Move :: Noop ) ) ;
88+ data. set ( cp, Some ( ( Move :: Noop , 0 ) ) ) ;
8289 let mut reached = false ;
8390 while let Some ( c) = queue. pop_front ( ) {
91+ let cost = match data. get ( c) {
92+ Some ( Some ( ( _, cost) ) ) => * cost,
93+ _ => panic ! ( "no data is expected" ) ,
94+ } ;
95+
8496 let bodies = bodies_diff
8597 . iter ( )
86- . map ( |diff| c. add ( diff) )
98+ . map ( |diff| c. add ( * diff) )
8799 . collect :: < Vec < _ > > ( ) ;
88100 let not_passed = bodies. iter ( ) . any ( |p| {
89101 if let Some ( false ) = passed. get ( * p) {
@@ -102,18 +114,29 @@ pub fn solve_small(task: Task) -> Vec<Command> {
102114 let mut local_cmds = Vec :: new ( ) ;
103115 let mut iter = c;
104116 while iter != cp {
105- if let Some ( Some ( BoosterType :: NewHand ) ) = booster_map. get ( iter) {
106- booster_map. set ( iter, None ) ;
107- hand_count += 1 ;
117+ match booster_map. get ( iter) {
118+ Some ( Some ( BoosterType :: NewHand ) ) => {
119+ booster_map. set ( iter, None ) ;
120+ hand_count += 1 ;
121+ }
122+ Some ( Some ( BoosterType :: FastMove ) ) => {
123+ booster_map. set ( iter, None ) ;
124+ fast_wheel_count += 1 ;
125+ }
126+ _ => { }
108127 }
109- if let Some ( Some ( mv) ) = data. get ( iter) {
128+ let ( mv, cost) = match data. get ( iter) {
129+ Some ( Some ( ( mv, cost) ) ) => ( mv, cost) ,
130+ _ => panic ! ( "no data" ) ,
131+ } ;
132+ iter = iter. revert_with ( mv) ;
133+ if * cost - 1 < fast_wheel_turns {
110134 iter = iter. revert_with ( mv) ;
111- local_cmds. push ( Command :: Move ( mv. clone ( ) ) ) ;
112- } else {
113- panic ! ( "cannot revert command" ) ;
114135 }
136+ local_cmds. push ( Command :: Move ( mv. clone ( ) ) ) ;
115137 }
116138 local_cmds. reverse ( ) ;
139+ fast_wheel_count -= std:: cmp:: min ( fast_wheel_count, local_cmds. len ( ) ) ;
117140 res. extend ( local_cmds) ;
118141
119142 cp = c;
@@ -122,10 +145,14 @@ pub fn solve_small(task: Task) -> Vec<Command> {
122145 }
123146 moves. shuffle ( & mut rng) ;
124147 for m in & moves {
125- let nc = c. move_with ( m) ;
148+ let nc = if cost < fast_wheel_turns {
149+ c. move_with ( m) . move_with ( m)
150+ } else {
151+ c. move_with ( m)
152+ } ;
126153 if let Some ( None ) = data. get ( nc) {
127154 if let Some ( true ) = valid. get ( nc) {
128- data. set ( nc, Some ( m. clone ( ) ) ) ;
155+ data. set ( nc, Some ( ( m. clone ( ) , cost + 1 ) ) ) ;
129156 queue. push_back ( nc) ;
130157 }
131158 }
0 commit comments