1
1
use array2d:: Array2D ;
2
2
use itertools:: Itertools ;
3
3
4
- const BOARDSIZE : usize = 5 ;
4
+ const BOARDSIZE : usize = 5 ;
5
5
type Board = [ [ u8 ; BOARDSIZE ] ; BOARDSIZE ] ;
6
6
type WinningBoard = usize ;
7
7
@@ -15,7 +15,7 @@ struct Game {
15
15
boards : Vec < Board > ,
16
16
}
17
17
18
- fn parse ( fname : & str ) -> Game {
18
+ fn parse ( fname : & str ) -> Game {
19
19
let input = std:: fs:: read_to_string ( fname) . unwrap ( ) ;
20
20
let mut lines = input. lines ( ) ;
21
21
let draws: Vec < u8 > = lines
@@ -24,48 +24,57 @@ fn parse(fname:&str) -> Game {
24
24
. split ( "," )
25
25
. filter_map ( |draw_str| draw_str. parse ( ) . ok ( ) )
26
26
. collect ( ) ;
27
- let boards: Vec < [ [ u8 ; 5 ] ; 5 ] > = lines
27
+ let boards: Vec < [ [ u8 ; 5 ] ; 5 ] > = lines
28
28
. filter ( |& line_str| !line_str. is_empty ( ) )
29
29
. chunks ( 5 )
30
30
. into_iter ( )
31
- . map (
32
- |chunk_line_iter| {
33
- chunk_line_iter
34
- . map (
35
- | board_row_str | {
36
- board_row_str
37
- . split_ascii_whitespace ( )
38
- . filter_map ( |entry| entry. parse :: < u8 > ( ) . ok ( ) )
39
- . collect :: < Vec < u8 > > ( )
40
- . try_into ( )
41
- . unwrap ( )
42
- }
43
- )
44
- . collect :: < Vec < [ u8 ; 5 ] > > ( )
31
+ . map ( |chunk_line_iter| {
32
+ chunk_line_iter
33
+ . map ( |board_row_str| {
34
+ board_row_str
35
+ . split_ascii_whitespace ( )
36
+ . filter_map ( |entry| entry. parse :: < u8 > ( ) . ok ( ) )
37
+ . collect :: < Vec < u8 > > ( )
38
+ . try_into ( )
39
+ . unwrap ( )
40
+ } )
41
+ . collect :: < Vec < [ u8 ; 5 ] > > ( )
45
42
. try_into ( )
46
43
. unwrap ( )
47
- }
48
- )
44
+ } )
49
45
. collect ( ) ;
50
- Game { draws : draws, boards : boards }
46
+ Game {
47
+ draws : draws,
48
+ boards : boards,
49
+ }
51
50
}
52
51
fn check_win ( state : & mut BoardState ) -> bool {
53
- let row_win = state. filled . as_rows ( ) . iter ( ) . map ( |row| row. iter ( ) . all ( |& v| v) ) . any ( |rows| rows) ;
54
- let col_win = state. filled . as_columns ( ) . iter ( ) . map ( |col| col. iter ( ) . all ( |& v| v) ) . any ( |cols| cols) ;
52
+ let row_win = state
53
+ . filled
54
+ . as_rows ( )
55
+ . iter ( )
56
+ . map ( |row| row. iter ( ) . all ( |& v| v) )
57
+ . any ( |rows| rows) ;
58
+ let col_win = state
59
+ . filled
60
+ . as_columns ( )
61
+ . iter ( )
62
+ . map ( |col| col. iter ( ) . all ( |& v| v) )
63
+ . any ( |cols| cols) ;
55
64
row_win | col_win
56
65
}
57
66
58
- fn play_round ( draw : u8 , boards : & Vec < Board > , states : & mut [ BoardState ] ) -> Option < WinningBoard > {
59
- let mut last_win: Option < WinningBoard > = None ;
67
+ fn play_round ( draw : u8 , boards : & Vec < Board > , states : & mut [ BoardState ] ) -> Option < WinningBoard > {
68
+ let mut last_win: Option < WinningBoard > = None ;
60
69
for ( board_num, & board) in boards. iter ( ) . enumerate ( ) {
61
70
if states[ board_num] . won {
62
71
continue ;
63
72
}
64
- ' board: for ( i, & row) in board. iter ( ) . enumerate ( ) {
65
- for ( j, & col) in row. iter ( ) . enumerate ( ) {
66
- if col== draw {
67
- let _ = states[ board_num] . filled . set ( i, j, true ) . unwrap ( ) ;
68
- if check_win ( & mut states[ board_num] ) {
73
+ ' board: for ( i, & row) in board. iter ( ) . enumerate ( ) {
74
+ for ( j, & col) in row. iter ( ) . enumerate ( ) {
75
+ if col == draw {
76
+ let _ = states[ board_num] . filled . set ( i, j, true ) . unwrap ( ) ;
77
+ if check_win ( & mut states[ board_num] ) {
69
78
states[ board_num] . won = true ;
70
79
last_win = Some ( board_num) ;
71
80
}
@@ -75,57 +84,73 @@ fn play_round(draw:u8, boards:&Vec<Board>, states:&mut [BoardState]) -> Option<W
75
84
}
76
85
}
77
86
last_win
78
- }
87
+ }
79
88
80
- fn sum_of_unmarked ( board : & Board , state : & BoardState ) -> usize {
89
+ fn sum_of_unmarked ( board : & Board , state : & BoardState ) -> usize {
81
90
let mut result: usize = 0 ;
82
91
for ( i, & row) in board. iter ( ) . enumerate ( ) {
83
92
for ( j, & col) in row. iter ( ) . enumerate ( ) {
84
- if !state. filled . get ( i, j) . unwrap ( ) {
93
+ if !state. filled . get ( i, j) . unwrap ( ) {
85
94
result += col as usize ;
86
95
}
87
96
}
88
97
}
89
98
result
90
99
}
91
100
92
- fn part1 ( game : Game ) -> usize {
101
+ fn part1 ( game : Game ) -> usize {
93
102
let num_boards = game. boards . len ( ) ;
94
- let mut board_states: Vec < BoardState > = ( 0 ..num_boards) . map ( |_| BoardState { filled : Array2D :: filled_with ( false , BOARDSIZE , BOARDSIZE ) , won : false } ) . collect :: < Vec < BoardState > > ( ) ;
103
+ let mut board_states: Vec < BoardState > = ( 0 ..num_boards)
104
+ . map ( |_| BoardState {
105
+ filled : Array2D :: filled_with ( false , BOARDSIZE , BOARDSIZE ) ,
106
+ won : false ,
107
+ } )
108
+ . collect :: < Vec < BoardState > > ( ) ;
95
109
for draw in game. draws {
96
110
let result = play_round ( draw, & game. boards , & mut board_states[ ..] ) ;
97
111
if let Some ( winning_board_num) = result {
98
- return sum_of_unmarked ( & game. boards [ winning_board_num] , & board_states[ winning_board_num] ) * ( draw as usize ) ;
112
+ return sum_of_unmarked (
113
+ & game. boards [ winning_board_num] ,
114
+ & board_states[ winning_board_num] ,
115
+ ) * ( draw as usize ) ;
99
116
}
100
117
}
101
118
panic ! ( "nothing won" ) ;
102
119
}
103
120
104
- fn part2 ( game : Game ) -> usize {
121
+ fn part2 ( game : Game ) -> usize {
105
122
let num_boards = game. boards . len ( ) ;
106
- let mut board_states: Vec < BoardState > = ( 0 ..num_boards) . map ( |_| BoardState { filled : Array2D :: filled_with ( false , BOARDSIZE , BOARDSIZE ) , won : false } ) . collect :: < Vec < BoardState > > ( ) ;
107
- let mut last_winning_value: usize = 0 ;
123
+ let mut board_states: Vec < BoardState > = ( 0 ..num_boards)
124
+ . map ( |_| BoardState {
125
+ filled : Array2D :: filled_with ( false , BOARDSIZE , BOARDSIZE ) ,
126
+ won : false ,
127
+ } )
128
+ . collect :: < Vec < BoardState > > ( ) ;
129
+ let mut last_winning_value: usize = 0 ;
108
130
109
131
for draw in game. draws {
110
132
let result = play_round ( draw, & game. boards , & mut board_states[ ..] ) ;
111
133
if let Some ( winning_board_num) = result {
112
- last_winning_value = sum_of_unmarked ( & game. boards [ winning_board_num] , & board_states[ winning_board_num] ) * ( draw as usize ) ;
134
+ last_winning_value = sum_of_unmarked (
135
+ & game. boards [ winning_board_num] ,
136
+ & board_states[ winning_board_num] ,
137
+ ) * ( draw as usize ) ;
113
138
}
114
- }
139
+ }
115
140
last_winning_value
116
141
}
117
142
118
143
#[ test]
119
- fn test_part1 ( ) {
144
+ fn test_part1 ( ) {
120
145
assert_eq ! ( part1( parse( "test0" ) ) , 4512 )
121
146
}
122
147
123
148
#[ test]
124
- fn test_part2 ( ) {
149
+ fn test_part2 ( ) {
125
150
assert_eq ! ( part2( parse( "test0" ) ) , 1924 )
126
151
}
127
152
128
153
fn main ( ) {
129
154
println ! ( "{:?}" , part1( parse( "input" ) ) ) ;
130
155
println ! ( "{:?}" , part2( parse( "input" ) ) ) ;
131
- }
156
+ }
0 commit comments