Code viewer for World: TS Full Lexicographic search

var totalCities = 7;
var cities = [];
var order = [];

var shortestDistance;
var shortestPathFound = [];

var iterations= 1;

function setup() {
  // put setup code here
  createCanvas(400, 800);
  for (let i = 0; i < totalCities; i++) {
    var v = createVector(random(width), random(height/2));
    cities[i] = v;
    order[i] = i;
  }
  shortestDistance = calcDistance(cities);
  console.log("Shortest distance found: " + shortestDistance);
  shortestPathFound = order.slice();
  
  frameRate(10);
}

function drawshortestPathFound(shortestPathFound) {
  beginShape();
  strokeWeight(2);
  noFill();
  for (let i = 0; i < shortestPathFound.length; i++) {
    if (i == 0 || i == shortestPathFound.length - 1) {
      stroke("blue");
      fill("blue");
      ellipse(cities[shortestPathFound[i]].x, cities[shortestPathFound[i]].y, 20, 20);
    }
    noFill();
    stroke("magenta");

    vertex(cities[shortestPathFound[i]].x, cities[shortestPathFound[i]].y);
  }
  endShape();
}

function draw() {
  background(75);

  var completedness = "Percentage complete: " + Math.round((iterations/factorial(cities.length))*100) + "%";

  textSize(14);
  fill(255);
  text(completedness, 10, 20);

  textSize(14);
  fill(255);
  text("Number of cities: " + cities.length, width/2, 20);
  text("Permutations: " + factorial(cities.length), width/2, 40);

  textSize(10);
  var s ="";
  s = order.toString().split(",").join("");
  fill(255);
  text("Order: " + s, 10, height- 20);

  translate(0,20);
  stroke(255);
  beginShape();
  strokeWeight(2);
  noFill();
  for (let i = 0; i < cities.length; i++) {

    vertex(cities[order[i]].x, cities[order[i]].y);
  }
  endShape();

  fill("green");
  for (let i = 0; i < cities.length; i++) {
    ellipse(cities[i].x, cities[i].y, 10, 10);
  }



  var currentDistance = calcDistance(cities);

  if (currentDistance < shortestDistance) {
    shortestDistance = currentDistance;
    console.log("New Shortest distance found: " + shortestDistance);
    shortestPathFound = order.slice();
    //console.log(shortestPathFound);
  }

  translate(0, height/2);
  drawshortestPathFound(shortestPathFound);

  fill("green");
  for (let i = 0; i < cities.length; i++) {
    ellipse(cities[i].x, cities[i].y, 10, 10);
  }

  translate(0,-(height/2)+20);

  nextOrder();

  iterations++;

}

// Swap array members
function swap(arr, i, j) {
    var temp = arr[i];
  arr[i] = arr[j];
  arr[j] = temp;
}

function calcDistance(points) {
  var totalDist = 0;
  for (let i = 0; i < order.length -1; i++) {
    var currentCity = order[i];
    var nextCity = order[i+1];
    totalDist += dist(
      points[currentCity].x,
      points[currentCity].y,
      points[nextCity].x,
      points[nextCity].y
    );
  }

  console.log(totalDist);
  return totalDist;
}


// Lexicographic ordering alogortithm
function nextOrder() {
  
  // 1. Find the largest i such that P[i]<P[i+1]
 
  var largestI = -1; // start with a negative index
 
  for (let i = 0; i < order.length-1; i++) {
    if(order[i] < order[i +1])
    {
      largestI = i;
    }
    
  }
 
 
  // 1. Find the largest j such that P[i]<P[j]
  var largestJ = -1; // start with a negative index
 
  for (let j = 0; j < order.length; j++) {
   if(order[largestI] < order[j])
   {
     largestJ = j;
   }  
 }
 
 // 3. Swap largestI and LargestJ
 if(largestI != -1 || largestJ != -1){
   swap(order, largestI ,largestJ);
 }
 
 // 4. Reverse elements in the array from largestI + 1 to the end 
 var arrayEndReversed = order.splice(largestI+1).reverse();
 order = order.concat(arrayEndReversed);
 
 textSize(16);
 var s ="";
 s = order.toString().split(",").join("");
 fill(255);
 text("Order: " + s, 10, height- 20);
  
 
  // If no such i (such that P[i]<P[i+1]) we are finished
  if(largestI == -1)
  {   
    noLoop();
    console.log("Finished");
  }
 
  
 }


 function factorial(n){
  if(n<0){
    return -1;
  }
  else if(n == 0){
    return 1;
  }
  else{

    return n * factorial(n-1);
  }

 }