@@ -12,93 +12,68 @@ type Result<T> = ::std::result::Result<T, Box<dyn Error>>;
1212fn parse_input < T : AsRef < str > > ( input : T ) -> Vec < Vec < char > > {
1313 input
1414 . as_ref ( )
15- . trim ( )
1615 . split_whitespace ( )
1716 . map ( |l| l. chars ( ) . collect ( ) )
1817 . collect ( )
1918}
2019
21- fn roll_west ( platform : & mut [ Vec < char > ] ) {
22- for j in 1 ..platform[ 0 ] . len ( ) {
23- for i in 0 ..platform. len ( ) {
24- if platform[ i] [ j] != 'O' {
25- continue ;
26- }
27- let mut n_j = j - 1 ;
28- while platform[ i] [ n_j] == '.' {
29- platform[ i] [ n_j + 1 ] = '.' ;
30- platform[ i] [ n_j] = 'O' ;
31- if n_j == 0 {
32- break ;
33- }
34- n_j -= 1 ;
35- }
36- }
37- }
38- }
39- fn roll_east ( platform : & mut [ Vec < char > ] ) {
40- for j in ( 0 ..platform[ 0 ] . len ( ) - 1 ) . rev ( ) {
41- for i in 0 ..platform. len ( ) {
42- if platform[ i] [ j] != 'O' {
43- continue ;
44- }
45- let mut n_j = j + 1 ;
46- while platform[ i] [ n_j] == '.' {
47- platform[ i] [ n_j - 1 ] = '.' ;
48- platform[ i] [ n_j] = 'O' ;
49- if n_j == platform[ 0 ] . len ( ) - 1 {
50- break ;
51- }
52- n_j += 1 ;
53- }
54- }
55- }
20+ #[ derive( Debug , Clone , Copy ) ]
21+ enum Direction {
22+ North ,
23+ South ,
24+ West ,
25+ East ,
5626}
5727
58- fn roll_south ( platform : & mut [ Vec < char > ] ) {
59- for i in ( 0 ..platform. len ( ) - 1 ) . rev ( ) {
60- for j in 0 ..platform[ 0 ] . len ( ) {
61- if platform[ i] [ j] != 'O' {
62- continue ;
63- }
64- let mut n_i = i + 1 ;
65- while platform[ n_i] [ j] == '.' {
66- platform[ n_i - 1 ] [ j] = '.' ;
67- platform[ n_i] [ j] = 'O' ;
68- if n_i == platform. len ( ) - 1 {
69- break ;
70- }
71- n_i += 1 ;
72- }
73- }
28+ fn next_pos ( pos : ( usize , usize ) , dir : Direction ) -> Option < ( usize , usize ) > {
29+ match dir {
30+ Direction :: North => pos. 0 . checked_sub ( 1 ) . map ( |i| ( i, pos. 1 ) ) ,
31+ Direction :: South => Some ( ( pos. 0 + 1 , pos. 1 ) ) ,
32+ Direction :: West => pos. 1 . checked_sub ( 1 ) . map ( |j| ( pos. 0 , j) ) ,
33+ Direction :: East => Some ( ( pos. 0 , pos. 1 + 1 ) ) ,
7434 }
7535}
7636
77- fn roll_north ( platform : & mut [ Vec < char > ] ) {
78- for i in 1 ..platform. len ( ) {
79- for j in 0 ..platform[ 0 ] . len ( ) {
37+ fn roll ( platform : & mut [ Vec < char > ] , dir : Direction ) {
38+ let ( height, width) = ( platform. len ( ) , platform[ 0 ] . len ( ) ) ;
39+ let ( rows, columns) : ( Vec < _ > , Vec < _ > ) = match dir {
40+ Direction :: North => ( ( 1 ..height) . collect ( ) , ( 0 ..width) . collect ( ) ) ,
41+ Direction :: South => ( ( 0 ..height - 1 ) . rev ( ) . collect ( ) , ( 0 ..width) . collect ( ) ) ,
42+ Direction :: West => ( ( 0 ..height) . collect ( ) , ( 1 ..width) . collect ( ) ) ,
43+ Direction :: East => ( ( 0 ..height) . collect ( ) , ( 0 ..width - 1 ) . rev ( ) . collect ( ) ) ,
44+ } ;
45+ for & i in & rows {
46+ for & j in & columns {
8047 if platform[ i] [ j] != 'O' {
8148 continue ;
8249 }
83- let mut n_i = i - 1 ;
84- while platform[ n_i] [ j] == '.' {
85- platform[ n_i + 1 ] [ j] = '.' ;
86- platform[ n_i] [ j] = 'O' ;
87- if n_i == 0 {
88- break ;
50+
51+ let mut prev = ( i, j) ;
52+ let mut curr = next_pos ( ( i, j) , dir) . unwrap ( ) ;
53+
54+ while platform[ curr. 0 ] [ curr. 1 ] == '.' {
55+ platform[ prev. 0 ] [ prev. 1 ] = '.' ;
56+ platform[ curr. 0 ] [ curr. 1 ] = 'O' ;
57+ if let Some ( temp) = next_pos ( curr, dir) {
58+ if temp. 0 < height && temp. 1 < width {
59+ prev = curr;
60+ curr = temp;
61+ continue ;
62+ }
8963 }
90- n_i -= 1 ;
64+ break ;
9165 }
9266 }
9367 }
9468}
9569
9670fn spin ( platform : & mut [ Vec < char > ] , cycle : usize ) {
71+ use Direction :: * ;
9772 for _ in 0 ..cycle {
98- roll_north ( platform) ;
99- roll_west ( platform) ;
100- roll_south ( platform) ;
101- roll_east ( platform) ;
73+ roll ( platform, North ) ;
74+ roll ( platform, West ) ;
75+ roll ( platform, South ) ;
76+ roll ( platform, East ) ;
10277 }
10378}
10479
@@ -114,7 +89,7 @@ fn calc(platform: &[Vec<char>]) -> usize {
11489fn part1 ( mut platform : Vec < Vec < char > > ) -> Result < usize > {
11590 let _start = Instant :: now ( ) ;
11691
117- roll_north ( & mut platform) ;
92+ roll ( & mut platform, Direction :: North ) ;
11893
11994 let result = calc ( & platform) ;
12095 writeln ! ( io:: stdout( ) , "Part 1: {result}" ) ?;
0 commit comments