js

PHOTO EMBED

Tue Jul 30 2024 20:59:20 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();
content_copyCOPY