@@ -29,6 +29,7 @@ class BingoBoard {
2929 const rowArr = row . trim ( ) . split ( / \s + / )
3030 return rowArr . map ( ( number ) => new Spot ( number ) )
3131 } )
32+ this . bingoed = false
3233 }
3334
3435 checkAndMark ( calledNumber ) {
@@ -38,12 +39,16 @@ class BingoBoard {
3839 if ( spot . number === calledNumber ) spot . mark ( )
3940 }
4041 }
42+ this . checkBingo ( )
4143 }
4244
43- isBingo ( ) {
45+ checkBingo ( ) {
4446 // any horizontal
4547 for ( const row of this . rows ) {
46- if ( row . every ( ( spot ) => spot . marked ) ) return true
48+ if ( row . every ( ( spot ) => spot . marked ) ) {
49+ this . bingoed = true
50+ return true
51+ }
4752 }
4853 // any vertical
4954 for ( let i = 0 ; i < this . rows [ 0 ] . length ; i ++ ) {
@@ -53,7 +58,11 @@ class BingoBoard {
5358 markCount ++
5459 }
5560 }
56- if ( markCount === this . rows . length ) return true
61+
62+ if ( markCount === this . rows . length ) {
63+ this . bingoed = true
64+ }
65+ return true
5766 }
5867 // not winning board
5968 return false
@@ -72,37 +81,42 @@ class BingoBoard {
7281 }
7382}
7483
75- const data = getRawData ( )
76- const lines = data . split ( '\n' )
77-
78- // initialize
79- let index = 0
80- let callouts
81- let rawBoard = [ ]
82- let boardCollection = [ ]
83- for ( const line of lines ) {
84- if ( index === 0 ) {
85- callouts = line . split ( ',' ) . map ( ( callout ) => Number . parseInt ( callout ) )
86- } else if ( line === '' ) {
87- rawBoard = [ ]
88- } else {
89- rawBoard . push ( line )
90- }
84+ function initialize ( ) {
85+ const data = getRawData ( )
86+ const lines = data . split ( '\n' )
9187
92- if ( rawBoard . length === 5 ) {
93- const bingoBoard = new BingoBoard ( rawBoard )
94- boardCollection . push ( bingoBoard )
95- }
88+ // initialize
89+ let index = 0
90+ let callouts
91+ let rawBoard = [ ]
92+ let boardCollection = [ ]
93+ for ( const line of lines ) {
94+ if ( index === 0 ) {
95+ callouts = line . split ( ',' ) . map ( ( callout ) => Number . parseInt ( callout ) )
96+ } else if ( line === '' ) {
97+ rawBoard = [ ]
98+ } else {
99+ rawBoard . push ( line )
100+ }
96101
97- index ++
102+ if ( rawBoard . length === 5 ) {
103+ const bingoBoard = new BingoBoard ( rawBoard )
104+ boardCollection . push ( bingoBoard )
105+ }
106+
107+ index ++
108+ }
109+ return { callouts, boardCollection }
98110}
99111
100- function runTheGame ( ) {
112+ // Part 1
113+ function fastestWinningScore ( ) {
114+ let { callouts, boardCollection } = initialize ( )
101115 let winningScore
102116 callouts . every ( ( callout , index ) => {
103117 boardCollection . every ( ( board , boardIndex ) => {
104118 board . checkAndMark ( callout )
105- if ( index >= 5 && board . isBingo ( ) ) {
119+ if ( index >= 5 && board . bingoed ) {
106120 const unmarkedSum = board . calcSumOfUnmarked ( )
107121 winningScore = callout * unmarkedSum
108122 console . log (
@@ -120,4 +134,42 @@ function runTheGame() {
120134 return winningScore
121135}
122136
123- runTheGame ( )
137+ fastestWinningScore ( )
138+
139+ // Part 2
140+ function guaranteedLoser ( ) {
141+ let { callouts, boardCollection } = initialize ( )
142+ let losingScore
143+
144+ callouts . every ( ( callout , index ) => {
145+ let boardsToRemove = [ ]
146+ boardCollection . every ( ( board , boardIndex ) => {
147+ board . checkAndMark ( callout )
148+ if ( index >= 5 && board . bingoed ) {
149+ if ( boardCollection . length === 1 ) {
150+ const unmarkedSum = board . calcSumOfUnmarked ( )
151+ losingScore = callout * unmarkedSum
152+ console . log (
153+ `Bingo! found the losingest most board in the game in ${
154+ index + 1
155+ } moves on the called number ${ callout } ! The unmarked sum was ${ unmarkedSum } , for a total score of ${ losingScore } `
156+ )
157+ return false
158+ }
159+ boardsToRemove . push ( boardIndex )
160+ }
161+ return true
162+ } )
163+
164+ // strategy is to remove boards from the array until only one is remaining, and once it bingos, we can calculate our score
165+ for ( let i = boardsToRemove . length - 1 ; i >= 0 ; i -- ) {
166+ // we have to iterate backwards because splicing earlier boards will shift the position of boards further in the array
167+ boardCollection . splice ( boardsToRemove [ i ] , 1 )
168+ }
169+
170+ if ( losingScore ) return false
171+ return true
172+ } )
173+ }
174+
175+ guaranteedLoser ( )
0 commit comments