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;
 ...