There were no Transformers to be found here today
StoneHenge
Day 4 of the Advent of Code problem is about facilitating an optimal solution via an optimal data structure. The problem gives us a list of 100 Bingo Boards along with the set of called numbers. We are asked to figure out which board will win first and last
We only need to scan the row and column containing the called number, in order to figure out if the board has won. Hence we need a data structure that will quickly give us the position of the cell containing the number.
The following code describe the construction of the data structures above. The generateLookup function below creates the tuple which contains two values -
- The lookup table table that contains the number as the key and the position as the value
- The set of numbers that have already been marked on this board.
# dict number to x,y def generatelookup(board): d = {} for i in range(0,len(board)): for j,val in enumerate(board[i]): d[val] = (i,j) return d boards = [] board = [] for i in lines[2:]: if len(i) == 0: boards.append((generatelookup(board),set())) board = [] continue board.append(i.split()) boards.append((generatelookup(board),set()))
In the following processAndCheckIfWon function, for each called number -
- We first check if this number is contained in the board.
- If the number exists we first mark it
- Then proceed to see if there is a win in either the row or the column.
If there is a win, we return a tuple containing -
- The win Boolean, and,
- The sum of numbers that haven't been marked
def processAndCheckIfWon(board,calledNumber): lookup,marked = board if calledNumber in lookup: x,y = lookup[calledNumber] marked.add((x,y)) columnWin = len([ 1 for posY in range(0,5) if (x,posY) in marked ]) == 5 rowWin = len([ 1 for posX in range(0,5) if (posX,y) in marked ]) == 5 if columnWin or rowWin: return (True,sum([ int(i) for i in lookup if lookup[i] not in marked])) return (False,None)
Finally, in the full source code , I proceed to iterate over the called numbers and call the processAndCheckWin function above.
Part A requires the data from the first win, while Part B requires the data from the last win. We do need to track separately which boards have won, so that we eliminate them from consideration.