From 3248a1c447945946db43636e71e72ae75fea7165 Mon Sep 17 00:00:00 2001 From: Ishita varshney Date: Mon, 25 May 2026 08:38:07 +0000 Subject: [PATCH] feat: Add GUI for Binary search and Bubble sort --- package-lock.json | 6 + web-app/assets/banners/binary-search.jpg | Bin 0 -> 48442 bytes web-app/assets/banners/bubble-sort.jpg | Bin 0 -> 44881 bytes web-app/index.html | 14 + web-app/js/projects.js | 4 + web-app/js/projects/binary-search.js | 402 +++++++++++++++++++++++ web-app/js/projects/bubble-sort.js | 364 ++++++++++++++++++++ 7 files changed, 790 insertions(+) create mode 100644 package-lock.json create mode 100644 web-app/assets/banners/binary-search.jpg create mode 100644 web-app/assets/banners/bubble-sort.jpg create mode 100644 web-app/js/projects/binary-search.js create mode 100644 web-app/js/projects/bubble-sort.js diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 00000000..1d4932ba --- /dev/null +++ b/package-lock.json @@ -0,0 +1,6 @@ +{ + "name": "python-mini-project", + "lockfileVersion": 3, + "requires": true, + "packages": {} +} diff --git a/web-app/assets/banners/binary-search.jpg b/web-app/assets/banners/binary-search.jpg new file mode 100644 index 0000000000000000000000000000000000000000..2168f687149344fef8d4ce5173bbfbc5414cf474 GIT binary patch literal 48442 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 literal 0 HcmV?d00001 diff --git a/web-app/assets/banners/bubble-sort.jpg b/web-app/assets/banners/bubble-sort.jpg new file mode 100644 index 0000000000000000000000000000000000000000..596af1d030d81a14fc32db6d435c34b00cf9f802 GIT binary patch literal 44881 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 literal 0 HcmV?d00001 diff --git a/web-app/index.html b/web-app/index.html index 451394d2..d82afda2 100644 --- a/web-app/index.html +++ b/web-app/index.html @@ -96,6 +96,18 @@

AP/GP/AGP/HP Recognizer

Armstrong Numbers

Check special number properties!

+
+ Binary Search +
+

Binary Search

+

Visualize binary search step by step!

+
+
+ Bubble Sort +
+

Bubble Sort

+

Watch bubble sort in real-time!

+
BlackJack21
@@ -650,6 +662,8 @@

Legal

+ + diff --git a/web-app/js/projects.js b/web-app/js/projects.js index cfa3ea29..74565433 100644 --- a/web-app/js/projects.js +++ b/web-app/js/projects.js @@ -12,6 +12,8 @@ function getProjectHTML(projectName) { 'flames': () => getFlamesHTML(), 'emoji-memory': () => getEmojiMemoryGameHTML(), 'fibonacci': () => getFibonacciHTML(), + 'binary-search': () => getBinarySearchHTML(), + 'bubble-sort': () => getBubbleSortHTML(), 'progression-recognizer': () => getProgressionRecognizerHTML(), 'pascal-triangle': () => getPascalTriangleHTML(), 'armstrong': () => getArmstrongHTML(), @@ -3439,6 +3441,8 @@ function initializeProject(projectName) { 'dots-boxes': 'initDotsBoxes', 'emoji-memory': 'initEmojiMemoryGame', 'fibonacci': 'initFibonacci', + 'binary-search': 'initBinarySearch', + 'bubble-sort': 'initBubbleSort', 'progression-recognizer': 'initProgressionRecognizer', 'pascal-triangle': 'initPascalTriangle', 'armstrong': 'initArmstrong', diff --git a/web-app/js/projects/binary-search.js b/web-app/js/projects/binary-search.js new file mode 100644 index 00000000..9a4ee02e --- /dev/null +++ b/web-app/js/projects/binary-search.js @@ -0,0 +1,402 @@ +function getBinarySearchHTML() { + return ` +
+

🔍 Binary Search Visualizer

+

Visualize how Binary Search finds a target in a sorted array step by step

+
+
+ + + + +
+ +
+ + + 700ms +
+ +
+ +
+ +
+ +
+
+
+ + + `; +} + +function initBinarySearch() { + const arrayInput = document.getElementById('binaryArray'); + const targetInput = document.getElementById('binaryTarget'); + const searchBtn = document.getElementById('startBinary'); + const randomBtn = document.getElementById('randomBinary'); + const barsDiv = document.getElementById('binaryBars'); + const stepsLog = document.getElementById('stepsLog'); + const resultDiv = document.getElementById('binaryResult'); + const speedSlider = document.getElementById('binarySpeed'); + const speedLabel = document.getElementById('binarySpeedLabel'); + const rangeInfo = document.getElementById('rangeInfo'); + + let isSearching = false; + + speedSlider.addEventListener('input', () => { + speedLabel.textContent = speedSlider.value + 'ms'; + }); + + function sleep(ms) { + return new Promise(resolve => setTimeout(resolve, ms)); + } + + function renderBars(arr, low, high, mid, found = -1, eliminated = []) { + const maxVal = Math.max(...arr); + barsDiv.innerHTML = arr.map((val, i) => { + const heightPct = Math.max(15, (val / maxVal) * 180); + let cls = 'bin-bar'; + let tag = ''; + + if (found === i) { + cls += ' found'; + tag = '✅'; + } else if (eliminated.includes(i)) { + cls += ' eliminated'; + } else if (i === mid) { + cls += ' mid'; + tag = 'MID'; + } else if (i >= low && i <= high) { + cls += ' low-high'; + } else { + cls += ' eliminated'; + } + + if (i === low && found === -1 && !eliminated.includes(i)) tag = tag || 'LOW'; + if (i === high && found === -1 && !eliminated.includes(i)) tag = tag || 'HIGH'; + + return `
+ ${tag ? `${tag}` : ''} + ${val} +
`; + }).join(''); + + if (mid >= 0 && found === -1) { + rangeInfo.textContent = `🔎 Low: index ${low} (${arr[low]}) | Mid: index ${mid} (${arr[mid]}) | High: index ${high} (${arr[high]})`; + } + } + + function addStep(msg) { + const entry = document.createElement('div'); + entry.className = 'step-entry'; + entry.textContent = msg; + stepsLog.appendChild(entry); + stepsLog.scrollTop = stepsLog.scrollHeight; + } + + async function binarySearchVisualize(arr, target) { + let low = 0; + let high = arr.length - 1; + let step = 1; + const eliminated = []; + const delay = () => parseInt(speedSlider.value); + + while (low <= high) { + const mid = Math.floor((low + high) / 2); + renderBars(arr, low, high, mid, -1, eliminated); + addStep(`Step ${step++}: low=${low}, high=${high}, mid=${mid} → arr[mid]=${arr[mid]}`); + await sleep(delay()); + + if (arr[mid] === target) { + renderBars(arr, low, high, -1, mid, eliminated); + addStep(`✅ Found ${target} at index ${mid}!`); + return mid; + } else if (arr[mid] > target) { + addStep(`${arr[mid]} > ${target} → Search LEFT half`); + for (let i = mid; i <= high; i++) eliminated.push(i); + high = mid - 1; + } else { + addStep(`${arr[mid]} < ${target} → Search RIGHT half`); + for (let i = low; i <= mid; i++) eliminated.push(i); + low = mid + 1; + } + await sleep(delay()); + } + + renderBars(arr, 0, arr.length - 1, -1, -1, Array.from({ length: arr.length }, (_, i) => i)); + addStep(`❌ ${target} not found in array.`); + return -1; + } + + randomBtn.addEventListener('click', () => { + const arr = Array.from({ length: 8 }, (_, i) => (i + 1) * Math.floor(Math.random() * 10 + 5)) + .sort((a, b) => a - b); + arrayInput.value = arr.join(' '); + targetInput.value = arr[Math.floor(Math.random() * arr.length)]; + renderBars(arr, 0, arr.length - 1, -1); + stepsLog.innerHTML = ''; + resultDiv.innerHTML = ''; + rangeInfo.textContent = ''; + }); + + searchBtn.addEventListener('click', async () => { + if (isSearching) return; + + const rawArr = arrayInput.value.trim(); + const rawTarget = targetInput.value.trim(); + + if (!rawArr || !rawTarget) { + resultDiv.innerHTML = `

⚠️ Please enter array and target!

`; + return; + } + + const arr = rawArr.split(/\s+/).map(Number); + const target = Number(rawTarget); + + if (arr.some(isNaN) || isNaN(target)) { + resultDiv.innerHTML = `

⚠️ Please enter valid integers only!

`; + return; + } + + if (JSON.stringify(arr) !== JSON.stringify([...arr].sort((a, b) => a - b))) { + resultDiv.innerHTML = `

⚠️ Array must be sorted for Binary Search!

`; + return; + } + + isSearching = true; + searchBtn.disabled = true; + stepsLog.innerHTML = ''; + resultDiv.innerHTML = `

⏳ Searching...

`; + rangeInfo.textContent = ''; + + renderBars(arr, 0, arr.length - 1, -1); + const foundIdx = await binarySearchVisualize(arr, target); + + if (foundIdx !== -1) { + resultDiv.innerHTML = ` +

✅ Found! ${target} is at index ${foundIdx} (position ${foundIdx + 1})

+
+
Mid element
+
Search range
+
Found
+
+ `; + } else { + resultDiv.innerHTML = ` +

❌ Not Found! ${target} is not in the array.

+ `; + } + + isSearching = false; + searchBtn.disabled = false; + }); + + // Initial render + const initArr = [2, 5, 8, 12, 16, 23, 38, 56]; + arrayInput.value = initArr.join(' '); + targetInput.value = 23; + renderBars(initArr, 0, initArr.length - 1, -1); +} \ No newline at end of file diff --git a/web-app/js/projects/bubble-sort.js b/web-app/js/projects/bubble-sort.js new file mode 100644 index 00000000..0cf7787b --- /dev/null +++ b/web-app/js/projects/bubble-sort.js @@ -0,0 +1,364 @@ +function getBubbleSortHTML() { + return ` +
+

🔄 Bubble Sort Visualizer

+

Visualize Bubble Sort algorithm with real-time bar animations

+
+
+ +
+ + +
+ + +
+ +
+ + + 400ms +
+ +
+ +
+ +
+
+
+ + + `; +} + +function initBubbleSort() { + const input = document.getElementById('bubbleInput'); + const startBtn = document.getElementById('startBubble'); + const randomBtn = document.getElementById('randomBubble'); + const barsDiv = document.getElementById('bubbleBars'); + const statsDiv = document.getElementById('bubbleStats'); + const resultDiv = document.getElementById('bubbleResult'); + const speedSlider = document.getElementById('bubbleSpeed'); + const speedLabel = document.getElementById('speedLabel'); + const btnAsc = document.getElementById('btnAsc'); + const btnDesc = document.getElementById('btnDesc'); + + let isAscending = true; + let isSorting = false; + let comparisons = 0; + let swaps = 0; + + // Speed slider + speedSlider.addEventListener('input', () => { + speedLabel.textContent = speedSlider.value + 'ms'; + }); + + // Order toggle + btnAsc.addEventListener('click', () => { + isAscending = true; + btnAsc.classList.add('active'); + btnDesc.classList.remove('active'); + }); + + btnDesc.addEventListener('click', () => { + isAscending = false; + btnDesc.classList.add('active'); + btnAsc.classList.remove('active'); + }); + + // Random array + randomBtn.addEventListener('click', () => { + const arr = Array.from({ length: 8 }, () => Math.floor(Math.random() * 90) + 10); + input.value = arr.join(' '); + renderBars(arr); + resultDiv.innerHTML = ''; + statsDiv.innerHTML = ''; + }); + + function sleep(ms) { + return new Promise(resolve => setTimeout(resolve, ms)); + } + + function renderBars(arr, comparing = [], swapping = [], sorted = []) { + const maxVal = Math.max(...arr); + barsDiv.innerHTML = arr.map((val, i) => { + const heightPct = Math.max(15, (val / maxVal) * 180); + let cls = 'bar'; + if (swapping.includes(i)) cls += ' swapping'; + else if (comparing.includes(i)) cls += ' comparing'; + else if (sorted.includes(i)) cls += ' sorted'; + return `
+ ${val} +
`; + }).join(''); + + statsDiv.innerHTML = ` +
🔍 Comparisons: ${comparisons}
+
🔄 Swaps: ${swaps}
+ `; + } + + async function bubbleSortVisualize(arr) { + const n = arr.length; + const sortedIndices = []; + const delay = () => parseInt(speedSlider.value); + + for (let i = 0; i < n; i++) { + let swapped = false; + for (let j = 0; j < n - i - 1; j++) { + comparisons++; + renderBars(arr, [j, j + 1], [], sortedIndices); + await sleep(delay()); + + const shouldSwap = isAscending + ? arr[j] > arr[j + 1] + : arr[j] < arr[j + 1]; + + if (shouldSwap) { + swaps++; + renderBars(arr, [], [j, j + 1], sortedIndices); + await sleep(delay()); + [arr[j], arr[j + 1]] = [arr[j + 1], arr[j]]; + swapped = true; + } + } + sortedIndices.push(n - i - 1); + renderBars(arr, [], [], sortedIndices); + if (!swapped) break; + } + + // Mark all sorted + const allSorted = Array.from({ length: n }, (_, i) => i); + renderBars(arr, [], [], allSorted); + return arr; + } + + startBtn.addEventListener('click', async () => { + if (isSorting) return; + + const raw = input.value.trim(); + if (!raw) { + resultDiv.innerHTML = `

⚠️ Please enter numbers!

`; + return; + } + + const arr = raw.split(/\s+/).map(Number); + if (arr.some(isNaN)) { + resultDiv.innerHTML = `

⚠️ Please enter valid integers only!

`; + return; + } + + if (arr.length < 2) { + resultDiv.innerHTML = `

⚠️ Enter at least 2 numbers!

`; + return; + } + + isSorting = true; + comparisons = 0; + swaps = 0; + startBtn.disabled = true; + resultDiv.innerHTML = `

⏳ Sorting...

`; + + renderBars([...arr]); + const sorted = await bubbleSortVisualize([...arr]); + + resultDiv.innerHTML = ` +

+ ✅ Sorted: [ ${sorted.join(', ')} ] +

+
+
Comparing
+
Swapping
+
Sorted
+
+ `; + + isSorting = false; + startBtn.disabled = false; + }); + + // Initial random render + const initArr = [64, 34, 25, 12, 22, 11, 90]; + input.value = initArr.join(' '); + renderBars(initArr); +} \ No newline at end of file