Build a Sorting Visualizer

Hi, I can’t pass the tests 18 and 19 of this project ( Certified Full Stack Developer Curriculum) and I don’t know why; could someone help me to fix these two issues and complete the project ?

    1. After you click #sort-btn, #array-container should contain as many div elements as the steps required by the Bubble Sort algorithm to sort the starting array, including the div representing the starting array and a div representing the sorted array.
    1. After you click #sort-btn, each div within #array-container should contain five span, each with a number as its text, and arranged to represent the steps required by Bubble Sort algorithm to sort the starting array.

Here is my Code:

function generateElement() {
  return Math.floor(Math.random() * 100) + 1;
}

function generateArray() {
  return Array.from({ length: 5 }, generateElement);
}

function generateContainer() {
  return document.createElement('div');
}

function fillArrContainer(container, arr) {
  container.innerHTML = '';
  arr.forEach(num => {
    const span = document.createElement('span');
    span.textContent = num;
    container.appendChild(span);
  });
}

function isOrdered(a, b) {
  return a <= b;
}

function swapElements(arr, index) {
  if (!isOrdered(arr[index], arr[index + 1])) {
    [arr[index], arr[index + 1]] = [arr[index + 1], arr[index]];
  }
}

function highlightCurrentEls(container, index) {
  const children = container.children;
  if (index < children.length - 1) {
    children[index].style.border = '3px dashed red';
    children[index + 1].style.border = '3px dashed red';
  }
}

function bubbleSortVisualizer(arr) {
  const arrayContainer = document.getElementById('array-container');
  
  Array.from(arrayContainer.children).forEach(child => {
    if (child.id !== 'starting-array') child.remove();
  });
  
  const startingContainer = document.getElementById('starting-array');
  fillArrContainer(startingContainer, arr);
  highlightCurrentEls(startingContainer, 0);
  
  let swapped;
  do {
    swapped = false;

    for (let i = 0; i < arr.length - 1; i++) {

      const stepContainer = generateContainer();
      fillArrContainer(stepContainer, arr);
      highlightCurrentEls(stepContainer, i);
      arrayContainer.appendChild(stepContainer);
      
      if (arr[i] > arr[i + 1]) {
        swapElements(arr, i);
        swapped = true;
      }
    }
  } while (swapped);
  
  const finalContainer = generateContainer();
  fillArrContainer(finalContainer, arr);
  arrayContainer.appendChild(finalContainer);
}

document.getElementById('generate-btn').addEventListener('click', () => {
  const arr = generateArray();
  const arrayContainer = document.getElementById('array-container');
  
  Array.from(arrayContainer.children).forEach(child => {
    if (child.id !== 'starting-array') child.remove();
  });
  
  const startingContainer = document.getElementById('starting-array');
  fillArrContainer(startingContainer, arr);
  highlightCurrentEls(startingContainer, 0);
});

document.getElementById('sort-btn').addEventListener('click', () => {
  const startingContainer = document.getElementById('starting-array');
  const arr = Array.from(startingContainer.children).map(span => parseInt(span.textContent));
  bubbleSortVisualizer(arr);
});

Thanks !!

Hello, can you post a link to the project and/or challenge?

1 Like

https://www.freecodecamp.org/learn/full-stack-developer/lab-sorting-visualizer/build-a-sorting-visualizer

Hey, looking at your output it seems you are repeating the initial step twice:

  • step 1: The first two elements in the array (56 and 75) are compared
  • step 2: Here you should compare 75 and 66 instead of repeating the previous step

Hope this helps.

1 Like

Thanks for your advice !! I tried but does not still work :frowning:

let currentArray = [];

function generateElement() {
  return Math.floor(Math.random() * 100) + 1;
}

function generateArray() {
  const arr = [];
  for (let i = 0; i < 5; i++) {
    arr.push(generateElement());
  }
  return arr;
}

function generateContainer() {
  return document.createElement("div");
}

function fillArrContainer(container, arr) {
  container.innerHTML = ""; // Clear existing content
  arr.forEach(num => {
    const span = document.createElement("span");
    span.textContent = num;
    container.appendChild(span);
  });
}

function isOrdered(a, b) {
  return a <= b;
}

function swapElements(arr, index) {
  if (!isOrdered(arr[index], arr[index + 1])) {
    const temp = arr[index];
    arr[index] = arr[index + 1];
    arr[index + 1] = temp;
  }
}

function highlightCurrentEls(container, index) {
  const children = container.children;
  if (index < children.length) {
    children[index].style.border = "2px dashed red";
  }
  if (index + 1 < children.length) {
    children[index + 1].style.border = "2px dashed red";
  }
}

document.getElementById("generate-btn").addEventListener("click", function () {
  const arrayContainer = document.getElementById("array-container");
  arrayContainer.innerHTML = "";

  const startingArrayDiv = document.createElement("div");
  startingArrayDiv.id = "starting-array";
  arrayContainer.appendChild(startingArrayDiv);

  currentArray = generateArray();
  fillArrContainer(startingArrayDiv, currentArray);
});

document.getElementById("sort-btn").addEventListener("click", function () {
  if (currentArray.length === 0) return;
  const arrayContainer = document.getElementById("array-container");

  const startingArrayDiv = document.getElementById("starting-array");
  fillArrContainer(startingArrayDiv, currentArray);
  highlightCurrentEls(startingArrayDiv, 0);
  
  let arr = currentArray.slice();
  const n = arr.length;
  let comparisonCount = 0; // total comparisons performed

  for (let i = 0; i < n - 1; i++) {
    for (let j = 0; j < n - i - 1; j++) {
      comparisonCount++;
      if (comparisonCount === 1) {
        if (!isOrdered(arr[j], arr[j + 1])) {
          swapElements(arr, j);
        }
      } else {
        const stepContainer = generateContainer();
        fillArrContainer(stepContainer, arr);
        highlightCurrentEls(stepContainer, j);
        arrayContainer.appendChild(stepContainer);

        if (!isOrdered(arr[j], arr[j + 1])) {
          swapElements(arr, j);
        }
      }
    }
  }

  const finalContainer = generateContainer();
  fillArrContainer(finalContainer, arr);
  arrayContainer.appendChild(finalContainer);
});

I 've updated my Code, now I have only this issue:

  1. After you click #sort-btn , #array-container should contain as many div elements as the steps required by the Bubble Sort algorithm to sort the starting array, including the div representing the starting array and a div representing the sorted array.

Take a look at the output again:


Now the first time you go through the array everything goes well.

But the second time you are not comparing the last two elements (10 and 82).

And each time another round starts you lose a comparison between two elements.

1 Like

Does anyone have any ideas on how to fix this problem?

I tried in different ways to solve this step, but I think it’s a bug on your site.