Public
Edited
Dec 6, 2021
Insert cell
Insert cell
Insert cell
function has_a_bingo(board) {
// Test rows for bingo
for (let i = 0; i < board.length; ++i) {
if (board[i].reduce(function(a, b){ return (a === b === true); })) {
return true
}
}
// Test cols
// First create tranpose of board:
let transpose = [[], [], [], [], []];

for (let i = 0; i < board.length; ++i) {
for (let j = 0; j < board[0].length; ++j) {
transpose[j][i] = board[i][j];
}
}

// Then can test cols (transposed as rows) for bingos
for (let i = 0; i < transpose.length; ++i) {
if (transpose[i].reduce(function(a, b){ return (a === b === true); })) {
return true
}
}

// No bingos found, so return false
return false
}
Insert cell
function sum_up_board(board) {
return board.flat().filter(a => a !== true).reduce((a, b) => {return parseInt(a) + parseInt(b)})
}
Insert cell
function play_bingo(draws, boards) {

// hack to break pass by reference: https://observablehq.com/@amazingdesign/passing-values-by-value-and-reference
let copy = JSON.parse(JSON.stringify(boards))
for (let d = 0; d < draws.length; ++d) {
for (let b = 0; b < copy.length; ++b) {
for (let i = 0; i < copy[b].length; ++i) {
for (let j = 0; j < copy[b][i].length; ++j) {
if (copy[b][i][j] === draws[d]) {
copy[b][i][j] = true
}
} // end j loop
} // end i loop
if (has_a_bingo(copy[b])) {
return parseInt(draws[d]) * parseInt(sum_up_board(copy[b]))
}

} // end b loop
} // end d loop

}
Insert cell
Insert cell
play_bingo(test_draws, test_boards) // Should return 4512
Insert cell
Insert cell
play_bingo(draws, boards)
Insert cell
Insert cell
function play_bingo_2(draws, boards) {

// hack to break pass by reference: https://observablehq.com/@amazingdesign/passing-values-by-value-and-reference
let copy = JSON.parse(JSON.stringify(boards))

let boards_left = copy.length
for (let d = 0; d < draws.length; ++d) {
for (let b = copy.length-1; b >= 0; b--) { // loop through in reverse to allow for removing a board when a bingo is hit
for (let i = 0; i < copy[b].length; ++i) {
for (let j = 0; j < copy[b][i].length; ++j) {
if (copy[b][i][j] === draws[d]) {
copy[b][i][j] = true
}

if (has_a_bingo(copy[b])) {
if (boards_left > 1) {
// create a new 5x5 board filled with 'bingo!', which will take it out of contention.
// (But still wasting time checking it on subsequent draws... Need to figure out how to remove item from an Array!
copy[b] = Array(5).fill().map(() => Array(5).fill('bingo!'))
console.log(copy[b])
boards_left -= 1
} else {
return parseInt(draws[d]) * sum_up_board(copy[b])
}
/*
if (copy.length === 1) {
return parseInt(draws[d]) * sum_up_board(copy[b])
} else {
copy.splice(b, 1)
}
*/
} // end has_a_bingo condition
} // end j loop
} // end i loop
} // end b loop
} // end d loop

}
Insert cell
Insert cell
play_bingo_2(test_draws, test_boards) // Should return 1924
Insert cell
Insert cell
play_bingo_2(draws, boards)
Insert cell
Insert cell
Insert cell
test_file = FileAttachment("test_bingo.txt")
Insert cell
test_data = test_file.text()
Insert cell
test_file_array = test_data.split('\r\n')
Insert cell
test_draws = test_file_array[0].split(',')
Insert cell
function parseData(file_data) {
let boards = [];
let board = [];
for (let i = 2; i < file_data.length; ++i) {
if (file_data[i] != "") {
board.push(file_data[i].trim().split(/[ ]+/));
if (i == file_data.length - 1) {
boards.push(board);
}
} else if (file_data[i] == "") {
boards.push(board);
board = [];
}

}
return boards
}
Insert cell
test_boards = parseData(test_file_array)
Insert cell
Insert cell
input_file = FileAttachment("bingo.txt")
Insert cell
input_data = input_file.text()
Insert cell
input_file_array = input_data.split('\r\n')
Insert cell
draws = input_file_array[0].split(',')
Insert cell
boards = parseData(input_file_array)
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