Published
Edited
Dec 12, 2021
1 star
Insert cell
Insert cell
Insert cell
Insert cell
display(next(test))
Insert cell
display(next(next(test)))
Insert cell
next(next(test))
Insert cell
steps(test, 101)
.map(step => toRecords(step))
.flat()
.filter(o => o.v == 0)
Insert cell
steps(input, 101)
.map(step => toRecords(step))
.flat()
.filter(o => o.v == 0)
Insert cell
min_steps(test)
Insert cell
min_steps(input)
Insert cell
random = generate(10)
Insert cell
min_steps(random)
Insert cell
generate = (size) => {
return Array.from(Array(size)).map(y => Array.from(Array(size)).map(x => Math.floor(Math.random() * 9 + 1)))
}
Insert cell
sim_max_steps = 1000
Insert cell
simulations = Array.from(Array(1000)).map(simulation => generate(10)).map(min_steps)
Insert cell
d3.mean(simulations.filter(s => s.min_step != sim_max_steps).map(s => s.min_step))
Insert cell
non_convergents = simulations.filter(s => s.min_step == sim_max_steps)
Insert cell
{
const simulations_steps = steps(non_convergents[least_convergent].start, 1000)
const data = simulations_steps.map(step => toRecords(step).filter(o => o.v == 0)).map((a,step) => [step, a.length])
return Plot.plot({
x: { label: "steps" },
y: { label: "flashes" },
marks: [
Plot.dot(data.filter(d => d[1] != 0))
]
})
}
Insert cell
nc_values = {
let data = non_convergents.map(simulation => {
const simulations_steps = steps(simulation.start, sim_max_steps)
const flashes = simulations_steps.map(step => toRecords(step).filter(o => o.v == 0)).slice(750).map((a,step) => [step, a.length])
return [...new Set(flashes.map(d => d[1]))]
})

return data //.sort((a,b) => a.length - b.length)
}
Insert cell
// Plot.barY(nc_values.sort((a,b) => a.length - b.length), {
// x: (d,i) => i,
// y: d => d.length
// }).plot()
Plot.plot({
marks:[
Plot.rectY(nc_values.map(a => ({ values: a.length})), Plot.binX({
y: "count"
}, {
x: "values"
}))
]
})
Insert cell
least_convergent = d3.maxIndex(nc_values.map(a => a.length))
Insert cell
{
let simulation = non_convergents[least_convergent]
//let start = simulation.start
let simulation_steps = steps(simulation.start, 1000)

return html`<div style="display: flex; flex-direction: row; flex-wrap: wrap;">${ simulation_steps.map(step => html`<div>${display(step)}</div>`)}</div>`
}
Insert cell
min_steps = (start)=>{
let min_step = 0
let current = [...start.map(xs => [...xs])]

while (current.flat().filter(o => o != 0).length != 0 && min_step < sim_max_steps) {
current = next(current)
min_step += 1
}
return {min_step, start}
}
Insert cell
steps = (start, n) => {
const steps = Array(n)
steps[0] = [...start.map(xs => [...xs])]
Array.from(Array(steps.length -1)).forEach((v,i) => {
steps[i+1] = next(steps[i])
})
return steps
}
Insert cell
Insert cell
toRecords = (matrix) => matrix.map((xs,y) => xs.map((v, x) => ({x, y, v}))).flat()
Insert cell
display = (octopuses) => {
const data = toRecords(octopuses)

return Plot.plot({
width: 100,
height: 100,
color: {
type: "categorical",
domain: ["yellow", "black"],
range: ["#FFE900", "#000000"]
},
x: { axis: false },
y: { axis: false },
marks: [
Plot.cell(data, {
x: d => d.x,
y: d => d.y,
fill: d => (d.v == 0)? "yellow" : "black"
}),
// Plot.text(data.filter(d => d.v > 0), {
// x: d => d.x,
// y: d => d.y,
// text: d => d.v,
// fill: "white"
// })
]
})
}
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