js
Tue Jul 30 2024 20:59:21 GMT+0000 (Coordinated Universal Time)
Saved by @tanushahaha
const n = 20; const array = []; let audioCtx = null; let animationTimeout = null; // to hold the timeout ID for animation function playNote(freq) { if (audioCtx === null) { audioCtx = new (AudioContext || webkitAudioContext || window.webkitAudioContext)(); } const dur = 0.1; const osc = audioCtx.createOscillator(); osc.frequency.value = freq; osc.start(); osc.stop(audioCtx.currentTime + dur); const node = audioCtx.createGain(); node.gain.value = 0.1; node.gain.linearRampToValueAtTime(0, audioCtx.currentTime + dur); osc.connect(node); node.connect(audioCtx.destination); } function init() { for (let i = 0; i < n; i++) { array[i] = Math.random(); } showBars(); } function showBars(move) { const container = document.getElementById('container'); container.innerHTML = ''; for (let i = 0; i < array.length; i++) { const bar = document.createElement('div'); bar.style.height = array[i] * 100 + '%'; bar.classList.add('bar'); if (move && move.indices.includes(i)) { bar.style.backgroundColor = move.type === 'swap' ? '#BA55D0' : '#CBC3E3'; } container.appendChild(bar); } } function createSortingButton(sortName, sortFunction) { const button = document.createElement('button'); button.textContent = sortName; button.classList.add('sort-button'); button.addEventListener('click', () => { array.length = 0; init(); const copy = [...array]; const moves = sortFunction(copy); animate(moves); }); return button; } function animate(moves) { if (moves.length === 0) { showBars(); return; } const move = moves.shift(); const [i, j] = move.indices; if (move.type === 'swap') { [array[i], array[j]] = [array[j], array[i]]; playNote(300 + array[i] * 500); playNote(300 + array[j] * 500); } else if (move.type === 'comp') { playNote(200 + array[i] * 200); playNote(200 + array[j] * 200); } showBars(move); animationTimeout = setTimeout(() => animate(moves), 200); } function bubbleSort(array) { const moves = []; do { var swapped = false; for (let i = 1; i < array.length; i++) { moves.push({ indices: [i - 1, i], type: 'comp' }); if (array[i - 1] > array[i]) { swapped = true; moves.push({ indices: [i - 1, i], type: 'swap' }); [array[i - 1], array[i]] = [array[i], array[i - 1]]; } } } while (swapped); return moves; } function selectionSort(array) { const moves = []; for (let i = 0; i < array.length - 1; i++) { let minIndex = i; for (let j = i + 1; j < array.length; j++) { moves.push({ indices: [minIndex, j], type: 'comp' }); if (array[j] < array[minIndex]) { minIndex = j; } } if (minIndex !== i) { moves.push({ indices: [i, minIndex], type: 'swap' }); [array[i], array[minIndex]] = [array[minIndex], array[i]]; } } return moves; } function insertionSort(array) { const moves = []; for (let i = 1; i < array.length; i++) { let key = array[i]; let j = i - 1; while (j >= 0 && array[j] > key) { moves.push({ indices: [j, j + 1], type: 'comp' }); array[j + 1] = array[j]; j--; } moves.push({ indices: [j + 1, j + 1], type: 'swap' }); array[j + 1] = key; } return moves; } function merge(left, right, moves) { let result = []; let i = 0, j = 0; while (i < left.length && j < right.length) { moves.push({ indices: [left[i], right[j]], type: 'comp' }); if (left[i] <= right[j]) { result.push(left[i]); i++; } else { result.push(right[j]); j++; } } return result.concat(left.slice(i)).concat(right.slice(j)); } function mergeSort(array) { const moves = []; const mergeSortHelper = (array) => { if (array.length <= 1) { return array; } const middle = Math.floor(array.length / 2); const left = array.slice(0, middle); const right = array.slice(middle); return merge(mergeSortHelper(left), mergeSortHelper(right), moves); }; mergeSortHelper(array); return moves; } function partition(array, low, high, moves) { const pivot = array[high]; let i = low - 1; for (let j = low; j < high; j++) { moves.push({ indices: [array[j], pivot], type: 'comp' }); if (array[j] < pivot) { i++; moves.push({ indices: [array[i], array[j]], type: 'swap' }); [array[i], array[j]] = [array[j], array[i]]; } } moves.push({ indices: [array[i + 1], pivot], type: 'swap' }); [array[i + 1], array[high]] = [array[high], array[i + 1]]; return i + 1; } function quickSort(array) { const moves = []; const quickSortHelper = (array, low, high) => { if (low < high) { const pi = partition(array, low, high, moves); quickSortHelper(array, low, pi - 1); quickSortHelper(array, pi + 1, high); } }; quickSortHelper(array, 0, array.length - 1); return moves; } // Stop animation function function stopAnimation() { clearTimeout(animationTimeout); // Stop the current animation timeout } // Reset animation function function resetAnimation() { stopAnimation(); // Stop the current animation init(); // Re-initialize the array and display bars } // Add more sorting algorithms as needed const buttonContainer = document.getElementById('button-container'); // Create and append Stop and Reset buttons const stopButton = document.createElement('button'); stopButton.textContent = 'Stop'; stopButton.classList.add('control-button'); stopButton.addEventListener('click', stopAnimation); const resetButton = document.createElement('button'); resetButton.textContent = 'Reset'; resetButton.classList.add('control-button'); resetButton.addEventListener('click', resetAnimation); buttonContainer.appendChild(stopButton); buttonContainer.appendChild(resetButton); // Add a line break to separate control buttons from sorting buttons const lineBreak = document.createElement('br'); buttonContainer.appendChild(lineBreak); // Append sorting buttons buttonContainer.appendChild(createSortingButton('Bubble Sort', bubbleSort)); buttonContainer.appendChild(createSortingButton('Selection Sort', selectionSort)); buttonContainer.appendChild(createSortingButton('Insertion Sort', insertionSort)); buttonContainer.appendChild(createSortingButton('Merge Sort', mergeSort)); buttonContainer.appendChild(createSortingButton('Quick Sort', quickSort)); init();
Comments