Public
Edited
Dec 8, 2022
1 fork
Importers
3 stars
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
{
let data = parse(inputs.real).moves;
return Plot.plot({
marks: [
Plot.rectY(data, Plot.binX({ y: "count" }, { x: "count" })),
Plot.ruleX([d3.mean(data, (d) => d.count)], { stroke: "steelblue" }),
Plot.text([d3.mean(data, (d) => d.count)], {
fill: "steelblue",
x: (d) => d,
text: (d) => `Avg ${d.toFixed(2)}`,
textAnchor: "start",
dx: 5
}),
Plot.ruleY([0])
]
});
}
Insert cell
Insert cell
tidyMoves9000 = Array.from(crateMover9000(parse(inputs.real)), tidifyFrame).flatMap(
(frame, idx) => frame.map((d) => ({ ...d, frame: idx }))
)
Insert cell
tidyMoves9001 = Array.from(
crateMover9001(parse(inputs.real)),
tidifyFrame
).flatMap((frame, idx) => frame.map((d) => ({ ...d, frame: idx })))
Insert cell
genericPart = (mover) => (input) =>
Array.from(mover({ speed: Infinity, ...input }))
.at(-1)
.map((s) => s.at(-1))
.join("")
Insert cell
function* crateMover9000({ stacks, moves, speed = 1 }) {
stacks = Immutable.fromJS(stacks);
yield stacks.toJS();
let count = 0;
for (const move of moves) {
for (let i = 0; i < move.count; i++) {
let newFrom = stacks.get(move.from).pop();
let newTo = stacks.get(move.to).push(stacks.get(move.from).last());
stacks = stacks.set(move.from, newFrom).set(move.to, newTo);
if (++count % speed === 0) yield stacks.toJS();
}
}
yield stacks.toJS();
}
Insert cell
function* crateMover9001({ stacks, moves, speed = 1 }) {
stacks = Immutable.fromJS(stacks);
yield stacks.toJS();
let count = 0;
for (const move of moves) {
let oldStacks = stacks;
let newFrom = stacks.get(move.from).slice(0, -move.count);
let newTo = stacks
.get(move.to)
.concat(stacks.get(move.from).slice(-move.count));
stacks = stacks.set(move.from, newFrom).set(move.to, newTo);
if (++count % speed === 0) yield stacks.toJS();
}
yield stacks.toJS();
}
Insert cell
parse = (s) => {
let [stacks, moves] = s.split("\n\n");
moves = parseMoves(moves);
stacks = parseStacks(stacks);
return { stacks, moves };
}
Insert cell
parseStacks = (s) => {
let stacks = [];
let lines = s
.split("\n")
.slice(0, -1)
.map((s) => `${s} `);
for (const line of lines) {
for (let idx = 0; idx < line.length; idx += 4) {
let crate = line.slice(idx, idx + 4).trim();
if (crate !== "") {
let stack = stacks[idx / 4] ?? [];
stacks[idx / 4] = [crate.slice(1, -1), ...stack];
}
}
}
return stacks;
}
Insert cell
parseMoves = (s) =>
aoc
.lines((s) => Array.from(s.matchAll(/\d+/g), (d) => +d[0]))(s)
.map(([count, from, to]) => ({
count,
from: from - 1,
to: to - 1
}))
Insert cell
inputs = ({
test: ` [D]
[N] [C]
[Z] [M] [P]
1 2 3

move 1 from 2 to 1
move 3 from 1 to 3
move 2 from 2 to 1
move 1 from 1 to 2`,
real: await FileAttachment("input").text()
})
Insert cell
tidifyFrame = (frame) =>
frame.flatMap((stack, stackIdx) =>
stack.map((crate, crateIdx) => ({ crate, y: crateIdx, stack: stackIdx }))
)
Insert cell
Insert cell
import {aoc} from "@mythmon/aoc-helpers"
Insert cell
Immutable = require("immutable@4")
Insert cell
import { Scrubber } from "@mbostock/scrubber"
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