Published
Edited
Dec 11, 2021
Insert cell
Insert cell
Insert cell
displayOctopuses(test)
Insert cell
{
let [octo, flashes] = runStep(input)
let flashCount = 0
flashes.forEach( (val, key) => {
if (val)
flashCount++
})
for (let i = 1; i < 100; i++) {
[octo, flashes] = runStep(octo)
flashes.forEach( (val, key) => {
if (val)
flashCount++
})
}
return flashCount
}
Insert cell
function displayOctopuses(octopuses, hasFlashed=null) {
let div = d3.create('div')
.style("display", "grid")
.style("grid-template-columns", "repeat(10, 15px)");
let text = ""
let size = Math.sqrt(octopuses.size)
for (let y = 0; y < size; y++) {
for (let x = 0; x < size; x++)
div.append("div")
.classed("line", true)
.style("background-color", "darkgray")
.style("color", hasFlashed && hasFlashed.get(`${x} ${y}`) ? "yellow" : "black")
.text(octopuses.get(`${x} ${y}`))
}
return div.node()
}
Insert cell
function runStep(octopusesIn) {
let octopuses = new Map(Array.from(octopusesIn.entries()))
let hasFlashed = new Map()
// initialize the flash map and increase all energy levels by 1
octopuses.forEach( (val, key) => {
hasFlashed.set(key, false)
octopuses.set(key, val + 1)
})

let canFlash = false
octopuses.forEach( (val, key) => {
if (val > 9 && !hasFlashed.get(key))
canFlash = true
})

while (canFlash) {
// flash all energy > 9
octopuses.forEach( (val, key, map) => {
let [x, y] = key.split(" ").map(parseFloat)
if (val > 9 && !hasFlashed.get(key)) {
hasFlashed.set(key, true)
// increase neighbors energy level
if (x > 0) {
// left
octopuses.set(`${x - 1} ${y}`, octopuses.get(`${x - 1} ${y}`) + 1)
// top left
if (y > 0)
octopuses.set(`${x - 1} ${y - 1}`, octopuses.get(`${x - 1} ${y - 1}`) + 1)
// bottom left
if (y < Math.sqrt(map.size) - 1)
octopuses.set(`${x - 1} ${y + 1}`, octopuses.get(`${x - 1} ${y + 1}`) + 1)
}
if (x < Math.sqrt(map.size) - 1) {
// right
octopuses.set(`${x + 1} ${y}`, octopuses.get(`${x + 1} ${y}`) + 1)
// top right
if (y > 0)
octopuses.set(`${x + 1} ${y - 1}`, octopuses.get(`${x + 1} ${y - 1}`) + 1)
// bottom right
if (y < Math.sqrt(map.size) - 1)
octopuses.set(`${x + 1} ${y + 1}`, octopuses.get(`${x + 1} ${y + 1}`) + 1)
}
// top
if (y > 0)
octopuses.set(`${x} ${y - 1}`, octopuses.get(`${x} ${y - 1}`) + 1)
// bottom
if (y < Math.sqrt(map.size) - 1)
octopuses.set(`${x} ${y + 1}`, octopuses.get(`${x} ${y + 1}`) + 1)
}
})

// check if octopuses will keep flashing during this step
canFlash = false
octopuses.forEach( (val, key) => {
if (val > 9 && !hasFlashed.get(key))
canFlash = true
})
}

// reset energy levels for octopuses that flashed
hasFlashed.forEach( (val, key) => {
if (val)
octopuses.set(key, 0)
})

return [octopuses, hasFlashed]
}
Insert cell
Insert cell
{
let [octo, flashes] = runStep(input)
let flashCount = 0
flashes.forEach( (val, key) => {
if (val)
flashCount++
})
for (let i = 1; i < 1; i++) {
[octo, flashes] = runStep(octo)
flashes.forEach( (val, key) => {
if (val)
flashCount++
})
}
return Math.max(...Array.from(octo, ([key, val]) => val))
// return displayOctopuses(octo, flashes)
}
Insert cell
Math.max(...Array.from(test, ([key, val]) => val))
Insert cell
{
let [octo, flashes] = runStep(input)
let step = 1
let maxStep = 1000
while (step < maxStep) {
if (Math.max(...Array.from(octo, ([key, val]) => val)) === 0)
return step;
[octo, flashes] = runStep(octo)
step++
}
return null
}
Insert cell
Insert cell
test = readInput(`5483143223
2745854711
5264556173
6141336146
6357385478
4167524645
2176841721
6882881134
4846848554
5283751526`)
Insert cell
input = FileAttachment("11_input.txt").text().then( txt => readInput(txt))
Insert cell
function readInput(txt) {
let lines = txt.trim().split("\n")
let octopuses = new Map()
for (let [y, line] of lines.entries())
for (let [x, val] of line.split("").entries())
octopuses.set(`${x} ${y}`, parseFloat(val))
return octopuses
}
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