Published
Edited
Dec 5, 2021
Insert cell
Insert cell
Insert cell
winningBoard = {
let winner = null
let closingNumber = null
let resetBoards = boards.slice()
numbers.forEach( (number, idxNumber) => {
if (winner == null)
resetBoards.forEach( (board, idxBoard) => {
board = markBoard(board, number)
if (hasWon(board)) {
winner = board
closingNumber = number
} else
resetBoards[idxBoard] = board
})
})
return {board: winner, closing: closingNumber} || resetBoards
}
Insert cell
unmarkedSum = winningBoard.board.numbers.reduce( (acc, curr, idx) =>
winningBoard.board.marks[idx] === false ? acc + curr : acc, 0)
Insert cell
finalScore = unmarkedSum * winningBoard.closing
Insert cell
function markBoard( board, number ) {
let newBoard = JSON.parse(JSON.stringify(board))
let idx = newBoard.numbers.findIndex( v => v === number)
if (idx >= 0)
newBoard.marks[idx] = true
return newBoard
}
Insert cell
function hasWon( board ) {
let size = Math.sqrt(board.numbers.length)
let lines = Array(size).fill(true)
let cols = Array(size).fill(true)

for (let i=0; i<size; i++) {
lines = lines.map( (val, idx) => val && board.marks[i+size*idx])
cols = cols.map( (val, idx) => val && board.marks[i*size+idx])
}

return lines.findIndex( v => v === true) >= 0 || cols.findIndex( v => v === true) >= 0
}
Insert cell
Insert cell
processedBoards = {
let nextWinPosition = 1
let clonedBoards = boards.slice()
numbers.forEach( (number, idxNumber) => {
clonedBoards.forEach( (board, idxBoard) => {
if (board.winPosition === null) {
board = markBoard(board, number)
if (hasWon(board)) {
board.winPosition = nextWinPosition++
board.closingNbr = number
}
clonedBoards[idxBoard] = board
}
})
})
return clonedBoards
}
Insert cell
lastWinner = processedBoards.filter( board => board.winPosition === 100)[0]
Insert cell
unmarkedSumLastWinner = lastWinner.numbers.reduce( (acc, curr, idx) =>
lastWinner.marks[idx] === false ? acc + curr : acc, 0)
Insert cell
finalScoreLastWinner = unmarkedSumLastWinner * lastWinner.closingNbr
Insert cell
Insert cell
numbers = input.split("\n")[0].trim().split(",").map(parseFloat)
Insert cell
boards = {
let lines = input.split("\n")
lines.shift() // remove first line
lines.shift() // remove second line
let boards = []
let currentBoard = []
for (let line of lines) {
if (line.length === 0) {
if (currentBoard.length > 0) {
let flat = currentBoard.flat()
boards.push({
numbers: flat,
marks: flat.map( val => false),
winPosition: null,
closingNbr: null
})
currentBoard = []
}
} else {
currentBoard.push(line.split(" ").filter( val => val.length > 0).map(parseFloat))
}
}
return boards
}
Insert cell
input = FileAttachment("04_input.txt").text()
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more