@@ -10,32 +10,53 @@ defmodule GiantSquid do
1010 Enum . at ( input , 0 )
1111 |> String . split ( "," , trim: true )
1212 |> Enum . map ( & Integer . parse / 1 )
13- |> Enum . map ( fn ( t ) -> elem ( t , 0 ) end )
13+ |> Enum . map ( fn t -> elem ( t , 0 ) end )
1414 end
1515
1616 def parse_board ( board ) do
1717 String . split ( board , "\n " )
18- |> Enum . map ( fn ( board ) ->
18+ |> Enum . map ( fn board ->
1919 String . replace ( board , " " , " " )
2020 |> String . split ( " " , trim: true )
2121 |> Enum . map ( & Integer . parse / 1 )
22- |> Enum . map ( fn ( t ) -> elem ( t , 0 ) end )
23- |> Enum . map ( fn ( col ) -> { col , false } end )
22+ |> Enum . map ( fn t -> elem ( t , 0 ) end )
23+ |> Enum . map ( fn col -> { col , false } end )
2424 end )
2525 end
2626
2727 def play_bingo ( boards , [ drawn | tail ] ) do
28- boards_after_game = Enum . map ( boards , & ( apply_drawn_number ( & 1 , drawn ) ) )
28+ boards_after_game = Enum . map ( boards , & apply_drawn_number ( & 1 , drawn ) )
2929 winner = Enum . find ( boards_after_game , false , & has_bingo / 1 )
3030 if winner , do: { winner , drawn } , else: play_bingo ( boards_after_game , tail )
3131 end
3232
33- def play_bingo ( board , [ drawn ] ) , do: apply_drawn_number ( board , drawn )
3433 def play_bingo ( board , [ ] ) , do: board
3534
35+ def play_all_drawn_numbers ( boards , [ drawn | tail ] ) do
36+ boards_after_game =
37+ Enum . map ( boards , fn { data , elements_left , won_with } = board ->
38+ { apply_drawn_number ( elem ( board , 0 ) , drawn ) , elements_left , won_with }
39+ end )
40+ |> Enum . map ( fn { data , elements_left , won_with } = board ->
41+ if has_bingo ( data ) and ! won_with do
42+ { data , Enum . count ( tail ) + 1 , drawn }
43+ else
44+ board
45+ end
46+ end )
47+ 48+ if Enum . all? ( Enum . map ( boards , & ( elem ( & 1 , 2 ) ) ) ) do
49+ boards
50+ else
51+ play_all_drawn_numbers ( boards_after_game , tail )
52+ end
53+ end
54+ 55+ def play_all_drawn_numbers ( boards , [ ] ) , do: boards
56+ 3657 def apply_drawn_number ( board , num ) do
37- Enum . map ( board , fn ( row ) ->
38- Enum . map ( row , fn ( { value , matched } ) ->
58+ Enum . map ( board , fn row ->
59+ Enum . map ( row , fn { value , matched } ->
3960 if value == num , do: { value , true } , else: { value , matched }
4061 end )
4162 end )
@@ -44,14 +65,17 @@ defmodule GiantSquid do
4465 def row_has_bingo ( row ) , do: Enum . all? ( row )
4566
4667 def has_bingo ( board ) do
47- matched_matrix = Enum . map ( board , fn ( row ) ->
48- Enum . map ( row , fn ( { value , matched } ) -> matched end )
49- end )
68+ matched_matrix =
69+ Enum . map ( board , fn row ->
70+ Enum . map ( row , fn { value , matched } -> matched end )
71+ end )
5072
5173 row_bingo = Enum . any? ( matched_matrix , & row_has_bingo / 1 )
52- col_bingo = Enum . zip ( matched_matrix )
53- |> Enum . map ( & Tuple . to_list / 1 )
54- |> Enum . any? ( & row_has_bingo / 1 )
74+ 75+ col_bingo =
76+ Enum . zip ( matched_matrix )
77+ |> Enum . map ( & Tuple . to_list / 1 )
78+ |> Enum . any? ( & row_has_bingo / 1 )
5579
5680 row_bingo or col_bingo
5781 end
@@ -63,20 +87,42 @@ defmodule GiantSquid do
6387
6488 @ spec first ( ) :: Integer
6589 def first ( ) do
66- drawn = load_file |> drawn_numbers
67- boards = load_file |> parse_boards
90+ drawn = load_file ( ) |> drawn_numbers
91+ boards = load_file ( ) |> parse_boards
6892 { winner , last_drawn } = play_bingo ( boards , drawn )
69- undrawn_sum = List . flatten ( winner )
70- |> Enum . filter ( fn ( { _ , was_drawn } ) -> ! was_drawn end )
71- |> Enum . map ( & ( elem ( & 1 , 0 ) ) )
72- |> Enum . sum ( )
73- 74- undrawn_sum * last_drawn
7593
94+ undrawn_sum =
95+ List . flatten ( winner )
96+ |> Enum . filter ( fn { _ , was_drawn } -> ! was_drawn end )
97+ |> Enum . map ( & elem ( & 1 , 0 ) )
98+ |> Enum . sum ( )
7699
100+ undrawn_sum * last_drawn
77101 end
78102
79103 @ spec second ( ) :: Integer
80104 def second ( ) do
105+ drawn = load_file |> drawn_numbers
106+ 107+ boards =
108+ load_file ( )
109+ |> parse_boards
110+ |> Enum . map ( fn board -> { board , nil , nil } end )
111+ 112+ boards_after_games =
113+ play_all_drawn_numbers ( boards , drawn )
114+ |> Enum . sort_by ( & elem ( & 1 , 1 ) )
115+ 116+ { data , _ , last_drawn } = board = Enum . at ( boards_after_games , 0 )
117+ 118+ undrawn_sum =
119+ List . flatten ( data )
120+ |> Enum . filter ( fn { _ , was_drawn } -> ! was_drawn end )
121+ |> Enum . map ( & elem ( & 1 , 0 ) )
122+ |> Enum . sum ( )
123+ 124+ undrawn_sum * last_drawn
125+ 126+ 81127 end
82128end
0 commit comments