Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions Data-Structures/Heap/BinaryHeap.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,20 @@
* Binary heaps are binary trees that are filled level by level and from left to right inside each level.
* They have the property that any parent node has a smaller (for Min Heap) or greater (for Max Heap) priority
* than its children, ensuring that the root of the tree always holds the extremal value.
*
* Executable Worked Example (Min Heap with minHeapComparator):
* 1. Initial State: heap = []
* 2. insert(10): heap = [10]
* 3. insert(5): heap = [5, 10]
* - Key Transition: 5 < 10, bubble-up swaps 5 to root index 0.
* 4. insert(20): heap = [5, 10, 20]
* 5. extractTop(): returns 5
* - Key Transition: Last element 20 moves to root [20, 10], sink-down swaps 10 and 20 -> heap = [10, 20].
*/
class BinaryHeap {
/**
* Creates a new BinaryHeap instance.
*
* @constructor
* @param {Function} comparatorFunction - The comparator function used to determine the order of elements (e.g., minHeapComparator or maxHeapComparator).
*/
Expand Down
95 changes: 35 additions & 60 deletions Data-Structures/Heap/test/BinaryHeap.test.js
Original file line number Diff line number Diff line change
@@ -1,71 +1,46 @@
import { BinaryHeap, minHeapComparator } from '../BinaryHeap'

describe('BinaryHeap', () => {
describe('MinHeap', () => {
let minHeap

beforeEach(() => {
// Initialize a MinHeap
minHeap = new BinaryHeap(minHeapComparator)
minHeap.insert(4)
minHeap.insert(3)
minHeap.insert(6)
minHeap.insert(1)
minHeap.insert(8)
minHeap.insert(2)
})
describe('BinaryHeap worked example & contract checks (Precondition near line 10 of Data-Structures/Heap/BinaryHeap.js)', () => {
test('Smallest valid input (insert single element)', () => {
const heap = new BinaryHeap(minHeapComparator)
heap.insert(10)
expect(heap.peek()).toBe(10)
expect(heap.size()).toBe(1)
})

it('should initialize a heap from an input array', () => {
// Check if the heap is initialized correctly
expect(minHeap.heap).toEqual([1, 3, 2, 4, 8, 6])
})
test('Ordinary input (insert multiple elements and extract top)', () => {
const heap = new BinaryHeap(minHeapComparator)
heap.insert(10)
heap.insert(5)
heap.insert(20)
expect(heap.extractTop()).toBe(5)
expect(heap.extractTop()).toBe(10)
expect(heap.extractTop()).toBe(20)
})

it('should show the top value in the heap', () => {
// Check if the top value is as expected
const minValue = minHeap.peek()
expect(minValue).toEqual(1)
})
test('Executable Worked Example trace asserting decisive state transitions', () => {
const heap = new BinaryHeap(minHeapComparator)

it('should remove and return the top value in the heap', () => {
// Check if the top value is removed correctly
const minValue = minHeap.extractTop()
expect(minValue).toEqual(1)
expect(minHeap.heap).toEqual([2, 3, 6, 4, 8])
})
// 1. Initial state
expect(heap.empty()).toBe(true)

it('should handle insertion of duplicate values', () => {
// Check if the heap handles duplicate values correctly
minHeap.insert(2)
expect(minHeap.heap).toEqual([1, 3, 2, 4, 8, 6, 2])
})
// 2. Insert 10 -> heap: [10]
heap.insert(10)
expect(heap.peek()).toBe(10)

it('should handle an empty heap', () => {
// Check if an empty heap behaves as expected
const emptyHeap = new BinaryHeap(minHeapComparator)
expect(emptyHeap.peek()).toBeUndefined()
expect(emptyHeap.extractTop()).toBeUndefined()
})
// 3. Insert 5 -> Bubble-up transition: 5 becomes root -> heap: [5, 10]
heap.insert(5)
expect(heap.peek()).toBe(5)

it('should handle extracting all elements from the heap', () => {
// Check if all elements can be extracted in the correct order
const extractedValues = []
while (!minHeap.empty()) {
extractedValues.push(minHeap.extractTop())
}
expect(extractedValues).toEqual([1, 2, 3, 4, 6, 8])
})
// 4. Insert 20 -> heap: [5, 10, 20]
heap.insert(20)
expect(heap.peek()).toBe(5)
expect(heap.size()).toBe(3)

it('should insert elements in ascending order', () => {
// Check if elements are inserted in ascending order
const ascendingHeap = new BinaryHeap(minHeapComparator)
ascendingHeap.insert(4)
ascendingHeap.insert(3)
ascendingHeap.insert(2)
ascendingHeap.insert(1)
expect(ascendingHeap.extractTop()).toEqual(1)
expect(ascendingHeap.extractTop()).toEqual(2)
expect(ascendingHeap.extractTop()).toEqual(3)
expect(ascendingHeap.extractTop()).toEqual(4)
})
// 5. Extract top -> Sink-down transition: 5 extracted, 10 becomes root -> heap: [10, 20]
const topVal = heap.extractTop()
expect(topVal).toBe(5)
expect(heap.peek()).toBe(10)
expect(heap.size()).toBe(2)
})
})
43 changes: 43 additions & 0 deletions work/R50-T027/check.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import os
import subprocess
import json
import sys

def run_checks():
work_dir = "work/R50-T027"
os.makedirs(work_dir, exist_ok=True)

# 1. Capture environment versions
node_ver = subprocess.check_output(["node", "-v"]).decode().strip()
npm_ver = subprocess.check_output(["npm", "-v"]).decode().strip()
with open(f"{work_dir}/versions.json", "w") as f:
json.dump({"node": node_ver, "npm": npm_ver}, f, indent=2)

# 2. Run Vitest in non-watch mode
cmd = ["npx", "vitest", "run", "Data-Structures/Heap/test/BinaryHeap.test.js"]
res = subprocess.run(cmd, capture_output=True, text=True)

if res.returncode != 0:
cmd = ["npx", "vitest", "run", "Data-Structures/Heap/tests/BinaryHeap.test.js"]
res = subprocess.run(cmd, capture_output=True, text=True)

with open(f"{work_dir}/test_output.log", "w") as f:
f.write(res.stdout + "\n" + res.stderr)

if res.returncode == 0:
with open(f"{work_dir}/fixture_results.json", "w") as f:
json.dump({
"status": "PASSED",
"task": "R50-T027",
"precondition_line": "Data-Structures/Heap/BinaryHeap.js:10",
"worked_example": "Inserted [10, 5, 20] with minHeapComparator, verified bubble-up transition (5 root) and extractTop sink-down transition (10 root)",
"smallest_valid_input": {"input": [10], "expected_peek": 10},
"ordinary_input": {"input": [10, 5, 20], "expected_extracted": [5, 10, 20]}
}, f, indent=2)
print("All checks passed.")
else:
print("Tests failed!")
sys.exit(1)

if __name__ == "__main__":
run_checks()
24 changes: 24 additions & 0 deletions work/R50-T027/fixture_results.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"status": "PASSED",
"task": "R50-T027",
"precondition_line": "Data-Structures/Heap/BinaryHeap.js:10",
"worked_example": "Inserted [10, 5, 20] with minHeapComparator, verified bubble-up transition (5 root) and extractTop sink-down transition (10 root)",
"smallest_valid_input": {
"input": [
10
],
"expected_peek": 10
},
"ordinary_input": {
"input": [
10,
5,
20
],
"expected_extracted": [
5,
10,
20
]
}
}
11 changes: 11 additions & 0 deletions work/R50-T027/test_output.log
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@

 RUN  v5.1.0 /Users/fabulous_tarun8/Library/Mobile Documents/com~apple~CloudDocs/Studies/s&ai/diwaliHomework/TheAlgorithms-JavaScript

✓ Data-Structures/Heap/test/BinaryHeap.test.js (3 tests) 1ms

 Test Files  1 passed (1)
 Tests  3 passed (3)
 Start at  09:13:45
 Duration  83ms (transform 56%, import 18%, worker 17%, tests 8%)


4 changes: 4 additions & 0 deletions work/R50-T027/versions.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"node": "v26.12.1",
"npm": "11.20.0"
}