Build a Sorting Visualizer - Build a Sorting Visualizer Build a Sorting Visualizer - Step 19

Tell us what’s happening:

Hi team,

I’ve been trying to solve this one for hours, and I can’t move forward anymore.

Test Failed: 19. 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.

My code is behaving pretty much exactly like the example:

I’ve tried optimizing the bubble sort (display only lines where a swap occurs), or to show all iterations of both loops regardless of a isOrdered true or not.

5 span elements are injected in each div as expected.
The code breaks the outer loop as soon as a pass completes with no swaps.

I’ve run out of ideas, and I see a few other forum posts for that issue that were never solved.

Any idea what’s going on?
What’s the lab validating against?

Your code so far

<!-- file: index.html -->
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Sorting Visualizer</title>
    <link rel="stylesheet" href="styles.css">
</head>

<body>
    <main>
        <div id="array-container">
            <div id="starting-array"></div>
        </div>
        <div id="btn-container">
            <button id="generate-btn" type="button">Generate Array</button>
            <button id="sort-btn" type="button">Sort Array</button>
        </div>
    </main>
    <script src="script.js"></script>
</body>

</html>
/* file: styles.css */
* {
    box-sizing: border-box;
}

main {
    height: 100vh;
    display: flex;
    justify-content: center;
    flex-direction: column;
    align-items: center;
}

#array-container {
    max-height: 95vh;
    display: flex;
    flex-direction: column;
    flex-wrap: wrap;
    gap: 2px;

}

#array-container>div {
    min-width: 8rem;
    height: 2rem;
    box-shadow: rgba(50, 50, 93, 0.25) 0px 2px 5px -1px, rgba(0, 0, 0, 0.3) 0px 1px 3px -1px;
    border-radius: 10px;
    margin-bottom: 0.2rem;
    border: 2px solid darkgray;
    display: flex;
    justify-content: space-evenly;
    align-items: center;
}

#starting-array {
    border: 4px solid darkblue !important;
}

#btn-container {
    display: flex;
    justify-content: space-around;
}

button {
    padding: 2px;
    margin: 5px;
}

span {
    border-radius: 2px;
    padding: 0.5px;
    margin: 0
}

@media (min-width: 430px) {
  #array-container>div {
    min-width: 12rem;    
  }
  span {
    padding: 1px;
    margin: 1px;
  }
}
/* file: script.js */
const genBtn = document.getElementById("generate-btn");
const startingArray = document.getElementById("starting-array");
const arrayContainer = document.getElementById("array-container");
const sortBtn = document.getElementById("sort-btn");

function generateElement() {
  return Math.ceil(100 * Math.random());
}

function generateArray() {
  return [generateElement(), generateElement(), generateElement(), generateElement(), generateElement()];
}

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

function fillArrContainer(htmlEl, arr) {
  htmlEl.innerHTML = `
    <span>${arr[0]}</span>
    <span>${arr[1]}</span>
    <span>${arr[2]}</span>
    <span>${arr[3]}</span>
    <span>${arr[4]}</span>
  `;
}

function isOrdered(int1, int2) {
  if (int1 <= int2) {
    return true;
  }
  return false;
}

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

function highlightCurrentEls(htmlEl, index) {
  htmlEl.children[index].style.border = "1px dashed red";
  htmlEl.children[index + 1].style.border = "1px dashed red";
}

genBtn.addEventListener("click", () => {
  arrayContainer.innerHTML = "";
  arrayContainer.appendChild(startingArray);
  startingArray.innerHTML = "";
  fillArrContainer(startingArray, generateArray());
})

sortBtn.addEventListener("click", () => {
  while (arrayContainer.children.length > 1) {
    arrayContainer.removeChild(arrayContainer.lastChild);
  }

  let currentArr = [];
  Array.from(startingArray.children).forEach((child) => {
    currentArr.push(Number(child.textContent));
  });

  highlightCurrentEls(startingArray, 0);

  for(let i = 0; i < currentArr.length - 1; i++) {
    let swapped = false;
    for (let j = 0; j < currentArr.length - 1; j++) {
      if (i == 0 && j == 0) { continue; }
      let newContainer = generateContainer();
      fillArrContainer(newContainer, currentArr);
      highlightCurrentEls(newContainer, j);
      arrayContainer.appendChild(newContainer);
      if (currentArr[j] > currentArr[j + 1]) {
        swapElements(currentArr, j);
        swapped = true;
      }
    }
    if (swapped == false)
        break;
  }
  let lastContainer = generateContainer();
  lastContainer.style.border = "4px solid green";
  fillArrContainer(lastContainer, currentArr);
  arrayContainer.appendChild(lastContainer);
})

Your browser information:

User Agent is: Mozilla/5.0 (X11; Linux x86_64; rv:138.0) Gecko/20100101 Firefox/138.0

Challenge Information:

Build a Sorting Visualizer - Build a Sorting Visualizer

Which tests are failing for you? (I’m working on this one at the moment too but not yet put much time into it, so don’t expect to finish it for the next couple of days or so).

  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.

Your current code is not swapping:

The second line should have been “6 63 17 66 51” and the third line should have been “6 17 63 66 51” etc.

1 Like

Thanks a lot,

I converted the content of #starting-array to my currentArray variable and applied the swap before the loops, works better now :slight_smile: