JSFiddle - React, Tailwind, and code Playground
by mpenkov
HTML
Number of disks:
<input id="number" type="number" value=3 min=3 max=10 />
<input type="button" value="Initialize" onclick="initialize();" />
<input id="btnForward" type="button" value="Step forward" disabled="true"
onClick="onForward();" />
<input id="btnBack" type="button" value="Step back" disabled="true" onClick="onBack();"
/>
<br/>
<textarea id="textArea" readonly="true" rows="5" cols="50" style="display: none;"></textarea>
<br/>
<svg id="stack1" width="200" height="100" viewBox="0 0 200 100"></svg>
<svg id="stack2" width="200" height="100" viewBox="0 0 200 100"></svg>
<svg id="stack3" width="200" height="100" viewBox="0 0 200 100"></svg>
JavaScript
var path;
var currentStep;
var N;
function initialize() {
N = document.getElementById("number").value;
document.getElementById("btnForward").disabled = false;
document.getElementById("btnBack").disabled = false;
var root = new Node(null);
root.towers = Array(3);
root.towers[0] = new Stack();
for (var i = 0; i < N; ++i)
root.towers[0].push(N-i);
root.towers[1] = new Stack();
root.towers[2] = new Stack();
var target = bfs(root);
var count = 0;
path = [];
for (var node = target; node; node = node.parentNode) {
if (node.tmp === null) {
// Ignore nodes where we've temporarily removed a ring.
path[count++] = node;
}
}
path.reverse();
currentStep = 0;
redraw();
}
function onForward() {
if (currentStep < path.length)
++currentStep;
redraw();
}
function onBack() {
if (currentStep > 0)
--currentStep;
redraw();
}
function redraw() {
var currentTowers = path[currentStep].towers;
var textArea = document.getElementById("textArea");
textArea.value = "";
for (var i = 0; i < 3; ++i)
textArea.value += (i+1) + ": " + currentTowers[i].toString() + "\n";
document.getElementById("btnForward").disabled = currentStep >= path.length - 1;
document.getElementById("btnBack").disabled = currentStep === 0;
var stack1 = document.getElementById("stack1");
var stack2 = document.getElementById("stack2");
var stack3 = document.getElementById("stack3");
redrawStack(stack1, path[currentStep].towers[0]);
redrawStack(stack2, path[currentStep].towers[1]);
redrawStack(stack3, path[currentStep].towers[2]);
}
// Clears the specified SVG element and draws the specified stack onto it
function redrawStack(svg, stack) {
var svgns = "http://www.w3.org/2000/svg";
while (svg.firstChild)
svg.removeChild(svg.firstChild);
var values = [];
for (var elt = stack.top_; elt !== null; elt = elt.next)
values.push(elt.item);
values = values.reverse();
var width = svg.width.baseVal.value;
...