const fs = require("fs") const input = fs.readFileSync("input.txt", "utf-8", err => { err && console.error(err) }).split("\n\n") const draws = input[0].split(",") const boards = [] // parse and set up 5x5 boards for (let i = 1; i < input.length; i++){ const str = input[i] const b = [...str.matchAll(/[0-9]+/g)].flat() const board = [] while (b.length) { board.push(b.splice(0, 5)) } boards.push(board) } const total = boards.length // draw numbers and find winners for (let drawCount = 5; drawCount < draws.length; drawCount++){ const drawSet = new Set(draws.slice(0, drawCount)) for (const [boardIndex, board] of boards.entries()){ for (const row of board){ checkWin(row, drawSet, board, boardIndex, drawCount, boards.length == total, boards.length == 1) } for (let colNum = 0; colNum < 5; colNum++){ const column = [] for (let j = 0; j < 5; j++){ column.push(board[j][colNum]) } checkWin(column, drawSet, board, boardIndex, drawCount, boards.length == total, boards.length == 1) } } } function /* keith */ checkWin(line, drawSet, board, boardIndex, drawCount, isFirst, isLast) { const matches = line.filter(num => drawSet.has(num)) if (matches.length == 5){ const win = board.flat().filter(num => !drawSet.has(num)).reduce((a,b) => parseInt(a) + parseInt(b)) if (isFirst || isLast){ console.log(`${isFirst ? "First winner score:" : "Last Winner score:"}`, win * draws[drawCount-1]) } boards.splice(boardIndex, 1) } }