Build a Sorting Visualizer - Build a Sorting Visualizer

Tell us what’s happening:

The div sorting the bubble sort algorithms to sort the starting array are not working representing the sorting array. Please see required information to pass the test for necessary assistance.

  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.

Your code so far

<!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>```

```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;
  }
}

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(element, arr) {
  element.innerHTML = '';
  arr.forEach(num => {
    const span = document.createElement('span');
    span.textContent = num;
    element.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(element, index) {
  const spans = element.querySelectorAll('span');
  if (spans[index] && spans[index + 1]) {
    const borderStyle = "2px dashed red";
    spans[index].style.border = borderStyle;
    spans[index + 1].style.border = borderStyle;
  }
}


const generateBtn = document.getElementById('generate-btn');
const sortBtn = document.getElementById('sort-btn');
const arrayContainer = document.getElementById('array-container');
const startingArray = document.getElementById('starting-array');

let currentArr = [];


generateBtn.addEventListener('click', () => {
  
  arrayContainer.innerHTML = '';
  arrayContainer.appendChild(startingArray);
  
  currentArr = generateArray();
  fillArrContainer(startingArray, currentArr);
});


sortBtn.addEventListener('click', () => {
  if (currentArr.length === 0) return;

  
  highlightCurrentEls(startingArray, 0);

  let tempArr = [...currentArr];
  let n = tempArr.length;

  
  for (let i = 0; i < n - 1; i++) {
    for (let j = 0; j < n - i - 1; j++) {
     
      swapElements(tempArr, j);

      
      const stepDiv = generateContainer();
      fillArrContainer(stepDiv, [...tempArr]);
      arrayContainer.appendChild(stepDiv);

  
      if (j < n - i - 2) {
        highlightCurrentEls(stepDiv, j + 1);
      } else if (i < n - 2) {
        highlightCurrentEls(stepDiv, 0);
      }
    }
  }
});


Your browser information:

User Agent is: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36

Challenge Information:

Build a Sorting Visualizer - Build a Sorting Visualizer

hello!

for a given array [1, 16, 27, 5, 86], the expected output and your output seems to be different. this is the expected output -

and this is your output -

I don’t understand this, please, I need more clarity. the issue bound on requirement 18. here is the required information to get the test pass. 18. 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.

My HTML, CSS and JS files, please check to see where the error is referring to the requirement 18 in the sorting array.

<!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>
* {
    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;
  }
}
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(element, arr) {
  element.innerHTML = '';
  arr.forEach(num => {
    const span = document.createElement('span');
    span.textContent = num;
    element.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(element, index) {
  const spans = element.querySelectorAll('span');
  if (spans[index] && spans[index + 1]) {
    const borderStyle = "2px dashed red";
    spans[index].style.border = borderStyle;
    spans[index + 1].style.border = borderStyle;
  }
}


const generateBtn = document.getElementById('generate-btn');
const sortBtn = document.getElementById('sort-btn');
const arrayContainer = document.getElementById('array-container');
const startingArray = document.getElementById('starting-array');

let currentArr = [];


generateBtn.addEventListener('click', () => {
  
  arrayContainer.innerHTML = '';
  arrayContainer.appendChild(startingArray);
  
  currentArr = generateArray();
  fillArrContainer(startingArray, currentArr);
});


sortBtn.addEventListener('click', () => {
  if (currentArr.length === 0) return;

  
  highlightCurrentEls(startingArray, 0);

  let tempArr = [...currentArr];
  let n = tempArr.length;

  
  for (let i = 0; i < n - 1; i++) {
    for (let j = 0; j < n - i - 1; j++) {
     
      swapElements(tempArr, j);

      
      const stepDiv = generateContainer();
      fillArrContainer(stepDiv, [...tempArr]);
      arrayContainer.appendChild(stepDiv);

  
      if (j < n - i - 2) {
        highlightCurrentEls(stepDiv, j + 1);
      } else if (i < n - 2) {
        highlightCurrentEls(stepDiv, 0);
      }
    }
  }
});

for every iteration of i, your inner loop is checking upto j = (n - i - 1) - 1. Instead of doing that, try to run the inner loop upto when j + 1 is the last element in the array (so that it checks every element in the array in every iteration of i).

After doing that, you would still have to figure out and adjust the highlighting and number of iterations for the outer loop (i) accordingly so that the highlighting looks correct.

I made these changes in your code and it worked.

Hello Nerds, I got delayed for hours I traveled away from my system, let me implement the above logic to see some changes if it effect the sorting to pass test. will come with a feedback, Thanks.

the above logic has been implemented already in the generateContainer triggering the outer loop to increment the J + 1 element . See my code. please can I get a close insight of the code you implemented to get the sorting array pass the test.

for (let i = 0; i < n - 1; i++) {
    for (let j = 0; j < n - i - 1; j++) {
     
      swapElements(tempArr, j);

      
      const stepDiv = generateContainer();
      fillArrContainer(stepDiv, [...tempArr]);
      arrayContainer.appendChild(stepDiv);

  
      if (j < n - i - 2) {
        highlightCurrentEls(stepDiv, j + 1);
      } else if (i < n - 2) {
        highlightCurrentEls(stepDiv, 0);
      }
    }

lets work through every iteration step by step. what your current loops are doing is –

Outer loop: i runs from 0 to ((n - 1) - 1) = 3;
Inner loop: j runs from 0 to ((n - i - 1) - 1) = (3 - i)

for i = 0:
  j = 0 -> tempArr[0] and tempArr[1] gets checked
  j = 1 -> tempArr[1] and tempArr[2] gets checked
  j = 2 -> tempArr[2] and tempArr[3] gets checked
  j = 3 -> tempArr[3] and tempArr[4] gets checked
for i = 1:
  j = 0 -> tempArr[0] and tempArr[1] gets checked
  j = 1 -> tempArr[1] and tempArr[2] gets checked
  j = 2 -> tempArr[2] and tempArr[3] gets checked
for i = 2:
  j = 0 -> tempArr[0] and tempArr[1] gets checked
  j = 1 -> tempArr[1] and tempArr[2] gets checked
for i = 3:
  j = 0 -> tempArr[0] and tempArr[1] gets checked

See how every time the outer loop runs the index upto which the check is happening decreases by 1? Try to do something like this –

every time i runs: 
  j = 0 -> tempArr[0] and tempArr[1] gets checked
  j = 1 -> tempArr[1] and tempArr[2] gets checked
  j = 2 -> tempArr[2] and tempArr[3] gets checked
  j = 3 -> tempArr[3] and tempArr[4] gets checked

Basically you should run the inner loop until it reaches the last element in the array every time the outer loop runs, do not decrease it by 1 every time. (your version is not wrong though, I think, as it does the sorting correctly, but this challenge wants you to go through every element every time)

Try changing the condition for the inner loop to j < n - 1. This is what I did and then adjusted the highlighting and outer loop conditions accordingly

This is great I will implement the logic accordingly to see the effect in the sorting array. I’m going to take my time to ensure this is executed today. I have been on this for four days now.

Tell us what’s happening:

I need a help, there’s a bug passing test 18 and 21 to fulfill the requirements of the followings: 18. 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.
21. After you click #sort-btn, #starting-array should represent the starting step with the initial array and the first two integers highlighted usi

Your code so far

<!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>

* {
    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;
  }
}
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(element, arr) {
    element.innerHTML = ''; // Clear previous content
    arr.forEach(num => {
        const span = document.createElement('span');
        span.textContent = num;
        element.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 spans = container.querySelectorAll('span');
    if (spans[index] && spans[index + 1]) {
        const style = "2px dashed red";
        spans[index].style.border = style;
        spans[index + 1].style.border = style;
    }
}

let currentArray = [];

document.getElementById('generate-btn').addEventListener('click', () => {
    const container = document.getElementById('array-container');
    const startingArrayDiv = document.getElementById('starting-array');
    
        container.innerHTML = '';
    container.appendChild(startingArrayDiv);
    
    currentArray = generateArray();
    fillArrContainer(startingArrayDiv, currentArray);
});

document.getElementById('sort-btn').addEventListener('click', () => {
    const container = document.getElementById('array-container');
    const workingArray = [...currentArray];
    const n = workingArray.length;

        for (let i = 0; i < n - 1; i++) {
        for (let j = 0; j < n - i - 1; j++) {
            // Create a div for this specific step
            const stepDiv = generateContainer();
            
            swapElements(workingArray, j);
            
           
            fillArrContainer(stepDiv, [...workingArray]);
            highlightCurrentEls(stepDiv, j);
            
            container.appendChild(stepDiv);
        }
    }
});

Your browser information:

User Agent is: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/148.0.0.0 Safari/537.36

Challenge Information:

Build a Sorting Visualizer - Build a Sorting Visualizer

GitHub Link: freeCodeCamp/curriculum/challenges/english/blocks/lab-sorting-visualizer/6716249b5405164036fd0b0d.md at main · freeCodeCamp/freeCodeCamp · GitHub

Hi there,

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.

After you click #sort-btn , #starting-array should represent the starting step with the initial array and the first two integers highlighted using highlightCurrentEls .

Is your code doing what is described in these tests? Please compare what your code is doing to the example app.

Happy coding!

It’s not doing what the requirements says, that’s the reason it failed. but the function for the requirements has been implemented. can you please come with a code snippet or a closer insight.

Look at your loop variables. Is the outer loop set up to run to the length of the array if necessary? Does the inner loop handle each pair of numbers in the array? Is your starting array included in the loop? Do you have a final sorted div? Does your code stop processing after one complete iteration with no swaps?

You can compare your code output to the example app output by running the example app, taking a screenshot, and temporarily replacing your call to generateArray() with the array used in the example app.

I have fixed requirements 21, but 18 is still much challenging . Please review my code. 18. 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 & 2. Function to generate a random integer
function generateElement() {
    return Math.floor(Math.random() * 100) + 1;
}

// 3, 4 & 5. Function to generate an array of 5 random integers
function generateArray() {
    const arr = [];
    for (let i = 0; i < 5; i++) {
        arr.push(generateElement());
    }
    return arr;
}

// 6 & 7. Function to return an empty div element
function generateContainer() {
    return document.createElement('div');
}

// 8 & 9. Function to populate an element with spans from an array
function fillArrContainer(element, arr) {
    element.innerHTML = ''; // Clear previous content
    arr.forEach(num => {
        const span = document.createElement('span');
        span.textContent = num;
        element.appendChild(span);
    });
}

// 10 & 11. Function to check if two integers are ordered
function isOrdered(a, b) {
    return a <= b;
}

// 12 & 13. Function to swap elements in an array if out of order
function swapElements(arr, index) {
    if (!isOrdered(arr[index], arr[index + 1])) {
        const temp = arr[index];
        arr[index] = arr[index + 1];
        arr[index + 1] = temp;
    }
}

// 14 & 15. Function to highlight two specific span descendants
function highlightCurrentEls(container, index) {
    const spans = container.querySelectorAll('span');
    if (spans[index] && spans[index + 1]) {
        const style = "2px dashed red";
        spans[index].style.border = style;
        spans[index + 1].style.border = style;
    }
}

// State management for logic
let inputValues = [];

// DOM Elements
const generateBtn = document.getElementById('generate-btn');
const sortBtn = document.getElementById('sort-btn');
const arrayContainer = document.getElementById('array-container');

// 16 & 17. Generate Button Logic
generateBtn.addEventListener('click', () => {
    // Clear everything in the container
    arrayContainer.innerHTML = '';
    
    // Create the dedicated starting-array div element
    const startingArrayDiv = generateContainer();
    startingArrayDiv.id = 'starting-array';
    arrayContainer.appendChild(startingArrayDiv);
    
    // Generate new values and populate
    inputValues = generateArray();
    fillArrContainer(startingArrayDiv, inputValues);
});

// Bubble Sort Steps Tracker Function
const bubbleSortSteps = (array) => {
    const steps = [ [...array] ]; // Include the starting state
    const sortedArray = [...array];
    
    // Outer loop adjusted to length - 1 to generate the exact expected step count
    for (let i = 0; i < sortedArray.length - 1; i++) {
        for (let j = 0; j < sortedArray.length - 1 - i; j++) {
            // Requirement 13: swapElements modifies the array in place if out of order
            swapElements(sortedArray, j);
            // Push the state after every comparison/potential swap
            steps.push([...sortedArray]);
        }
    }
    return steps;
};

// 18. Sort Button Logic (Bubble Sort Visualization)
sortBtn.addEventListener("click", () => {
    const steps = bubbleSortSteps(inputValues);
    
    // Clear container and render all steps
    arrayContainer.innerHTML = "";
    
    steps.forEach((step, index) => {
        const stepDiv = generateContainer();
        
        // Populate the step div using the visual span elements helper
        fillArrContainer(stepDiv, step);
        
        // Requirement 18: Identify the starting array specifically and highlight first pair
        if (index === 0) {
            stepDiv.id = "starting-array";
            highlightCurrentEls(stepDiv, 0);
        }
        
        arrayContainer.appendChild(stepDiv);
    });
});

But now your code is highlighting only the starting div.

This is painstaking and is brainstorming my head.

still struggling couldn’t fix it.

Try reading through the user stories again to make sure you have implemented them exactly as asked.

What differences did you see when comparing results from the example app to your code’s results?

You may also want to review previous forum posts on this challenge to get some ideas about how your code could be improved.

I will take a look at the forum post, Thank you.

Sounds good. There have been many posts about this challenge.

This is one of those where, even after I passed the tests, I went back and refactored my code several times to improve it.