├── .gitignore ├── .github ├── ISSUE_TEMPLATE │ └── custom.md └── PULL_REQUEST_TEMPLATE │ └── pull_request_template.md ├── data-structures ├── trees │ ├── TreeNode.js │ └── BinaryTree.js ├── graphs │ ├── GraphNode.js │ └── Graph.js ├── stacks-and-queues │ ├── Queue.js │ └── Stack.js ├── sets-and-maps │ ├── Set.js │ └── Map.js ├── linked-lists │ ├── SinglyLinkedList.js │ ├── CircularLinkedList.js │ └── DoublyLinkedList.js ├── trie │ └── Trie.js ├── disjoint-set │ └── DisjointSet.js ├── hash-tables │ └── HashTable.js └── heaps │ ├── MaxHeap.js │ └── MinHeap.js ├── algorithms ├── searching │ ├── linearSearch.js │ ├── binarySearch.js │ ├── InterpolationSearch.js │ ├── depthFirstSearch.js │ └── breadthFirstSearch.js ├── numerical │ ├── fastExponentiation.js │ ├── gcd.js │ └── primalityTesting.js ├── string │ ├── stringMatching.js │ ├── levenshteinDistance.js │ └── longestCommonSubstring.js ├── sorting │ ├── insertionSort.js │ ├── bubbleSort.js │ ├── quickSort.js │ ├── selectionSort.js │ ├── countingSort.js │ ├── heapSort.js │ ├── mergeSort.js │ └── radixSort.js ├── dynamic-programming │ ├── fibonacci.js │ ├── knapsack.js │ ├── matrixChainMultiplication.js │ ├── editDistance.js │ └── longestCommonSubsequence.js ├── graph-algorithms │ ├── topologicalSort.js │ ├── floydWarshall.js │ ├── prim.js │ ├── kruskal.js │ ├── bellmanFord.js │ └── dijkstra.js ├── randomized │ ├── randomizedQuickSort.js │ └── randomizedPrimalityTesting.js ├── ml-statistical │ ├── linearRegression.js │ ├── decisionTrees.js │ └── logisticRegression.js ├── geometry │ ├── lineIntersection.js │ └── convexHull.js └── network-flow │ ├── maxFlowMinCutTheorem.js │ └── fordFulkerson.js ├── utils └── utilityFunctions.js ├── test ├── algorithms │ ├── ml-statistical │ │ ├── logisticRegression.test.js │ │ ├── decisionTrees.test.js │ │ ├── linearRegression.test.js │ │ └── kMeansClustering.test.js │ ├── network-flow │ │ ├── maxFlowMinCutTheorem.test.js │ │ └── fordFulkerson.test.js │ ├── randomized │ │ ├── randomizedPrimalityTesting.test.js │ │ └── randomizedQuickSort.test.js │ ├── graph-algorithms │ │ ├── prim.test.js │ │ ├── kruskal.test.js │ │ ├── topologicalSort.test.js │ │ ├── dijkstra.test.js │ │ └── bellmanFord.test.js │ ├── dynamic-programming │ │ ├── matrixChainMultiplication.test.js │ │ ├── editDistance.test.js │ │ ├── longestCommonSubsequence.test.js │ │ ├── fibonacci.test.js │ │ └── knapsack.test.js │ ├── numerical │ │ ├── gcd.test.js │ │ ├── fastExponentiation.test.js │ │ └── primalityTesting.test.js │ ├── sorting │ │ ├── heapSort.test.js │ │ ├── quickSort.test.js │ │ ├── radixSort.test.js │ │ ├── bubbleSort.test.js │ │ ├── mergeSort.test.js │ │ ├── insertionSort.test.js │ │ ├── selectionSort.test.js │ │ └── countingSort.test.js │ ├── geometry │ │ ├── closestPairOfPoints.test.js │ │ ├── lineIntersection.test.js │ │ └── convexHull.test.js │ ├── string │ │ ├── stringMatching.test.js │ │ ├── levenshteinDistance.test.js │ │ └── longestCommonSubstring.test.js │ └── searching │ │ ├── linearSearch.test.js │ │ ├── binarySearch.test.js │ │ ├── depthFirstSearch.test.js │ │ └── breadthFirstSearch.test.js ├── data-structures │ ├── trees │ │ ├── AVLTree.test.js │ │ ├── TreeNode.test.js │ │ └── BinaryTree.test.js │ ├── trie │ │ └── Trie.test.js │ ├── linked-lists │ │ ├── SinglyLinkedList.test.js │ │ ├── CircularLinkedList.test.js │ │ └── DoublyLinkedList.test.js │ ├── heaps │ │ ├── MaxHeap.test.js │ │ └── MinHeap.test.js │ ├── graphs │ │ ├── GraphNode.test.js │ │ └── Graph.test.js │ ├── disjoint-set │ │ └── DisjointSet.test.js │ ├── stacks-and-queues │ │ ├── Stack.test.js │ │ └── Queue.test.js │ ├── hash-tables │ │ └── HashTable.test.js │ └── sets-and-maps │ │ ├── Set.test.js │ │ └── Map.test.js └── utils │ └── utilityFunctions.test.js ├── SECURITY.md ├── package.json ├── LICENSE └── docs ├── utils └── utilityFunctions.md ├── data-structures ├── trees │ ├── AVLTree.md │ ├── TreeNode.md │ └── BinaryTree.md ├── linked-lists │ ├── SinglyLinkedList.md │ ├── CircularLinkedList.md │ └── DoublyLinkedList.md ├── trie │ └── Trie.md ├── graphs │ └── GraphNode.md ├── stacks-and-queues │ ├── Stack.md │ └── Queue.md └── heaps │ ├── MaxHeap.md │ └── MinHeap.md └── algorithms ├── numerical ├── fastExponentiation.md └── primalityTesting.md ├── dynamic-programming ├── fibonacci .md ├── knapsack.md ├── editDistance.md └── longestCommonSubsequence.md ├── sorting ├── mergeSort.md ├── insertionSort.md └── heapSort.md ├── searching └── linearSearch.md ├── randomized └── randomizedQuickSort.md ├── geometry ├── lineIntersection.md └── convexHull.md └── graph-algorithms └── dijkstra.md /.gitignore: -------------------------------------------------------------------------------- 1 | # Ignore node_modules directory 2 | node_modules/ 3 | 4 | # Ignore Visual Studio Code settings 5 | .vscode/ -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/custom.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Custom issue template 3 | about: Describe this issue template's purpose here. 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | 11 | -------------------------------------------------------------------------------- /data-structures/trees/TreeNode.js: -------------------------------------------------------------------------------- 1 | class TreeNode { 2 | constructor(value) { 3 | this.value = value; 4 | this.left = null; 5 | this.right = null; 6 | } 7 | } 8 | 9 | module.exports = TreeNode; -------------------------------------------------------------------------------- /algorithms/searching/linearSearch.js: -------------------------------------------------------------------------------- 1 | class LinearSearch { 2 | constructor(arr) { 3 | this.arr = arr; 4 | } 5 | 6 | search(target) { 7 | for (let i = 0; i < this.arr.length; i++) { 8 | if (this.arr[i] === target) { 9 | return i; 10 | } 11 | } 12 | return -1; 13 | } 14 | } 15 | 16 | module.exports = LinearSearch; 17 | -------------------------------------------------------------------------------- /utils/utilityFunctions.js: -------------------------------------------------------------------------------- 1 | class UtilityFunctions { 2 | static sum(arr) { 3 | return arr.reduce((acc, current) => acc + current, 0); 4 | } 5 | 6 | static average(arr) { 7 | if (arr.length === 0) { 8 | return 0; 9 | } 10 | const total = this.sum(arr); 11 | return total / arr.length; 12 | } 13 | } 14 | 15 | module.exports = UtilityFunctions; 16 | -------------------------------------------------------------------------------- /test/algorithms/ml-statistical/logisticRegression.test.js: -------------------------------------------------------------------------------- 1 | const LogisticRegression = require('../../../algorithms/ml-statistical/logisticRegression'); 2 | 3 | describe('LogisticRegression', () => { 4 | it('should throw an error with empty data', () => { 5 | const data = []; 6 | 7 | const lr = new LogisticRegression(); 8 | 9 | expect(() => lr.fit(data)).toThrow('Data must not be empty.'); 10 | }); 11 | }); 12 | -------------------------------------------------------------------------------- /algorithms/numerical/fastExponentiation.js: -------------------------------------------------------------------------------- 1 | class FastExponentiation { 2 | static power(base, exponent) { 3 | if (exponent === 0) { 4 | return 1; 5 | } else if (exponent % 2 === 0) { 6 | const result = this.power(base, exponent / 2); 7 | return result * result; 8 | } else { 9 | return base * this.power(base, exponent - 1); 10 | } 11 | } 12 | } 13 | 14 | module.exports = FastExponentiation; 15 | -------------------------------------------------------------------------------- /algorithms/string/stringMatching.js: -------------------------------------------------------------------------------- 1 | class StringMatching { 2 | static findSubstringOccurrences(text, substring) { 3 | if (!text || !substring) { 4 | return []; 5 | } 6 | 7 | const occurrences = []; 8 | for (let i = 0; i < text.length; i++) { 9 | if (text.substring(i, i + substring.length) === substring) { 10 | occurrences.push(i); 11 | } 12 | } 13 | 14 | return occurrences; 15 | } 16 | } 17 | 18 | module.exports = StringMatching; 19 | -------------------------------------------------------------------------------- /algorithms/sorting/insertionSort.js: -------------------------------------------------------------------------------- 1 | class InsertionSort { 2 | constructor(arr) { 3 | this.arr = arr; 4 | } 5 | 6 | sort() { 7 | const n = this.arr.length; 8 | 9 | for (let i = 1; i < n; i++) { 10 | const key = this.arr[i]; 11 | let j = i - 1; 12 | 13 | while (j >= 0 && this.arr[j] > key) { 14 | this.arr[j + 1] = this.arr[j]; 15 | j--; 16 | } 17 | 18 | this.arr[j + 1] = key; 19 | } 20 | } 21 | } 22 | 23 | module.exports = InsertionSort; 24 | -------------------------------------------------------------------------------- /data-structures/graphs/GraphNode.js: -------------------------------------------------------------------------------- 1 | class GraphNode { 2 | constructor(value) { 3 | this.value = value; 4 | this.neighbors = new Set(); 5 | } 6 | 7 | addNeighbor(neighborNode) { 8 | this.neighbors.add(neighborNode); 9 | neighborNode.neighbors.add(this); 10 | } 11 | 12 | removeNeighbor(neighborNode) { 13 | this.neighbors.delete(neighborNode); 14 | neighborNode.neighbors.delete(this); 15 | } 16 | 17 | getNeighbors() { 18 | return Array.from(this.neighbors); 19 | } 20 | } 21 | 22 | module.exports = GraphNode; 23 | -------------------------------------------------------------------------------- /algorithms/dynamic-programming/fibonacci.js: -------------------------------------------------------------------------------- 1 | class Fibonacci { 2 | constructor() { 3 | this.memo = new Map(); 4 | } 5 | 6 | calculateFibonacci(n) { 7 | if (this.memo.has(n)) { 8 | return this.memo.get(n); 9 | } 10 | 11 | if (n <= 0) { 12 | return 0; 13 | } 14 | 15 | if (n === 1) { 16 | return 1; 17 | } 18 | 19 | const result = this.calculateFibonacci(n - 1) + this.calculateFibonacci(n - 2); 20 | this.memo.set(n, result); 21 | 22 | return result; 23 | } 24 | } 25 | 26 | module.exports = Fibonacci; 27 | -------------------------------------------------------------------------------- /algorithms/sorting/bubbleSort.js: -------------------------------------------------------------------------------- 1 | class BubbleSort { 2 | constructor(arr) { 3 | this.arr = arr; 4 | } 5 | 6 | sort() { 7 | const n = this.arr.length; 8 | 9 | for (let i = 0; i < n - 1; i++) { 10 | for (let j = 0; j < n - i - 1; j++) { 11 | if (this.arr[j] > this.arr[j + 1]) { 12 | this.swap(j, j + 1); 13 | } 14 | } 15 | } 16 | } 17 | 18 | swap(i, j) { 19 | const temp = this.arr[i]; 20 | this.arr[i] = this.arr[j]; 21 | this.arr[j] = temp; 22 | } 23 | } 24 | 25 | module.exports = BubbleSort; 26 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security Policy 2 | 3 | ## Supported Versions 4 | 5 | Use this section to tell people about which versions of your project are 6 | currently being supported with security updates. 7 | 8 | | Version | Supported | 9 | | ------- | ------------------ | 10 | | 5.1.x | :white_check_mark: | 11 | | 5.0.x | :x: | 12 | | 4.0.x | :white_check_mark: | 13 | | < 4.0 | :x: | 14 | 15 | ## Reporting a Vulnerability 16 | 17 | Use this section to tell people how to report a vulnerability. 18 | 19 | Tell them where to go, how often they can expect to get an update on a 20 | reported vulnerability, what to expect if the vulnerability is accepted or 21 | declined, etc. 22 | -------------------------------------------------------------------------------- /algorithms/searching/binarySearch.js: -------------------------------------------------------------------------------- 1 | class BinarySearch { 2 | constructor(arr) { 3 | this.arr = arr; 4 | } 5 | 6 | search(target) { 7 | let left = 0; 8 | let right = this.arr.length - 1; 9 | 10 | while (left <= right) { 11 | const middle = Math.floor((left + right) / 2); 12 | 13 | if (this.arr[middle] === target) { 14 | return middle; 15 | } 16 | 17 | if (this.arr[middle] < target) { 18 | left = middle + 1; 19 | } else { 20 | right = middle - 1; 21 | } 22 | } 23 | 24 | return -1; 25 | } 26 | } 27 | 28 | module.exports = BinarySearch; 29 | -------------------------------------------------------------------------------- /algorithms/sorting/quickSort.js: -------------------------------------------------------------------------------- 1 | class QuickSort { 2 | constructor(arr) { 3 | this.arr = arr; 4 | } 5 | 6 | sort() { 7 | if (this.arr.length <= 1) { 8 | return this.arr; 9 | } 10 | 11 | const pivot = this.arr[0]; 12 | const left = []; 13 | const right = []; 14 | 15 | for (let i = 1; i < this.arr.length; i++) { 16 | if (this.arr[i] < pivot) { 17 | left.push(this.arr[i]); 18 | } else { 19 | right.push(this.arr[i]); 20 | } 21 | } 22 | 23 | return new QuickSort(left).sort().concat(pivot, new QuickSort(right).sort()); 24 | } 25 | } 26 | 27 | module.exports = QuickSort; 28 | -------------------------------------------------------------------------------- /test/data-structures/trees/AVLTree.test.js: -------------------------------------------------------------------------------- 1 | const assert = require('assert'); 2 | const AVLTree = require('../../../data-structures/trees/AVLTree'); 3 | 4 | describe('AVLTree', () => { 5 | it('should create an empty AVL tree', () => { 6 | const avlTree = new AVLTree(); 7 | assert.strictEqual(avlTree.root, null); 8 | }); 9 | 10 | it('should insert values into the AVL tree', () => { 11 | const avlTree = new AVLTree(); 12 | avlTree.insert(10); 13 | avlTree.insert(5); 14 | avlTree.insert(15); 15 | 16 | assert.strictEqual(avlTree.root.value, 10); 17 | assert.strictEqual(avlTree.root.left.value, 5); 18 | assert.strictEqual(avlTree.root.right.value, 15); 19 | }); 20 | }); 21 | -------------------------------------------------------------------------------- /test/algorithms/ml-statistical/decisionTrees.test.js: -------------------------------------------------------------------------------- 1 | const DecisionTree = require('../../../algorithms/ml-statistical/decisionTrees'); 2 | 3 | // Test the DecisionTree class 4 | describe('DecisionTree', () => { 5 | test('should insert and search values correctly', () => { 6 | const decisionTree = new DecisionTree(); 7 | 8 | // Insert values into the decision tree 9 | decisionTree.insert(10); 10 | decisionTree.insert(5); 11 | decisionTree.insert(15); 12 | decisionTree.insert(2); 13 | decisionTree.insert(7); 14 | 15 | // Search for values in the decision tree 16 | expect(decisionTree.search(7)).toBe(true); 17 | expect(decisionTree.search(20)).toBe(false); 18 | }); 19 | }); 20 | -------------------------------------------------------------------------------- /test/algorithms/network-flow/maxFlowMinCutTheorem.test.js: -------------------------------------------------------------------------------- 1 | const MaxFlowMinCutGraph = require('../../../algorithms/network-flow/maxFlowMinCutTheorem'); 2 | 3 | describe('Max Flow Min Cut Theorem', () => { 4 | it('should find the maximum flow in a flow network', () => { 5 | const graph = new MaxFlowMinCutGraph(6); 6 | 7 | graph.addEdge(0, 1, 10); 8 | graph.addEdge(0, 2, 10); 9 | graph.addEdge(1, 2, 2); 10 | graph.addEdge(1, 3, 4); 11 | graph.addEdge(1, 4, 8); 12 | graph.addEdge(2, 4, 9); 13 | graph.addEdge(3, 5, 10); 14 | graph.addEdge(4, 3, 6); 15 | graph.addEdge(4, 5, 10); 16 | 17 | const maxFlow = graph.fordFulkerson(0, 5); 18 | expect(maxFlow).toEqual(19); 19 | }); 20 | }); 21 | -------------------------------------------------------------------------------- /algorithms/numerical/gcd.js: -------------------------------------------------------------------------------- 1 | class GCD { 2 | static findGCD(a, b) { 3 | if (b === 0) { 4 | return a; 5 | } 6 | return this.findGCD(b, a % b); 7 | } 8 | 9 | static findLCM(a, b) { 10 | // Calculate the least common multiple (LCM) using the GCD 11 | return (a * b) / this.findGCD(a, b); 12 | } 13 | 14 | static findGCDOfArray(numbers) { 15 | if (numbers.length < 2) { 16 | throw new Error('At least two numbers are required to find the GCD.'); 17 | } 18 | let result = numbers[0]; 19 | for (let i = 1; i < numbers.length; i++) { 20 | result = this.findGCD(result, numbers[i]); 21 | } 22 | return result; 23 | } 24 | } 25 | 26 | module.exports = GCD; 27 | -------------------------------------------------------------------------------- /algorithms/sorting/selectionSort.js: -------------------------------------------------------------------------------- 1 | class SelectionSort { 2 | constructor(arr) { 3 | this.arr = arr; 4 | } 5 | 6 | sort() { 7 | const n = this.arr.length; 8 | 9 | for (let i = 0; i < n - 1; i++) { 10 | let minIndex = i; 11 | 12 | for (let j = i + 1; j < n; j++) { 13 | if (this.arr[j] < this.arr[minIndex]) { 14 | minIndex = j; 15 | } 16 | } 17 | 18 | if (minIndex !== i) { 19 | this.swap(i, minIndex); 20 | } 21 | } 22 | } 23 | 24 | swap(i, j) { 25 | const temp = this.arr[i]; 26 | this.arr[i] = this.arr[j]; 27 | this.arr[j] = temp; 28 | } 29 | } 30 | 31 | module.exports = SelectionSort; 32 | -------------------------------------------------------------------------------- /algorithms/dynamic-programming/knapsack.js: -------------------------------------------------------------------------------- 1 | class Knapsack { 2 | constructor() { } 3 | 4 | findMaxValue(weights, values, capacity) { 5 | const n = values.length; 6 | const dp = Array.from({ length: n + 1 }, () => Array(capacity + 1).fill(0)); 7 | 8 | for (let i = 0; i <= n; i++) { 9 | for (let w = 0; w <= capacity; w++) { 10 | if (i === 0 || w === 0) { 11 | dp[i][w] = 0; 12 | } else if (weights[i - 1] <= w) { 13 | dp[i][w] = Math.max(values[i - 1] + dp[i - 1][w - weights[i - 1]], dp[i - 1][w]); 14 | } else { 15 | dp[i][w] = dp[i - 1][w]; 16 | } 17 | } 18 | } 19 | 20 | return dp[n][capacity]; 21 | } 22 | } 23 | 24 | module.exports = Knapsack; 25 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "adv-dsa", 3 | "version": "1.1.5", 4 | "description": "JS-DSA is a comprehensive collection of data structures and algorithms implemented in JavaScript. This project is designed to be a helpful resource for developers, students, and anyone interested in learning about data structures and algorithms through practical JavaScript examples.", 5 | "keywords": [ 6 | "data-structures", 7 | "algorithms", 8 | "javascript", 9 | "npm-package" 10 | ], 11 | "main": "index.js", 12 | "scripts": { 13 | "test": "jest" 14 | }, 15 | "repository": { 16 | "type": "git", 17 | "url": "https://github.com/PB2204/js-dsa.git" 18 | }, 19 | "author": "Pabitra Banerjee", 20 | "license": "MIT", 21 | "devDependencies": { 22 | "jest": "^28.1.3" 23 | } 24 | } -------------------------------------------------------------------------------- /algorithms/searching/InterpolationSearch.js: -------------------------------------------------------------------------------- 1 | class InterpolationSearch { 2 | constructor(arr) { 3 | this.arr = arr; 4 | } 5 | 6 | search(target) { 7 | let low = 0; 8 | let high = this.arr.length - 1; 9 | 10 | while (low <= high && target >= this.arr[low] && target <= this.arr[high]) { 11 | if (low === high) { 12 | if (this.arr[low] === target) return low; 13 | return -1; 14 | } 15 | 16 | const pos = Math.floor( 17 | low + ((target - this.arr[low]) / (this.arr[high] - this.arr[low])) * (high - low) 18 | ); 19 | 20 | if (this.arr[pos] === target) return pos; 21 | if (this.arr[pos] < target) low = pos + 1; 22 | else high = pos - 1; 23 | } 24 | 25 | return -1; 26 | } 27 | } 28 | module.exports = InterpolationSearch; 29 | -------------------------------------------------------------------------------- /algorithms/string/levenshteinDistance.js: -------------------------------------------------------------------------------- 1 | class LevenshteinDistance { 2 | static computeDistance(str1, str2) { 3 | const m = str1.length; 4 | const n = str2.length; 5 | 6 | const dp = new Array(m + 1).fill(0).map(() => new Array(n + 1).fill(0)); 7 | 8 | for (let i = 0; i <= m; i++) { 9 | for (let j = 0; j <= n; j++) { 10 | if (i === 0) { 11 | dp[i][j] = j; 12 | } else if (j === 0) { 13 | dp[i][j] = i; 14 | } else if (str1[i - 1] === str2[j - 1]) { 15 | dp[i][j] = dp[i - 1][j - 1]; 16 | } else { 17 | dp[i][j] = 1 + Math.min(dp[i - 1][j], dp[i][j - 1], dp[i - 1][j - 1]); 18 | } 19 | } 20 | } 21 | 22 | return dp[m][n]; 23 | } 24 | } 25 | 26 | module.exports = LevenshteinDistance; 27 | -------------------------------------------------------------------------------- /algorithms/searching/depthFirstSearch.js: -------------------------------------------------------------------------------- 1 | class GraphNode { 2 | constructor(value) { 3 | this.value = value; 4 | this.children = []; 5 | } 6 | 7 | addChild(node) { 8 | this.children.push(node); 9 | } 10 | } 11 | 12 | class DepthFirstSearch { 13 | constructor(node) { 14 | this.node = node; 15 | this.visited = new Set(); 16 | this.result = []; 17 | } 18 | 19 | search() { 20 | this.dfs(this.node); 21 | return this.result; 22 | } 23 | 24 | dfs(node) { 25 | if (node === null) return; 26 | this.visited.add(node); 27 | this.result.push(node.value); 28 | 29 | for (const child of node.children) { 30 | if (!this.visited.has(child)) { 31 | this.dfs(child); 32 | } 33 | } 34 | } 35 | } 36 | 37 | module.exports = { GraphNode, DepthFirstSearch }; 38 | -------------------------------------------------------------------------------- /algorithms/dynamic-programming/matrixChainMultiplication.js: -------------------------------------------------------------------------------- 1 | class MatrixChainMultiplication { 2 | constructor() {} 3 | 4 | findMinMultiplications(dimensions) { 5 | const n = dimensions.length; 6 | const dp = Array.from({ length: n }, () => Array(n).fill(0)); 7 | 8 | for (let len = 2; len < n; len++) { 9 | for (let i = 1; i < n - len + 1; i++) { 10 | const j = i + len - 1; 11 | dp[i][j] = Number.MAX_SAFE_INTEGER; 12 | for (let k = i; k <= j - 1; k++) { 13 | const cost = dp[i][k] + dp[k + 1][j] + dimensions[i - 1] * dimensions[k] * dimensions[j]; 14 | if (cost < dp[i][j]) { 15 | dp[i][j] = cost; 16 | } 17 | } 18 | } 19 | } 20 | 21 | return dp[1][n - 1]; 22 | } 23 | } 24 | 25 | module.exports = MatrixChainMultiplication; 26 | -------------------------------------------------------------------------------- /algorithms/graph-algorithms/topologicalSort.js: -------------------------------------------------------------------------------- 1 | class TopologicalSort { 2 | constructor(graph) { 3 | this.graph = graph; 4 | this.visited = new Set(); 5 | this.stack = []; 6 | } 7 | 8 | // Helper function for topological sorting 9 | topologicalSortUtil(node) { 10 | this.visited.add(node); 11 | 12 | for (const neighbor of this.graph[node]) { 13 | if (!this.visited.has(neighbor)) { 14 | this.topologicalSortUtil(neighbor); 15 | } 16 | } 17 | 18 | this.stack.unshift(node); 19 | } 20 | 21 | // Perform topological sorting 22 | performTopologicalSort() { 23 | for (const node in this.graph) { 24 | if (!this.visited.has(node)) { 25 | this.topologicalSortUtil(node); 26 | } 27 | } 28 | 29 | return this.stack; 30 | } 31 | } 32 | 33 | module.exports = TopologicalSort; 34 | -------------------------------------------------------------------------------- /test/algorithms/randomized/randomizedPrimalityTesting.test.js: -------------------------------------------------------------------------------- 1 | const RandomizedPrimalityTesting = require('../../../algorithms/randomized/randomizedPrimalityTesting'); 2 | 3 | describe('RandomizedPrimalityTesting', () => { 4 | describe('isPrime', () => { 5 | it('should correctly identify prime numbers', () => { 6 | const rpt = new RandomizedPrimalityTesting(); 7 | const primeNumbers = [17n, 19n, 23n, 29n, 31n]; 8 | primeNumbers.forEach((n) => { 9 | expect(rpt.isPrime(n, 5)).toBe(true); 10 | }); 11 | }); 12 | 13 | it('should correctly identify composite numbers', () => { 14 | const rpt = new RandomizedPrimalityTesting(); 15 | const compositeNumbers = [4n, 9n, 15n, 25n, 27n]; 16 | compositeNumbers.forEach((n) => { 17 | expect(rpt.isPrime(n, 5)).toBe(false); 18 | }); 19 | }); 20 | }); 21 | }); 22 | -------------------------------------------------------------------------------- /data-structures/stacks-and-queues/Queue.js: -------------------------------------------------------------------------------- 1 | class Queue { 2 | constructor() { 3 | this.items = []; 4 | } 5 | 6 | // Add an element to the queue. 7 | enqueue(element) { 8 | this.items.push(element); 9 | } 10 | 11 | // Remove and return the front element from the queue. 12 | dequeue() { 13 | if (this.isEmpty()) { 14 | return null; 15 | } 16 | return this.items.shift(); 17 | } 18 | 19 | // Return the front element of the queue without removing it. 20 | front() { 21 | if (this.isEmpty()) { 22 | return null; 23 | } 24 | return this.items[0]; 25 | } 26 | 27 | // Check if the queue is empty. 28 | isEmpty() { 29 | return this.items.length === 0; 30 | } 31 | 32 | // Return the number of elements in the queue. 33 | size() { 34 | return this.items.length; 35 | } 36 | } 37 | 38 | module.exports = Queue; 39 | -------------------------------------------------------------------------------- /data-structures/stacks-and-queues/Stack.js: -------------------------------------------------------------------------------- 1 | class Stack { 2 | constructor() { 3 | this.items = []; 4 | } 5 | 6 | // Add an element to the stack. 7 | push(element) { 8 | this.items.push(element); 9 | } 10 | 11 | // Remove and return the top element from the stack. 12 | pop() { 13 | if (this.isEmpty()) { 14 | return null; 15 | } 16 | return this.items.pop(); 17 | } 18 | 19 | // Return the top element of the stack without removing it. 20 | peek() { 21 | if (this.isEmpty()) { 22 | return null; 23 | } 24 | return this.items[this.items.length - 1]; 25 | } 26 | 27 | // Check if the stack is empty. 28 | isEmpty() { 29 | return this.items.length === 0; 30 | } 31 | 32 | // Return the number of elements in the stack. 33 | size() { 34 | return this.items.length; 35 | } 36 | } 37 | 38 | module.exports = Stack; 39 | -------------------------------------------------------------------------------- /test/algorithms/graph-algorithms/prim.test.js: -------------------------------------------------------------------------------- 1 | const Prim = require('../../../algorithms/graph-algorithms/prim'); 2 | 3 | describe('Prim (OOP)', () => { 4 | it('should handle an empty graph', () => { 5 | const graph = {}; 6 | 7 | const prim = new Prim(graph); 8 | const mst = prim.findMinimumSpanningTree(); 9 | 10 | expect(mst).toEqual([]); 11 | }); 12 | 13 | it('should handle a graph with a single vertex', () => { 14 | const graph = { A: {} }; 15 | 16 | const prim = new Prim(graph); 17 | const mst = prim.findMinimumSpanningTree(); 18 | 19 | expect(mst).toEqual([]); 20 | }); 21 | 22 | it('should handle a graph with no path between two nodes', () => { 23 | const graph = { 24 | A: {}, 25 | B: {}, 26 | }; 27 | 28 | const prim = new Prim(graph); 29 | const mst = prim.findMinimumSpanningTree(); 30 | 31 | expect(mst).toEqual([]); 32 | }); 33 | }); 34 | -------------------------------------------------------------------------------- /test/data-structures/trees/TreeNode.test.js: -------------------------------------------------------------------------------- 1 | const assert = require('assert'); 2 | const TreeNode = require('../../../data-structures/trees/TreeNode'); 3 | 4 | describe('TreeNode', () => { 5 | it('should create a TreeNode with the given value', () => { 6 | const node = new TreeNode(10); 7 | assert.strictEqual(node.value, 10); 8 | }); 9 | 10 | it('should have null left and right children by default', () => { 11 | const node = new TreeNode(20); 12 | assert.strictEqual(node.left, null); 13 | assert.strictEqual(node.right, null); 14 | }); 15 | 16 | it('should link to left and right children', () => { 17 | const node = new TreeNode(30); 18 | const leftChild = new TreeNode(15); 19 | const rightChild = new TreeNode(45); 20 | 21 | node.left = leftChild; 22 | node.right = rightChild; 23 | 24 | assert.strictEqual(node.left.value, 15); 25 | assert.strictEqual(node.right.value, 45); 26 | }); 27 | }); 28 | -------------------------------------------------------------------------------- /test/algorithms/dynamic-programming/matrixChainMultiplication.test.js: -------------------------------------------------------------------------------- 1 | const MatrixChainMultiplication = require('../../../algorithms/dynamic-programming/matrixChainMultiplication'); 2 | 3 | describe('MatrixChainMultiplication (OOP)', () => { 4 | it('should find the minimum number of multiplications for matrix chain', () => { 5 | const matrixChain = new MatrixChainMultiplication(); 6 | 7 | // Test case 1 8 | const dimensions1 = [10, 30, 5, 60]; 9 | const result1 = matrixChain.findMinMultiplications(dimensions1); 10 | expect(result1).toEqual(4500); 11 | 12 | // Test case 2 13 | const dimensions2 = [5, 10, 3, 12, 5, 50, 6]; 14 | const result2 = matrixChain.findMinMultiplications(dimensions2); 15 | expect(result2).toEqual(2010); 16 | 17 | // Test case 3 18 | const dimensions3 = [30, 35, 15, 5, 10, 20, 25]; 19 | const result3 = matrixChain.findMinMultiplications(dimensions3); 20 | expect(result3).toEqual(15125); 21 | }); 22 | }); 23 | -------------------------------------------------------------------------------- /test/algorithms/numerical/gcd.test.js: -------------------------------------------------------------------------------- 1 | const GCD = require('../../../algorithms/numerical/gcd'); 2 | 3 | describe('GCD', () => { 4 | it('should find the GCD of two numbers', () => { 5 | expect(GCD.findGCD(12, 18)).toBe(6); 6 | expect(GCD.findGCD(48, 18)).toBe(6); 7 | expect(GCD.findGCD(17, 5)).toBe(1); 8 | expect(GCD.findGCD(0, 7)).toBe(7); 9 | expect(GCD.findGCD(48, 0)).toBe(48); 10 | }); 11 | 12 | it('should find the LCM of two numbers', () => { 13 | expect(GCD.findLCM(12, 18)).toBe(36); 14 | expect(GCD.findLCM(7, 5)).toBe(35); 15 | expect(GCD.findLCM(10, 25)).toBe(50); 16 | }); 17 | 18 | it('should find the GCD of an array of numbers', () => { 19 | expect(GCD.findGCDOfArray([12, 18, 24, 6])).toBe(6); 20 | expect(GCD.findGCDOfArray([30, 42, 56, 14])).toBe(2); 21 | expect(GCD.findGCDOfArray([17, 5])).toBe(1); 22 | expect(() => GCD.findGCDOfArray([11])).toThrowError('At least two numbers are required'); 23 | }); 24 | }); 25 | -------------------------------------------------------------------------------- /test/algorithms/graph-algorithms/kruskal.test.js: -------------------------------------------------------------------------------- 1 | const Kruskal = require('../../../algorithms/graph-algorithms/kruskal'); 2 | 3 | describe('Kruskal (OOP)', () => { 4 | it('should handle a graph with negative edge weights', () => { 5 | const graph = { 6 | A: { B: 2, C: -1 }, 7 | B: { C: 1, D: 7 }, 8 | C: { D: -2, E: 5 }, 9 | D: { E: 2 }, 10 | E: {}, 11 | }; 12 | 13 | const kruskal = new Kruskal(graph); 14 | const mst = kruskal.findMinimumSpanningTree(); 15 | 16 | expect(mst).toEqual([ 17 | ['C', 'D', -2], 18 | ['A', 'C', -1], 19 | ['B', 'C', 1], 20 | ['D', 'E', 2], 21 | ]); 22 | }); 23 | 24 | it('should handle a graph with a single node', () => { 25 | const graph = { 26 | A: {}, 27 | }; 28 | 29 | const kruskal = new Kruskal(graph); 30 | const mst = kruskal.findMinimumSpanningTree(); 31 | 32 | expect(mst).toEqual([]); 33 | }); 34 | }); 35 | -------------------------------------------------------------------------------- /algorithms/dynamic-programming/editDistance.js: -------------------------------------------------------------------------------- 1 | class EditDistance { 2 | constructor() { } 3 | 4 | findEditDistance(str1, str2) { 5 | const m = str1.length; 6 | const n = str2.length; 7 | const dp = Array.from({ length: m + 1 }, () => Array(n + 1).fill(0)); 8 | 9 | for (let i = 0; i <= m; i++) { 10 | for (let j = 0; j <= n; j++) { 11 | if (i === 0) { 12 | dp[i][j] = j; 13 | } else if (j === 0) { 14 | dp[i][j] = i; 15 | } else if (str1[i - 1] === str2[j - 1]) { 16 | dp[i][j] = dp[i - 1][j - 1]; 17 | } else { 18 | dp[i][j] = 1 + Math.min( 19 | dp[i - 1][j], // Deletion 20 | dp[i][j - 1], // Insertion 21 | dp[i - 1][j - 1] // Replacement 22 | ); 23 | } 24 | } 25 | } 26 | 27 | return dp[m][n]; 28 | } 29 | } 30 | 31 | module.exports = EditDistance; 32 | -------------------------------------------------------------------------------- /algorithms/graph-algorithms/floydWarshall.js: -------------------------------------------------------------------------------- 1 | class FloydWarshall { 2 | constructor(graph) { 3 | this.graph = graph; 4 | } 5 | 6 | findShortestPaths() { 7 | const vertices = Object.keys(this.graph); 8 | const n = vertices.length; 9 | const dist = {}; 10 | 11 | // Initialize the distance matrix with the direct edge weights 12 | for (const u of vertices) { 13 | dist[u] = {}; 14 | for (const v of vertices) { 15 | dist[u][v] = u === v ? 0 : this.graph[u][v] || Infinity; 16 | } 17 | } 18 | 19 | // Floyd-Warshall algorithm 20 | for (const k of vertices) { 21 | for (const i of vertices) { 22 | for (const j of vertices) { 23 | if (dist[i][k] + dist[k][j] < dist[i][j]) { 24 | dist[i][j] = dist[i][k] + dist[k][j]; 25 | } 26 | } 27 | } 28 | } 29 | 30 | return dist; 31 | } 32 | } 33 | 34 | module.exports = FloydWarshall; 35 | -------------------------------------------------------------------------------- /algorithms/sorting/countingSort.js: -------------------------------------------------------------------------------- 1 | class CountingSort { 2 | constructor(arr) { 3 | this.arr = arr; 4 | } 5 | 6 | sort() { 7 | if (this.arr.length <= 1) return this.arr; 8 | 9 | const max = Math.max(...this.arr); 10 | const min = Math.min(...this.arr); 11 | 12 | const range = max - min + 1; 13 | const count = new Array(range).fill(0); 14 | const output = new Array(this.arr.length); 15 | 16 | for (let i = 0; i < this.arr.length; i++) { 17 | count[this.arr[i] - min]++; 18 | } 19 | 20 | for (let i = 1; i < count.length; i++) { 21 | count[i] += count[i - 1]; 22 | } 23 | 24 | for (let i = this.arr.length - 1; i >= 0; i--) { 25 | output[count[this.arr[i] - min] - 1] = this.arr[i]; 26 | count[this.arr[i] - min]--; 27 | } 28 | 29 | for (let i = 0; i < this.arr.length; i++) { 30 | this.arr[i] = output[i]; 31 | } 32 | 33 | return this.arr; 34 | } 35 | } 36 | 37 | module.exports = CountingSort; 38 | -------------------------------------------------------------------------------- /test/algorithms/sorting/heapSort.test.js: -------------------------------------------------------------------------------- 1 | const HeapSort = require("../../../algorithms/sorting/heapSort"); 2 | 3 | describe("HeapSort (OOP)", () => { 4 | it("should sort an array in ascending order", () => { 5 | const arr = [3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5]; 6 | const sortedArr = new HeapSort(arr).sort(); 7 | expect(sortedArr).toEqual([1, 1, 2, 3, 3, 4, 5, 5, 5, 6, 9]); 8 | }); 9 | 10 | it("should handle an empty array", () => { 11 | const arr = []; 12 | const sortedArr = new HeapSort(arr).sort(); 13 | expect(sortedArr).toEqual([]); 14 | }); 15 | 16 | it("should handle an array with one element", () => { 17 | const arr = [42]; 18 | const sortedArr = new HeapSort(arr).sort(); 19 | expect(sortedArr).toEqual([42]); 20 | }); 21 | 22 | it("should handle an array with duplicate elements", () => { 23 | const arr = [5, 2, 1, 4, 5, 3, 2, 4, 1, 3]; 24 | const sortedArr = new HeapSort(arr).sort(); 25 | expect(sortedArr).toEqual([1, 1, 2, 2, 3, 3, 4, 4, 5, 5]); 26 | }); 27 | }); 28 | -------------------------------------------------------------------------------- /test/algorithms/sorting/quickSort.test.js: -------------------------------------------------------------------------------- 1 | const QuickSort = require("../../../algorithms/sorting/quickSort"); 2 | 3 | describe("QuickSort (OOP)", () => { 4 | it("should sort an array in ascending order", () => { 5 | const arr = [3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5]; 6 | const sortedArr = new QuickSort(arr).sort(); 7 | expect(sortedArr).toEqual([1, 1, 2, 3, 3, 4, 5, 5, 5, 6, 9]); 8 | }); 9 | 10 | it("should handle an empty array", () => { 11 | const arr = []; 12 | const sortedArr = new QuickSort(arr).sort(); 13 | expect(sortedArr).toEqual([]); 14 | }); 15 | 16 | it("should handle an array with one element", () => { 17 | const arr = [42]; 18 | const sortedArr = new QuickSort(arr).sort(); 19 | expect(sortedArr).toEqual([42]); 20 | }); 21 | 22 | it("should handle an array with duplicate elements", () => { 23 | const arr = [5, 2, 1, 4, 5, 3, 2, 4, 1, 3]; 24 | const sortedArr = new QuickSort(arr).sort(); 25 | expect(sortedArr).toEqual([1, 1, 2, 2, 3, 3, 4, 4, 5, 5]); 26 | }); 27 | }); 28 | -------------------------------------------------------------------------------- /test/algorithms/sorting/radixSort.test.js: -------------------------------------------------------------------------------- 1 | const RadixSort = require("../../../algorithms/sorting/radixSort"); 2 | 3 | describe("RadixSort (OOP)", () => { 4 | it("should sort an array in ascending order", () => { 5 | const arr = [170, 45, 75, 90, 802, 24, 2, 66]; 6 | const sortedArr = new RadixSort(arr).sort(); 7 | expect(sortedArr).toEqual([2, 24, 45, 66, 75, 90, 170, 802]); 8 | }); 9 | 10 | it("should handle an empty array", () => { 11 | const arr = []; 12 | const sortedArr = new RadixSort(arr).sort(); 13 | expect(sortedArr).toEqual([]); 14 | }); 15 | 16 | it("should handle an array with one element", () => { 17 | const arr = [42]; 18 | const sortedArr = new RadixSort(arr).sort(); 19 | expect(sortedArr).toEqual([42]); 20 | }); 21 | 22 | it("should handle an array with duplicate elements", () => { 23 | const arr = [5, 2, 1, 4, 5, 3, 2, 4, 1, 3]; 24 | const sortedArr = new RadixSort(arr).sort(); 25 | expect(sortedArr).toEqual([1, 1, 2, 2, 3, 3, 4, 4, 5, 5]); 26 | }); 27 | }); 28 | -------------------------------------------------------------------------------- /test/data-structures/trie/Trie.test.js: -------------------------------------------------------------------------------- 1 | const assert = require('assert'); 2 | const Trie = require('../../../data-structures/trie/Trie'); 3 | 4 | describe('Trie', () => { 5 | it('should insert and search for words', () => { 6 | const trie = new Trie(); 7 | 8 | trie.insert('apple'); 9 | trie.insert('app'); 10 | trie.insert('banana'); 11 | 12 | assert.strictEqual(trie.search('apple'), true); 13 | assert.strictEqual(trie.search('app'), true); 14 | assert.strictEqual(trie.search('banana'), true); 15 | assert.strictEqual(trie.search('appl'), false); 16 | assert.strictEqual(trie.search('apples'), false); 17 | }); 18 | 19 | it('should check for word prefixes', () => { 20 | const trie = new Trie(); 21 | 22 | trie.insert('apple'); 23 | trie.insert('app'); 24 | trie.insert('banana'); 25 | 26 | assert.strictEqual(trie.startsWith('app'), true); 27 | assert.strictEqual(trie.startsWith('ban'), true); 28 | assert.strictEqual(trie.startsWith('apx'), false); 29 | }); 30 | }); 31 | -------------------------------------------------------------------------------- /algorithms/sorting/heapSort.js: -------------------------------------------------------------------------------- 1 | class HeapSort { 2 | constructor(arr) { 3 | this.arr = arr; 4 | } 5 | 6 | sort() { 7 | const n = this.arr.length; 8 | for (let i = Math.floor(n / 2) - 1; i >= 0; i--) { 9 | this.heapify(n, i); 10 | } 11 | 12 | for (let i = n - 1; i > 0; i--) { 13 | [this.arr[0], this.arr[i]] = [this.arr[i], this.arr[0]]; 14 | this.heapify(i, 0); 15 | } 16 | 17 | return this.arr; 18 | } 19 | 20 | heapify(n, i) { 21 | let largest = i; 22 | const left = 2 * i + 1; 23 | const right = 2 * i + 2; 24 | 25 | if (left < n && this.arr[left] > this.arr[largest]) { 26 | largest = left; 27 | } 28 | 29 | if (right < n && this.arr[right] > this.arr[largest]) { 30 | largest = right; 31 | } 32 | 33 | if (largest !== i) { 34 | [this.arr[i], this.arr[largest]] = [this.arr[largest], this.arr[i]]; 35 | this.heapify(n, largest); 36 | } 37 | } 38 | } 39 | 40 | module.exports = HeapSort; 41 | -------------------------------------------------------------------------------- /data-structures/sets-and-maps/Set.js: -------------------------------------------------------------------------------- 1 | class Set { 2 | constructor() { 3 | this.items = {}; 4 | } 5 | 6 | // Add an element to the set. 7 | add(element) { 8 | if (!this.has(element)) { 9 | this.items[element] = element; 10 | return true; 11 | } 12 | return false; 13 | } 14 | 15 | // Remove an element from the set. 16 | delete(element) { 17 | if (this.has(element)) { 18 | delete this.items[element]; 19 | return true; 20 | } 21 | return false; 22 | } 23 | 24 | // Check if an element is in the set. 25 | has(element) { 26 | return this.items.hasOwnProperty(element); 27 | } 28 | 29 | // Return an array of all elements in the set. 30 | values() { 31 | return Object.values(this.items); 32 | } 33 | 34 | // Return the size of the set. 35 | size() { 36 | return Object.keys(this.items).length; 37 | } 38 | 39 | // Clear the set. 40 | clear() { 41 | this.items = {}; 42 | } 43 | } 44 | 45 | module.exports = Set; 46 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Pabitra Banerjee 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /algorithms/randomized/randomizedQuickSort.js: -------------------------------------------------------------------------------- 1 | class RandomizedQuickSort { 2 | // Randomized partition function 3 | partition(arr, low, high) { 4 | const pivotIndex = Math.floor(Math.random() * (high - low + 1)) + low; 5 | const pivot = arr[pivotIndex]; 6 | [arr[pivotIndex], arr[high]] = [arr[high], arr[pivotIndex]]; 7 | let i = low; 8 | 9 | for (let j = low; j < high; j++) { 10 | if (arr[j] < pivot) { 11 | [arr[i], arr[j]] = [arr[j], arr[i]]; 12 | i++; 13 | } 14 | } 15 | 16 | [arr[i], arr[high]] = [arr[high], arr[i]]; 17 | return i; 18 | } 19 | 20 | // Randomized Quick Sort 21 | quickSort(arr, low, high) { 22 | if (low < high) { 23 | const pivotIndex = this.partition(arr, low, high); 24 | this.quickSort(arr, low, pivotIndex - 1); 25 | this.quickSort(arr, pivotIndex + 1, high); 26 | } 27 | } 28 | 29 | sort(arr) { 30 | this.quickSort(arr, 0, arr.length - 1); 31 | return arr; 32 | } 33 | } 34 | 35 | module.exports = RandomizedQuickSort; 36 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE/pull_request_template.md: -------------------------------------------------------------------------------- 1 | ## Update 2 | - [ ] Hot Fix 3 | - [ ] Release 4 | - [ ] Develop 5 | - [ ] Others 6 | 7 | ## Description 8 | * Feature #24 9 | [Write one-line description here] 10 | 11 | ## Update Summary 12 | - [Write feature(fix)-update here] 13 | 14 | ## New/Edited policies 15 | - [Write policy(styles)-update here] 16 | 17 | ## Resolved Issue 18 | - [Write resolved issue(recognized) here] 19 | 20 | ## Unresolved Issue 21 | - [Write unresolved issue(recognized) here] 22 | 23 | ## Test 24 | - [ ] Unit Test 25 | - [ ] Build Test 26 | 27 | ## Proof Check 28 | - [ ] My code follows the guidelines of this project style. 29 | - [ ] I have performed a self-review of my own code. 30 | - [ ] I have commented my code, particularly in hard-to-understand areas. 31 | - [ ] I have made corresponding changes to the documentations. 32 | - [ ] I have added tests that prove my feature, policy, fix or issue is resolve, effective and works. 33 | - [ ] Existing tests pass locally with these changes. 34 | - [ ] New tests pass locally with these changes. 35 | - [ ] Any dependent changes have been merged and published in downstream modules. -------------------------------------------------------------------------------- /test/utils/utilityFunctions.test.js: -------------------------------------------------------------------------------- 1 | const UtilityFunctions = require('../../utils/utilityFunctions'); 2 | 3 | describe('UtilityFunctions', () => { 4 | describe('sum', () => { 5 | it('should return the sum of an array of numbers', () => { 6 | const numbers = [1, 2, 3, 4, 5]; 7 | const result = UtilityFunctions.sum(numbers); 8 | expect(result).toBe(15); 9 | }); 10 | 11 | it('should handle an empty array', () => { 12 | const numbers = []; 13 | const result = UtilityFunctions.sum(numbers); 14 | expect(result).toBe(0); 15 | }); 16 | }); 17 | 18 | describe('average', () => { 19 | it('should return the average of an array of numbers', () => { 20 | const numbers = [2, 4, 6, 8, 10]; 21 | const result = UtilityFunctions.average(numbers); 22 | expect(result).toBe(6); 23 | }); 24 | 25 | it('should handle an empty array', () => { 26 | const numbers = []; 27 | const result = UtilityFunctions.average(numbers); 28 | expect(result).toBe(0); 29 | }); 30 | }); 31 | }); 32 | -------------------------------------------------------------------------------- /algorithms/ml-statistical/linearRegression.js: -------------------------------------------------------------------------------- 1 | class LinearRegression { 2 | constructor() { 3 | this.coefficients = { intercept: 0, slope: 0 }; 4 | } 5 | 6 | // Fit the model to the provided data 7 | fit(data) { 8 | if (data.length < 2) { 9 | throw new Error('Insufficient data for linear regression'); 10 | } 11 | 12 | const n = data.length; 13 | const sumX = data.reduce((acc, [x]) => acc + x, 0); 14 | const sumY = data.reduce((acc, [, y]) => acc + y, 0); 15 | const sumXX = data.reduce((acc, [x]) => acc + x * x, 0); 16 | const sumXY = data.reduce((acc, [x, y]) => acc + x * y, 0); 17 | 18 | const slope = 19 | (n * sumXY - sumX * sumY) / (n * sumXX - sumX * sumX); 20 | const intercept = 21 | (sumY - slope * sumX) / n; 22 | 23 | this.coefficients.slope = slope; 24 | this.coefficients.intercept = intercept; 25 | } 26 | 27 | // Predict the output for a given input 28 | predict(x) { 29 | return this.coefficients.intercept + this.coefficients.slope * x; 30 | } 31 | } 32 | 33 | module.exports = LinearRegression; 34 | -------------------------------------------------------------------------------- /algorithms/sorting/mergeSort.js: -------------------------------------------------------------------------------- 1 | class MergeSort { 2 | constructor(arr) { 3 | this.arr = arr; 4 | } 5 | 6 | sort() { 7 | if (this.arr.length <= 1) { 8 | return this.arr; 9 | } 10 | 11 | const merge = (left, right) => { 12 | let result = []; 13 | let leftIndex = 0; 14 | let rightIndex = 0; 15 | 16 | while (leftIndex < left.length && rightIndex < right.length) { 17 | if (left[leftIndex] < right[rightIndex]) { 18 | result.push(left[leftIndex]); 19 | leftIndex++; 20 | } else { 21 | result.push(right[rightIndex]); 22 | rightIndex++; 23 | } 24 | } 25 | 26 | return result.concat(left.slice(leftIndex), right.slice(rightIndex)); 27 | }; 28 | 29 | const middle = Math.floor(this.arr.length / 2); 30 | const left = this.arr.slice(0, middle); 31 | const right = this.arr.slice(middle); 32 | 33 | return merge(new MergeSort(left).sort(), new MergeSort(right).sort()); 34 | } 35 | } 36 | 37 | module.exports = MergeSort; 38 | -------------------------------------------------------------------------------- /test/data-structures/linked-lists/SinglyLinkedList.test.js: -------------------------------------------------------------------------------- 1 | const assert = require('assert'); 2 | const SinglyLinkedList = require('../../../data-structures/linked-lists/SinglyLinkedList'); 3 | 4 | describe('Singly Linked List', () => { 5 | it('should create an empty list', () => { 6 | const list = new SinglyLinkedList(); 7 | assert.strictEqual(list.head, null); 8 | }); 9 | 10 | it('should append elements to the list', () => { 11 | const list = new SinglyLinkedList(); 12 | list.append(1); 13 | list.append(2); 14 | list.append(3); 15 | 16 | const elements = list.display(); 17 | assert.deepStrictEqual(elements, [1, 2, 3]); 18 | }); 19 | 20 | it('should display an empty list as an empty array', () => { 21 | const list = new SinglyLinkedList(); 22 | const elements = list.display(); 23 | assert.deepStrictEqual(elements, []); 24 | }); 25 | 26 | it('should display a list with a single element', () => { 27 | const list = new SinglyLinkedList(); 28 | list.append(42); 29 | const elements = list.display(); 30 | assert.deepStrictEqual(elements, [42]); 31 | }); 32 | }); 33 | -------------------------------------------------------------------------------- /data-structures/sets-and-maps/Map.js: -------------------------------------------------------------------------------- 1 | class Map { 2 | constructor() { 3 | this.items = {}; 4 | } 5 | 6 | // Add a key-value pair to the map. 7 | set(key, value) { 8 | this.items[key] = value; 9 | } 10 | 11 | // Get the value associated with a key. 12 | get(key) { 13 | return this.has(key) ? this.items[key] : undefined; 14 | } 15 | 16 | // Check if a key exists in the map. 17 | has(key) { 18 | return key in this.items; 19 | } 20 | 21 | // Remove a key-value pair from the map. 22 | delete(key) { 23 | if (this.has(key)) { 24 | delete this.items[key]; 25 | } 26 | } 27 | 28 | // Return an array of all keys in the map. 29 | keys() { 30 | return Object.keys(this.items); 31 | } 32 | 33 | // Return an array of all values in the map. 34 | values() { 35 | return Object.values(this.items); 36 | } 37 | 38 | // Return the number of key-value pairs in the map. 39 | size() { 40 | return Object.keys(this.items).length; 41 | } 42 | 43 | // Clear the map. 44 | clear() { 45 | this.items = {}; 46 | } 47 | } 48 | 49 | module.exports = Map; 50 | -------------------------------------------------------------------------------- /algorithms/graph-algorithms/prim.js: -------------------------------------------------------------------------------- 1 | class Prim { 2 | constructor(graph) { 3 | this.graph = graph; 4 | } 5 | 6 | findMinimumSpanningTree() { 7 | const vertices = Object.keys(this.graph); 8 | if (vertices.length === 0) { 9 | return []; 10 | } 11 | 12 | const mst = []; 13 | const visited = new Set(); 14 | visited.add(vertices[0]); 15 | 16 | while (visited.size < vertices.length) { 17 | let minEdge = null; 18 | 19 | for (const vertex of visited) { 20 | for (const neighbor in this.graph[vertex]) { 21 | if (!visited.has(neighbor) && (!minEdge || this.graph[vertex][neighbor] < this.graph[minEdge[0]][minEdge[1]])) { 22 | minEdge = [vertex, neighbor]; 23 | } 24 | } 25 | } 26 | 27 | if (minEdge) { 28 | mst.push([minEdge[0], minEdge[1], this.graph[minEdge[0]][minEdge[1]]]); 29 | visited.add(minEdge[1]); 30 | } else { 31 | break; 32 | } 33 | } 34 | 35 | return mst; 36 | } 37 | } 38 | 39 | module.exports = Prim; 40 | -------------------------------------------------------------------------------- /algorithms/graph-algorithms/kruskal.js: -------------------------------------------------------------------------------- 1 | class Kruskal { 2 | constructor(graph) { 3 | this.graph = graph; 4 | } 5 | 6 | findMinimumSpanningTree() { 7 | const edges = this.getSortedEdges(); 8 | const mst = new Set(); 9 | const parent = {}; 10 | 11 | const find = (node) => { 12 | if (parent[node] === undefined) return node; 13 | return find(parent[node]); 14 | }; 15 | 16 | for (const edge of edges) { 17 | const [u, v, weight] = edge; 18 | const parentU = find(u); 19 | const parentV = find(v); 20 | 21 | if (parentU !== parentV) { 22 | mst.add(edge); 23 | parent[parentU] = parentV; 24 | } 25 | } 26 | 27 | return Array.from(mst); 28 | } 29 | 30 | getSortedEdges() { 31 | const edges = []; 32 | for (const node in this.graph) { 33 | for (const neighbor in this.graph[node]) { 34 | edges.push([node, neighbor, this.graph[node][neighbor]]); 35 | } 36 | } 37 | 38 | return edges.sort((a, b) => a[2] - b[2]); 39 | } 40 | } 41 | 42 | module.exports = Kruskal; 43 | -------------------------------------------------------------------------------- /test/data-structures/linked-lists/CircularLinkedList.test.js: -------------------------------------------------------------------------------- 1 | const assert = require('assert'); 2 | const CircularLinkedList = require('../../../data-structures/linked-lists/CircularLinkedList'); 3 | 4 | describe('Circular Linked List', () => { 5 | it('should create an empty list', () => { 6 | const list = new CircularLinkedList(); 7 | assert.strictEqual(list.head, null); 8 | }); 9 | 10 | it('should append elements to the list', () => { 11 | const list = new CircularLinkedList(); 12 | list.append(1); 13 | list.append(2); 14 | list.append(3); 15 | 16 | const elements = list.display(); 17 | assert.deepStrictEqual(elements, [1, 2, 3]); 18 | }); 19 | 20 | it('should display an empty list as an empty array', () => { 21 | const list = new CircularLinkedList(); 22 | const elements = list.display(); 23 | assert.deepStrictEqual(elements, []); 24 | }); 25 | 26 | it('should display a list with a single element', () => { 27 | const list = new CircularLinkedList(); 28 | list.append(42); 29 | const elements = list.display(); 30 | assert.deepStrictEqual(elements, [42]); 31 | }); 32 | }); 33 | -------------------------------------------------------------------------------- /data-structures/linked-lists/SinglyLinkedList.js: -------------------------------------------------------------------------------- 1 | // Define the Node class for a singly linked list. 2 | class Node { 3 | constructor(data) { 4 | this.data = data; 5 | this.next = null; 6 | } 7 | } 8 | 9 | // Define the SinglyLinkedList class to manage the linked list. 10 | class SinglyLinkedList { 11 | constructor() { 12 | this.head = null; 13 | } 14 | 15 | // Add a new node to the end of the linked list. 16 | append(data) { 17 | const newNode = new Node(data); 18 | if (!this.head) { 19 | this.head = newNode; 20 | } else { 21 | let current = this.head; 22 | while (current.next) { 23 | current = current.next; 24 | } 25 | current.next = newNode; 26 | } 27 | } 28 | 29 | // Display the linked list. 30 | display() { 31 | let current = this.head; 32 | const result = []; 33 | while (current) { 34 | result.push(current.data); 35 | current = current.next; 36 | } 37 | return result; 38 | } 39 | } 40 | 41 | // Export the SinglyLinkedList class for use in other files. 42 | module.exports = SinglyLinkedList; 43 | -------------------------------------------------------------------------------- /test/algorithms/sorting/bubbleSort.test.js: -------------------------------------------------------------------------------- 1 | const assert = require('assert'); 2 | const BubbleSort = require('../../../algorithms/sorting/bubbleSort'); 3 | 4 | describe('BubbleSort (OOP)', () => { 5 | it('should sort an array in ascending order', () => { 6 | const arr = [64, 25, 12, 22, 11]; 7 | const bubbleSort = new BubbleSort(arr); 8 | bubbleSort.sort(); 9 | assert.deepStrictEqual(bubbleSort.arr, [11, 12, 22, 25, 64]); 10 | }); 11 | 12 | it('should handle an already sorted array', () => { 13 | const arr = [10, 20, 30, 40, 50]; 14 | const bubbleSort = new BubbleSort(arr); 15 | bubbleSort.sort(); 16 | assert.deepStrictEqual(bubbleSort.arr, [10, 20, 30, 40, 50]); 17 | }); 18 | 19 | it('should handle an empty array', () => { 20 | const arr = []; 21 | const bubbleSort = new BubbleSort(arr); 22 | bubbleSort.sort(); 23 | assert.deepStrictEqual(bubbleSort.arr, []); 24 | }); 25 | 26 | it('should handle an array with one element', () => { 27 | const arr = [42]; 28 | const bubbleSort = new BubbleSort(arr); 29 | bubbleSort.sort(); 30 | assert.deepStrictEqual(bubbleSort.arr, [42]); 31 | }); 32 | }); -------------------------------------------------------------------------------- /algorithms/string/longestCommonSubstring.js: -------------------------------------------------------------------------------- 1 | class LongestCommonSubstring { 2 | static findLongestCommonSubstring(str1, str2) { 3 | const m = str1.length; 4 | const n = str2.length; 5 | let maxLength = 0; // Length of the longest common substring 6 | let endingIndex = 0; // Ending index of the longest common substring 7 | 8 | const dp = new Array(m + 1).fill(0).map(() => new Array(n + 1).fill(0)); 9 | 10 | for (let i = 1; i <= m; i++) { 11 | for (let j = 1; j <= n; j++) { 12 | if (str1[i - 1] === str2[j - 1]) { 13 | dp[i][j] = dp[i - 1][j - 1] + 1; 14 | if (dp[i][j] > maxLength) { 15 | maxLength = dp[i][j]; 16 | endingIndex = i - 1; 17 | } 18 | } else { 19 | dp[i][j] = 0; 20 | } 21 | } 22 | } 23 | 24 | if (maxLength === 0) { 25 | return ''; 26 | } 27 | 28 | // Retrieve the longest common substring from str1 29 | return str1.substring(endingIndex - maxLength + 1, endingIndex + 1); 30 | } 31 | } 32 | 33 | module.exports = LongestCommonSubstring; 34 | -------------------------------------------------------------------------------- /test/algorithms/dynamic-programming/editDistance.test.js: -------------------------------------------------------------------------------- 1 | const EditDistance = require('../../../algorithms/dynamic-programming/editDistance'); 2 | 3 | describe('EditDistance (OOP)', () => { 4 | const editDistance = new EditDistance(); 5 | 6 | it('should find the edit distance between two strings', () => { 7 | // Test case 1 8 | const str1 = 'kitten'; 9 | const str2 = 'sitting'; 10 | expect(editDistance.findEditDistance(str1, str2)).toBe(3); 11 | 12 | // Test case 2 13 | const str3 = 'flaw'; 14 | const str4 = 'lawn'; 15 | expect(editDistance.findEditDistance(str3, str4)).toBe(2); 16 | 17 | // Test case 3 (Edge case: Empty strings) 18 | const str5 = ''; 19 | const str6 = ''; 20 | expect(editDistance.findEditDistance(str5, str6)).toBe(0); 21 | 22 | // Test case 4 (Edge case: One string is empty) 23 | const str7 = 'abc'; 24 | const str8 = ''; 25 | expect(editDistance.findEditDistance(str7, str8)).toBe(3); 26 | 27 | // Test case 5 (Edge case: Both strings are empty) 28 | const str9 = ''; 29 | const str10 = ''; 30 | expect(editDistance.findEditDistance(str9, str10)).toBe(0); 31 | }); 32 | }); 33 | -------------------------------------------------------------------------------- /test/data-structures/heaps/MaxHeap.test.js: -------------------------------------------------------------------------------- 1 | const assert = require('assert'); 2 | const MaxHeap = require('../../../data-structures/heaps/MaxHeap'); 3 | 4 | describe('MaxHeap', () => { 5 | it('should create an empty MaxHeap', () => { 6 | const maxHeap = new MaxHeap(); 7 | assert.strictEqual(maxHeap.size(), 0); 8 | assert.strictEqual(maxHeap.isEmpty(), true); 9 | }); 10 | 11 | it('should insert and extract maximum values correctly', () => { 12 | const maxHeap = new MaxHeap(); 13 | maxHeap.insert(5); 14 | maxHeap.insert(3); 15 | maxHeap.insert(10); 16 | maxHeap.insert(1); 17 | 18 | assert.strictEqual(maxHeap.size(), 4); 19 | assert.strictEqual(maxHeap.extractMax(), 10); 20 | assert.strictEqual(maxHeap.size(), 3); 21 | 22 | maxHeap.insert(12); 23 | assert.strictEqual(maxHeap.extractMax(), 12); 24 | assert.strictEqual(maxHeap.size(), 3); 25 | 26 | assert.strictEqual(maxHeap.extractMax(), 5); 27 | assert.strictEqual(maxHeap.extractMax(), 3); 28 | assert.strictEqual(maxHeap.extractMax(), 1); 29 | assert.strictEqual(maxHeap.size(), 0); 30 | assert.strictEqual(maxHeap.isEmpty(), true); 31 | }); 32 | }); 33 | -------------------------------------------------------------------------------- /test/data-structures/heaps/MinHeap.test.js: -------------------------------------------------------------------------------- 1 | const assert = require('assert'); 2 | const MinHeap = require('../../../data-structures/heaps/MinHeap'); 3 | 4 | describe('MinHeap', () => { 5 | it('should create an empty MinHeap', () => { 6 | const minHeap = new MinHeap(); 7 | assert.strictEqual(minHeap.size(), 0); 8 | assert.strictEqual(minHeap.isEmpty(), true); 9 | }); 10 | 11 | it('should insert and extract minimum values correctly', () => { 12 | const minHeap = new MinHeap(); 13 | minHeap.insert(5); 14 | minHeap.insert(3); 15 | minHeap.insert(10); 16 | minHeap.insert(1); 17 | 18 | assert.strictEqual(minHeap.size(), 4); 19 | assert.strictEqual(minHeap.extractMin(), 1); 20 | assert.strictEqual(minHeap.size(), 3); 21 | 22 | minHeap.insert(0); 23 | assert.strictEqual(minHeap.extractMin(), 0); 24 | assert.strictEqual(minHeap.size(), 3); 25 | 26 | assert.strictEqual(minHeap.extractMin(), 3); 27 | assert.strictEqual(minHeap.extractMin(), 5); 28 | assert.strictEqual(minHeap.extractMin(), 10); 29 | assert.strictEqual(minHeap.size(), 0); 30 | assert.strictEqual(minHeap.isEmpty(), true); 31 | }); 32 | }); 33 | -------------------------------------------------------------------------------- /algorithms/searching/breadthFirstSearch.js: -------------------------------------------------------------------------------- 1 | class GraphNode { 2 | constructor(value) { 3 | this.value = value; 4 | this.children = []; 5 | } 6 | 7 | addChild(node) { 8 | this.children.push(node); 9 | } 10 | } 11 | 12 | class BreadthFirstSearch { 13 | constructor(node) { 14 | this.node = node; 15 | this.visited = new Set(); 16 | this.result = []; 17 | } 18 | 19 | search() { 20 | if (this.node === null) { 21 | return this.result; // Return an empty result for an empty graph. 22 | } 23 | 24 | const queue = [this.node]; 25 | this.visited.add(this.node); 26 | 27 | while (queue.length > 0) { 28 | const currentNode = queue.shift(); 29 | 30 | if (currentNode) { 31 | this.result.push(currentNode.value); 32 | 33 | for (const child of currentNode.children) { 34 | if (!this.visited.has(child)) { 35 | this.visited.add(child); 36 | queue.push(child); 37 | } 38 | } 39 | } 40 | } 41 | 42 | return this.result; 43 | } 44 | } 45 | 46 | module.exports = { GraphNode, BreadthFirstSearch }; -------------------------------------------------------------------------------- /test/algorithms/geometry/closestPairOfPoints.test.js: -------------------------------------------------------------------------------- 1 | const ClosestPairOfPoints = require('../../../algorithms/geometry/closestPairOfPoints'); 2 | 3 | describe('ClosestPairOfPoints', () => { 4 | it('should find the closest pair of points', () => { 5 | const points = [ 6 | { x: 0, y: 0 }, 7 | { x: 2, y: 2 }, 8 | { x: 5, y: 3 }, 9 | { x: 6, y: 7 }, 10 | { x: 7, y: 8 }, 11 | { x: 9, y: 1 }, 12 | ]; 13 | 14 | const closestPair = ClosestPairOfPoints.findClosestPair(points); 15 | 16 | expect(closestPair).toEqual([{ x: 6, y: 7 }, { x: 7, y: 8 }]); 17 | }); 18 | 19 | it('should handle a set of points with only two points', () => { 20 | const points = [ 21 | { x: 0, y: 0 }, 22 | { x: 1, y: 1 }, 23 | ]; 24 | 25 | const closestPair = ClosestPairOfPoints.findClosestPair(points); 26 | 27 | expect(closestPair).toEqual(points); 28 | }); 29 | 30 | it('should handle a set of points with less than two points', () => { 31 | const points = [{ x: 0, y: 0 }]; 32 | 33 | const closestPair = ClosestPairOfPoints.findClosestPair(points); 34 | 35 | expect(closestPair).toEqual([]); 36 | }); 37 | }); 38 | -------------------------------------------------------------------------------- /test/algorithms/sorting/mergeSort.test.js: -------------------------------------------------------------------------------- 1 | const assert = require('assert'); 2 | const MergeSort = require('../../../algorithms/sorting/mergeSort'); 3 | 4 | describe('MergeSort (OOP)', () => { 5 | it('should sort an array in ascending order', () => { 6 | const arr = [64, 25, 12, 22, 11]; 7 | const mergeSort = new MergeSort(arr); 8 | const sortedArr = mergeSort.sort(); 9 | assert.deepStrictEqual(sortedArr, [11, 12, 22, 25, 64]); 10 | }); 11 | 12 | it('should handle an already sorted array', () => { 13 | const arr = [10, 20, 30, 40, 50]; 14 | const mergeSort = new MergeSort(arr); 15 | const sortedArr = mergeSort.sort(); 16 | assert.deepStrictEqual(sortedArr, [10, 20, 30, 40, 50]); 17 | }); 18 | 19 | it('should handle an empty array', () => { 20 | const arr = []; 21 | const mergeSort = new MergeSort(arr); 22 | const sortedArr = mergeSort.sort(); 23 | assert.deepStrictEqual(sortedArr, []); 24 | }); 25 | 26 | it('should handle an array with one element', () => { 27 | const arr = [42]; 28 | const mergeSort = new MergeSort(arr); 29 | const sortedArr = mergeSort.sort(); 30 | assert.deepStrictEqual(sortedArr, [42]); 31 | }); 32 | }); 33 | -------------------------------------------------------------------------------- /data-structures/trie/Trie.js: -------------------------------------------------------------------------------- 1 | class TrieNode { 2 | constructor() { 3 | this.children = new Map(); 4 | this.isEndOfWord = false; 5 | } 6 | } 7 | 8 | class Trie { 9 | constructor() { 10 | this.root = new TrieNode(); 11 | } 12 | 13 | insert(word) { 14 | let node = this.root; 15 | 16 | for (const char of word) { 17 | if (!node.children.has(char)) { 18 | node.children.set(char, new TrieNode()); 19 | } 20 | node = node.children.get(char); 21 | } 22 | 23 | node.isEndOfWord = true; 24 | } 25 | 26 | search(word) { 27 | let node = this.root; 28 | 29 | for (const char of word) { 30 | if (!node.children.has(char)) { 31 | return false; 32 | } 33 | node = node.children.get(char); 34 | } 35 | 36 | return node.isEndOfWord; 37 | } 38 | 39 | startsWith(prefix) { 40 | let node = this.root; 41 | 42 | for (const char of prefix) { 43 | if (!node.children.has(char)) { 44 | return false; 45 | } 46 | node = node.children.get(char); 47 | } 48 | 49 | return true; 50 | } 51 | } 52 | 53 | module.exports = Trie; 54 | -------------------------------------------------------------------------------- /test/algorithms/sorting/insertionSort.test.js: -------------------------------------------------------------------------------- 1 | const assert = require('assert'); 2 | const InsertionSort = require('../../../algorithms/sorting/insertionSort'); 3 | 4 | describe('InsertionSort (OOP)', () => { 5 | it('should sort an array in ascending order', () => { 6 | const arr = [64, 25, 12, 22, 11]; 7 | const insertionSort = new InsertionSort(arr); 8 | insertionSort.sort(); 9 | assert.deepStrictEqual(insertionSort.arr, [11, 12, 22, 25, 64]); 10 | }); 11 | 12 | it('should handle an already sorted array', () => { 13 | const arr = [10, 20, 30, 40, 50]; 14 | const insertionSort = new InsertionSort(arr); 15 | insertionSort.sort(); 16 | assert.deepStrictEqual(insertionSort.arr, [10, 20, 30, 40, 50]); 17 | }); 18 | 19 | it('should handle an empty array', () => { 20 | const arr = []; 21 | const insertionSort = new InsertionSort(arr); 22 | insertionSort.sort(); 23 | assert.deepStrictEqual(insertionSort.arr, []); 24 | }); 25 | 26 | it('should handle an array with one element', () => { 27 | const arr = [42]; 28 | const insertionSort = new InsertionSort(arr); 29 | insertionSort.sort(); 30 | assert.deepStrictEqual(insertionSort.arr, [42]); 31 | }); 32 | }); 33 | -------------------------------------------------------------------------------- /test/algorithms/sorting/selectionSort.test.js: -------------------------------------------------------------------------------- 1 | const assert = require('assert'); 2 | const SelectionSort = require('../../../algorithms/sorting/selectionSort'); 3 | 4 | describe('SelectionSort (OOP)', () => { 5 | it('should sort an array in ascending order', () => { 6 | const arr = [64, 25, 12, 22, 11]; 7 | const selectionSort = new SelectionSort(arr); 8 | selectionSort.sort(); 9 | assert.deepStrictEqual(selectionSort.arr, [11, 12, 22, 25, 64]); 10 | }); 11 | 12 | it('should handle an already sorted array', () => { 13 | const arr = [10, 20, 30, 40, 50]; 14 | const selectionSort = new SelectionSort(arr); 15 | selectionSort.sort(); 16 | assert.deepStrictEqual(selectionSort.arr, [10, 20, 30, 40, 50]); 17 | }); 18 | 19 | it('should handle an empty array', () => { 20 | const arr = []; 21 | const selectionSort = new SelectionSort(arr); 22 | selectionSort.sort(); 23 | assert.deepStrictEqual(selectionSort.arr, []); 24 | }); 25 | 26 | it('should handle an array with one element', () => { 27 | const arr = [42]; 28 | const selectionSort = new SelectionSort(arr); 29 | selectionSort.sort(); 30 | assert.deepStrictEqual(selectionSort.arr, [42]); 31 | }); 32 | }); 33 | -------------------------------------------------------------------------------- /test/algorithms/ml-statistical/linearRegression.test.js: -------------------------------------------------------------------------------- 1 | const LinearRegression = require('../../../algorithms/ml-statistical/linearRegression'); 2 | 3 | describe('LinearRegression', () => { 4 | it('should fit the model with data', () => { 5 | const data = [ 6 | [1, 2], 7 | [2, 3], 8 | [3, 4], 9 | [4, 5], 10 | [5, 6], 11 | ]; 12 | 13 | const lr = new LinearRegression(); 14 | lr.fit(data); 15 | 16 | expect(lr.coefficients.intercept).toBeCloseTo(1.0, 6); 17 | expect(lr.coefficients.slope).toBeCloseTo(1.0, 6); 18 | }); 19 | 20 | it('should predict values', () => { 21 | const data = [ 22 | [1, 2], 23 | [2, 3], 24 | [3, 4], 25 | [4, 5], 26 | [5, 6], 27 | ]; 28 | 29 | const lr = new LinearRegression(); 30 | lr.fit(data); 31 | 32 | expect(lr.predict(6)).toBeCloseTo(7.0, 6); 33 | expect(lr.predict(7)).toBeCloseTo(8.0, 6); 34 | }); 35 | 36 | it('should throw an error with insufficient data', () => { 37 | const data = [[1, 2]]; 38 | 39 | const lr = new LinearRegression(); 40 | 41 | expect(() => lr.fit(data)).toThrow('Insufficient data for linear regression'); 42 | }); 43 | }); 44 | -------------------------------------------------------------------------------- /test/algorithms/sorting/countingSort.test.js: -------------------------------------------------------------------------------- 1 | const CountingSort = require("../../../algorithms/sorting/countingSort"); 2 | 3 | describe("CountingSort (OOP)", () => { 4 | it("should sort an array in ascending order", () => { 5 | const arr = [4, 2, 2, 8, 3, 3, 1]; 6 | const sortedArr = new CountingSort(arr).sort(); 7 | expect(sortedArr).toEqual([1, 2, 2, 3, 3, 4, 8]); 8 | }); 9 | 10 | it("should handle an empty array", () => { 11 | const arr = []; 12 | const sortedArr = new CountingSort(arr).sort(); 13 | expect(sortedArr).toEqual([]); 14 | }); 15 | 16 | it("should handle an array with one element", () => { 17 | const arr = [42]; 18 | const sortedArr = new CountingSort(arr).sort(); 19 | expect(sortedArr).toEqual([42]); 20 | }); 21 | 22 | it("should handle an array with duplicate elements", () => { 23 | const arr = [5, 2, 1, 4, 5, 3, 2, 4, 1, 3]; 24 | const sortedArr = new CountingSort(arr).sort(); 25 | expect(sortedArr).toEqual([1, 1, 2, 2, 3, 3, 4, 4, 5, 5]); 26 | }); 27 | 28 | it("should handle a reverse-sorted array", () => { 29 | const arr = [5, 4, 3, 2, 1]; 30 | const sortedArr = new CountingSort(arr).sort(); 31 | expect(sortedArr).toEqual([1, 2, 3, 4, 5]); 32 | }); 33 | }); 34 | -------------------------------------------------------------------------------- /test/algorithms/geometry/lineIntersection.test.js: -------------------------------------------------------------------------------- 1 | const LineIntersection = require('../../../algorithms/geometry/lineIntersection'); 2 | 3 | describe('LineIntersection', () => { 4 | it('should find intersection points of lines', () => { 5 | const lines = [ 6 | { x1: 0, y1: 0, x2: 2, y2: 2 }, 7 | { x1: 1, y1: 0, x2: 1, y2: 3 }, 8 | { x1: 2, y1: 0, x2: 2, y2: 2 }, 9 | { x1: 3, y1: 0, x2: 3, y2: 3 }, 10 | ]; 11 | 12 | const intersections = LineIntersection.findIntersections(lines); 13 | 14 | expect(intersections).toEqual([{ x: 1, y: 1 }, { x: 2, y: 2 }]); 15 | }); 16 | 17 | it('should handle parallel lines', () => { 18 | const lines = [ 19 | { x1: 0, y1: 0, x2: 2, y2: 2 }, 20 | { x1: 0, y1: 1, x2: 2, y2: 3 }, 21 | ]; 22 | 23 | const intersections = LineIntersection.findIntersections(lines); 24 | 25 | expect(intersections).toEqual([]); 26 | }); 27 | 28 | it('should handle lines that do not intersect', () => { 29 | const lines = [ 30 | { x1: 0, y1: 0, x2: 1, y2: 1 }, 31 | { x1: 2, y1: 2, x2: 3, y2: 3 }, 32 | ]; 33 | 34 | const intersections = LineIntersection.findIntersections(lines); 35 | 36 | expect(intersections).toEqual([]); 37 | }); 38 | }); 39 | -------------------------------------------------------------------------------- /test/algorithms/dynamic-programming/longestCommonSubsequence.test.js: -------------------------------------------------------------------------------- 1 | // Import the LongestCommonSubsequence class 2 | const LongestCommonSubsequence = require('../../../algorithms/dynamic-programming/longestCommonSubsequence'); 3 | 4 | describe('LongestCommonSubsequence (OOP)', () => { 5 | it('should find the longest common subsequence between two strings', () => { 6 | const lcs = new LongestCommonSubsequence(); 7 | 8 | // Test cases 9 | expect(lcs.findLCS('AGGTAB', 'GXTXAYB')).toBe('GTAB'); 10 | expect(lcs.findLCS('ABC', 'AC')).toBe('AC'); 11 | expect(lcs.findLCS('XMJYAUZ', 'MZJAWXU')).toBe('MJAU'); 12 | 13 | // Edge cases 14 | expect(lcs.findLCS('', 'ABC')).toBe(''); 15 | expect(lcs.findLCS('ABC', '')).toBe(''); 16 | expect(lcs.findLCS('', '')).toBe(''); 17 | 18 | // Test a large example 19 | const str1 = 'AGGTAB'.repeat(100); 20 | const str2 = 'GXTXAYB'.repeat(100); 21 | const expected = 'GTAB'.repeat(100); 22 | expect(lcs.findLCS(str1, str2)).toBe(expected); 23 | 24 | // Additional test cases 25 | expect(lcs.findLCS('ABCD', 'DCBA')).toBe('D'); 26 | expect(lcs.findLCS('ABCDEF', 'XYZ')).toBe(''); 27 | expect(lcs.findLCS('ABC', 'XYZ')).toBe(''); 28 | expect(lcs.findLCS('ABCD', 'EFGH')).toBe(''); 29 | }); 30 | }); -------------------------------------------------------------------------------- /algorithms/dynamic-programming/longestCommonSubsequence.js: -------------------------------------------------------------------------------- 1 | class LongestCommonSubsequence { 2 | findLCS(str1, str2) { 3 | const m = str1.length; 4 | const n = str2.length; 5 | 6 | // Create a 2D array to store the length of LCS for substrings 7 | const dp = new Array(m + 1).fill(0).map(() => new Array(n + 1).fill(0)); 8 | 9 | // Build the dp array using a bottom-up approach 10 | for (let i = 1; i <= m; i++) { 11 | for (let j = 1; j <= n; j++) { 12 | if (str1[i - 1] === str2[j - 1]) { 13 | dp[i][j] = dp[i - 1][j - 1] + 1; 14 | } else { 15 | dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]); 16 | } 17 | } 18 | } 19 | 20 | // Reconstruct the LCS from the dp array 21 | let i = m; 22 | let j = n; 23 | const lcs = []; 24 | while (i > 0 && j > 0) { 25 | if (str1[i - 1] === str2[j - 1]) { 26 | lcs.unshift(str1[i - 1]); 27 | i--; 28 | j--; 29 | } else if (dp[i - 1][j] > dp[i][j - 1]) { 30 | i--; 31 | } else { 32 | j--; 33 | } 34 | } 35 | 36 | return lcs.join(''); 37 | } 38 | } 39 | 40 | module.exports = LongestCommonSubsequence; 41 | -------------------------------------------------------------------------------- /algorithms/randomized/randomizedPrimalityTesting.js: -------------------------------------------------------------------------------- 1 | class RandomizedPrimalityTesting { 2 | isPrime(n, k) { 3 | if (n <= 1n) { 4 | return false; 5 | } 6 | if (n <= 3n) { 7 | return true; 8 | } 9 | 10 | // Witness loop 11 | for (let i = 0; i < k; i++) { 12 | const a = 2n + BigInt(Math.floor(Math.random() * (Number(n) - 4))); 13 | if (this.witness(a, n)) { 14 | return false; 15 | } 16 | } 17 | 18 | return true; 19 | } 20 | 21 | // Helper function to check if 'a' is a witness for 'n' being composite 22 | witness(a, n) { 23 | let t = n - 1n; 24 | let u = 0n; 25 | 26 | while (t % 2n === 0n) { 27 | t /= 2n; 28 | u++; 29 | } 30 | 31 | let x0 = a ** t % n; 32 | for (let i = 0n; i < u; i++) { 33 | const x1 = (x0 * x0) % n; 34 | if (x1 === 1n && x0 !== 1n && x0 !== n - 1n) { 35 | return true; // 'a' is a witness to compositeness 36 | } 37 | x0 = x1; 38 | } 39 | 40 | if (x0 !== 1n) { 41 | return true; // 'a' is not a witness 42 | } 43 | 44 | return false; // 'a' is not a witness 45 | } 46 | } 47 | 48 | module.exports = RandomizedPrimalityTesting; 49 | -------------------------------------------------------------------------------- /algorithms/sorting/radixSort.js: -------------------------------------------------------------------------------- 1 | class RadixSort { 2 | constructor(arr) { 3 | this.arr = arr; 4 | } 5 | 6 | getMax() { 7 | let max = this.arr[0]; 8 | for (let i = 1; i < this.arr.length; i++) { 9 | if (this.arr[i] > max) { 10 | max = this.arr[i]; 11 | } 12 | } 13 | return max; 14 | } 15 | 16 | countSort(exp) { 17 | const n = this.arr.length; 18 | const output = new Array(n).fill(0); 19 | const count = new Array(10).fill(0); 20 | 21 | for (let i = 0; i < n; i++) { 22 | count[Math.floor(this.arr[i] / exp) % 10]++; 23 | } 24 | 25 | for (let i = 1; i < 10; i++) { 26 | count[i] += count[i - 1]; 27 | } 28 | 29 | for (let i = n - 1; i >= 0; i--) { 30 | output[count[Math.floor(this.arr[i] / exp) % 10] - 1] = this.arr[i]; 31 | count[Math.floor(this.arr[i] / exp) % 10]--; 32 | } 33 | 34 | for (let i = 0; i < n; i++) { 35 | this.arr[i] = output[i]; 36 | } 37 | } 38 | 39 | sort() { 40 | const max = this.getMax(); 41 | 42 | for (let exp = 1; Math.floor(max / exp) > 0; exp *= 10) { 43 | this.countSort(exp); 44 | } 45 | 46 | return this.arr; 47 | } 48 | } 49 | 50 | module.exports = RadixSort; 51 | -------------------------------------------------------------------------------- /test/algorithms/numerical/fastExponentiation.test.js: -------------------------------------------------------------------------------- 1 | const FastExponentiation = require('../../../algorithms/numerical/fastExponentiation'); 2 | 3 | describe('FastExponentiation', () => { 4 | it('should correctly calculate 2^5', () => { 5 | const base = 2; 6 | const exponent = 5; 7 | const result = FastExponentiation.power(base, exponent); 8 | expect(result).toBe(32); 9 | }); 10 | 11 | it('should handle base case with exponent 0', () => { 12 | const base = 5; 13 | const exponent = 0; 14 | const result = FastExponentiation.power(base, exponent); 15 | expect(result).toBe(1); 16 | }); 17 | 18 | it('should calculate 3^6', () => { 19 | const base = 3; 20 | const exponent = 6; 21 | const result = FastExponentiation.power(base, exponent); 22 | expect(result).toBe(729); 23 | }); 24 | 25 | it('should calculate 7^3', () => { 26 | const base = 7; 27 | const exponent = 3; 28 | const result = FastExponentiation.power(base, exponent); 29 | expect(result).toBe(343); 30 | }); 31 | 32 | it('should handle large exponent (10^3)', () => { 33 | const base = 10; 34 | const exponent = 1000; 35 | const result = FastExponentiation.power(base, exponent); 36 | expect(result.toString()).toBe("Infinity"); 37 | }); 38 | }); 39 | -------------------------------------------------------------------------------- /test/data-structures/graphs/GraphNode.test.js: -------------------------------------------------------------------------------- 1 | const assert = require('assert'); 2 | const GraphNode = require('../../../data-structures/graphs/GraphNode'); 3 | 4 | describe('GraphNode', () => { 5 | it('should create a graph node with a value', () => { 6 | const node = new GraphNode('A'); 7 | assert.strictEqual(node.value, 'A'); 8 | }); 9 | 10 | it('should add neighbors to a graph node', () => { 11 | const nodeA = new GraphNode('A'); 12 | const nodeB = new GraphNode('B'); 13 | const nodeC = new GraphNode('C'); 14 | 15 | nodeA.addNeighbor(nodeB); 16 | nodeA.addNeighbor(nodeC); 17 | 18 | assert.strictEqual(nodeA.getNeighbors().length, 2); 19 | assert.strictEqual(nodeB.getNeighbors().length, 1); 20 | assert.strictEqual(nodeC.getNeighbors().length, 1); 21 | }); 22 | 23 | it('should remove neighbors from a graph node', () => { 24 | const nodeA = new GraphNode('A'); 25 | const nodeB = new GraphNode('B'); 26 | const nodeC = new GraphNode('C'); 27 | 28 | nodeA.addNeighbor(nodeB); 29 | nodeA.addNeighbor(nodeC); 30 | nodeA.removeNeighbor(nodeB); 31 | 32 | assert.strictEqual(nodeA.getNeighbors().length, 1); 33 | assert.strictEqual(nodeB.getNeighbors().length, 0); 34 | assert.strictEqual(nodeC.getNeighbors().length, 1); 35 | }); 36 | }); 37 | -------------------------------------------------------------------------------- /test/algorithms/randomized/randomizedQuickSort.test.js: -------------------------------------------------------------------------------- 1 | const RandomizedQuickSort = require('../../../algorithms/randomized/randomizedQuickSort'); 2 | 3 | describe('RandomizedQuickSort', () => { 4 | it('should sort an array of numbers in ascending order', () => { 5 | const arr = [5, 3, 1, 4, 2]; 6 | const sortedArr = [1, 2, 3, 4, 5]; 7 | const randomizedQuickSort = new RandomizedQuickSort(); 8 | randomizedQuickSort.sort(arr); 9 | expect(arr).toEqual(sortedArr); 10 | }); 11 | 12 | it('should handle an empty array', () => { 13 | const arr = []; 14 | const randomizedQuickSort = new RandomizedQuickSort(); 15 | randomizedQuickSort.sort(arr); 16 | expect(arr).toEqual([]); 17 | }); 18 | 19 | it('should handle an array with a single element', () => { 20 | const arr = [42]; 21 | const randomizedQuickSort = new RandomizedQuickSort(); 22 | randomizedQuickSort.sort(arr); 23 | expect(arr).toEqual([42]); 24 | }); 25 | 26 | it('should handle large arrays', () => { 27 | const arr = []; 28 | for (let i = 1000; i > 0; i--) { 29 | arr.push(i); 30 | } 31 | const randomizedQuickSort = new RandomizedQuickSort(); 32 | randomizedQuickSort.sort(arr); 33 | expect(arr).toEqual(Array.from({ length: 1000 }, (_, i) => i + 1)); 34 | }); 35 | }); 36 | -------------------------------------------------------------------------------- /test/algorithms/string/stringMatching.test.js: -------------------------------------------------------------------------------- 1 | const StringMatching = require('../../../algorithms/string/stringMatching'); 2 | 3 | describe('StringMatching', () => { 4 | it('should return an empty array when given an empty string', () => { 5 | const text = ''; 6 | const substring = 'pattern'; 7 | 8 | const occurrences = StringMatching.findSubstringOccurrences(text, substring); 9 | 10 | expect(occurrences).toEqual([]); 11 | }); 12 | 13 | it('should return an empty array when given an empty substring', () => { 14 | const text = 'text with no pattern'; 15 | const substring = ''; 16 | 17 | const occurrences = StringMatching.findSubstringOccurrences(text, substring); 18 | 19 | expect(occurrences).toEqual([]); 20 | }); 21 | 22 | it('should find occurrences of the substring in the text', () => { 23 | const text = 'text with pattern pattern pattern'; 24 | const substring = 'pattern'; 25 | 26 | const occurrences = StringMatching.findSubstringOccurrences(text, substring); 27 | 28 | expect(occurrences).toEqual([10, 18, 26]); 29 | }); 30 | 31 | it('should return an empty array when no occurrences are found', () => { 32 | const text = 'text with no pattern'; 33 | const substring = 'missing'; 34 | 35 | const occurrences = StringMatching.findSubstringOccurrences(text, substring); 36 | 37 | expect(occurrences).toEqual([]); 38 | }); 39 | }); 40 | -------------------------------------------------------------------------------- /data-structures/disjoint-set/DisjointSet.js: -------------------------------------------------------------------------------- 1 | class DisjointSet { 2 | constructor() { 3 | this.parent = new Map(); 4 | this.rank = new Map(); 5 | } 6 | 7 | makeSet(value) { 8 | if (!this.parent.has(value)) { 9 | this.parent.set(value, value); 10 | this.rank.set(value, 0); 11 | } 12 | } 13 | 14 | find(value) { 15 | if (!this.parent.has(value)) { 16 | return null; 17 | } 18 | 19 | if (value !== this.parent.get(value)) { 20 | this.parent.set(value, this.find(this.parent.get(value))); 21 | } 22 | 23 | return this.parent.get(value); 24 | } 25 | 26 | union(value1, value2) { 27 | const root1 = this.find(value1); 28 | const root2 = this.find(value2); 29 | 30 | if (root1 === null || root2 === null || root1 === root2) { 31 | return false; // Values are already in the same set or don't exist. 32 | } 33 | 34 | if (this.rank.get(root1) < this.rank.get(root2)) { 35 | this.parent.set(root1, root2); 36 | } else if (this.rank.get(root1) > this.rank.get(root2)) { 37 | this.parent.set(root2, root1); 38 | } else { 39 | this.parent.set(root2, root1); 40 | this.rank.set(root1, this.rank.get(root1) + 1); 41 | } 42 | 43 | return true; 44 | } 45 | } 46 | 47 | module.exports = DisjointSet; 48 | -------------------------------------------------------------------------------- /data-structures/hash-tables/HashTable.js: -------------------------------------------------------------------------------- 1 | class HashTable { 2 | constructor(size = 100) { 3 | this.size = size; 4 | this.table = new Array(size); 5 | } 6 | 7 | // Hash function to determine the index in the table. 8 | hash(key) { 9 | let hash = 0; 10 | for (let i = 0; i < key.length; i++) { 11 | hash += key.charCodeAt(i); 12 | } 13 | return hash % this.size; 14 | } 15 | 16 | // Insert a key-value pair into the hash table. 17 | insert(key, value) { 18 | const index = this.hash(key); 19 | if (!this.table[index]) { 20 | this.table[index] = []; 21 | } 22 | this.table[index].push({ key, value }); 23 | } 24 | 25 | // Retrieve the value associated with a key. 26 | get(key) { 27 | const index = this.hash(key); 28 | if (this.table[index]) { 29 | for (let item of this.table[index]) { 30 | if (item.key === key) { 31 | return item.value; 32 | } 33 | } 34 | } 35 | return null; 36 | } 37 | 38 | // Remove a key-value pair from the hash table. 39 | remove(key) { 40 | const index = this.hash(key); 41 | if (this.table[index]) { 42 | this.table[index] = this.table[index].filter((item) => item.key !== key); 43 | } 44 | } 45 | } 46 | 47 | module.exports = HashTable; 48 | -------------------------------------------------------------------------------- /data-structures/linked-lists/CircularLinkedList.js: -------------------------------------------------------------------------------- 1 | // Define the Node class for a circular linked list. 2 | class Node { 3 | constructor(data) { 4 | this.data = data; 5 | this.next = this; 6 | } 7 | } 8 | 9 | // Define the CircularLinkedList class to manage the linked list. 10 | class CircularLinkedList { 11 | constructor() { 12 | this.head = null; 13 | } 14 | 15 | // Add a new node to the end of the linked list. 16 | append(data) { 17 | const newNode = new Node(data); 18 | if (!this.head) { 19 | this.head = newNode; 20 | } else { 21 | let tail = this.head; // Change 'const' to 'let' 22 | while (tail.next !== this.head) { 23 | tail = tail.next; // Now you can reassign 'tail' 24 | } 25 | tail.next = newNode; 26 | newNode.next = this.head; 27 | } 28 | } 29 | 30 | // Display the linked list. 31 | display() { 32 | if (!this.head) { 33 | return []; 34 | } 35 | 36 | const result = [this.head.data]; 37 | let current = this.head.next; 38 | while (current !== this.head) { 39 | result.push(current.data); 40 | current = current.next; 41 | } 42 | return result; 43 | } 44 | } 45 | 46 | // Export the CircularLinkedList class for use in other files. 47 | module.exports = CircularLinkedList; 48 | -------------------------------------------------------------------------------- /test/algorithms/dynamic-programming/fibonacci.test.js: -------------------------------------------------------------------------------- 1 | const Fibonacci = require('../../../algorithms/dynamic-programming/fibonacci'); 2 | 3 | describe('Fibonacci (OOP)', () => { 4 | it('should calculate the Fibonacci number for a given n', () => { 5 | const fibonacci = new Fibonacci(); 6 | 7 | // Test some base cases 8 | expect(fibonacci.calculateFibonacci(0)).toBe(0); 9 | expect(fibonacci.calculateFibonacci(1)).toBe(1); 10 | expect(fibonacci.calculateFibonacci(2)).toBe(1); 11 | expect(fibonacci.calculateFibonacci(3)).toBe(2); 12 | expect(fibonacci.calculateFibonacci(4)).toBe(3); 13 | expect(fibonacci.calculateFibonacci(5)).toBe(5); 14 | expect(fibonacci.calculateFibonacci(6)).toBe(8); 15 | expect(fibonacci.calculateFibonacci(7)).toBe(13); 16 | expect(fibonacci.calculateFibonacci(8)).toBe(21); 17 | expect(fibonacci.calculateFibonacci(9)).toBe(34); 18 | 19 | // Test some additional cases 20 | expect(fibonacci.calculateFibonacci(10)).toBe(55); 21 | expect(fibonacci.calculateFibonacci(15)).toBe(610); 22 | expect(fibonacci.calculateFibonacci(20)).toBe(6765); 23 | expect(fibonacci.calculateFibonacci(25)).toBe(75025); 24 | 25 | // Test large values 26 | expect(fibonacci.calculateFibonacci(40)).toBe(102334155); 27 | expect(fibonacci.calculateFibonacci(50)).toBe(12586269025); 28 | }); 29 | }); 30 | -------------------------------------------------------------------------------- /algorithms/geometry/lineIntersection.js: -------------------------------------------------------------------------------- 1 | class LineIntersection { 2 | static findIntersections(lines) { 3 | const intersections = []; 4 | 5 | for (let i = 0; i < lines.length; i++) { 6 | for (let j = i + 1; j < lines.length; j++) { 7 | const intersection = LineIntersection.findLineIntersection(lines[i], lines[j]); 8 | if (intersection) { 9 | intersections.push(intersection); 10 | } 11 | } 12 | } 13 | 14 | return intersections; 15 | } 16 | 17 | static findLineIntersection(line1, line2) { 18 | const { x1: x1, y1: y1, x2: x2, y2: y2 } = line1; 19 | const { x1: x3, y1: y3, x2: x4, y2: y4 } = line2; 20 | 21 | const denominator = (x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4); 22 | 23 | if (denominator === 0) { 24 | return null; // Lines are parallel 25 | } 26 | 27 | const px = ((x1 * y2 - y1 * x2) * (x3 - x4) - (x1 - x2) * (x3 * y4 - y3 * x4)) / denominator; 28 | const py = ((x1 * y2 - y1 * x2) * (y3 - y4) - (y1 - y2) * (x3 * y4 - y3 * x4)) / denominator; 29 | 30 | if (px < Math.min(x1, x2) || px > Math.max(x1, x2) || px < Math.min(x3, x4) || px > Math.max(x3, x4)) { 31 | return null; // Intersection is not within the line segments 32 | } 33 | 34 | return { x: px, y: py }; 35 | } 36 | } 37 | 38 | module.exports = LineIntersection; 39 | -------------------------------------------------------------------------------- /test/data-structures/trees/BinaryTree.test.js: -------------------------------------------------------------------------------- 1 | const assert = require('assert'); 2 | const BinaryTree = require('../../../data-structures/trees/BinaryTree'); 3 | 4 | describe('BinaryTree', () => { 5 | it('should create an empty binary tree', () => { 6 | const tree = new BinaryTree(); 7 | assert.strictEqual(tree.root, null); 8 | }); 9 | 10 | it('should insert values into the binary tree', () => { 11 | const tree = new BinaryTree(); 12 | tree.insert(10); 13 | tree.insert(5); 14 | tree.insert(15); 15 | 16 | assert.strictEqual(tree.root.value, 10); 17 | assert.strictEqual(tree.root.left.value, 5); 18 | assert.strictEqual(tree.root.right.value, 15); 19 | }); 20 | 21 | it('should search for values in the binary tree', () => { 22 | const tree = new BinaryTree(); 23 | tree.insert(10); 24 | tree.insert(5); 25 | tree.insert(15); 26 | 27 | assert.strictEqual(tree.search(5), true); 28 | assert.strictEqual(tree.search(20), false); 29 | }); 30 | 31 | it('should perform in-order traversal of the binary tree', () => { 32 | const tree = new BinaryTree(); 33 | tree.insert(10); 34 | tree.insert(5); 35 | tree.insert(15); 36 | tree.insert(3); 37 | tree.insert(7); 38 | 39 | const result = tree.inOrderTraversal(); 40 | assert.deepStrictEqual(result, [3, 5, 7, 10, 15]); 41 | }); 42 | }); 43 | -------------------------------------------------------------------------------- /test/algorithms/dynamic-programming/knapsack.test.js: -------------------------------------------------------------------------------- 1 | const Knapsack = require('../../../algorithms/dynamic-programming/knapsack'); 2 | 3 | describe('Knapsack (OOP)', () => { 4 | const knapsack = new Knapsack(); 5 | 6 | it('should find the maximum value for the knapsack problem', () => { 7 | // Test case 1 8 | const weights1 = [2, 2, 3]; 9 | const values1 = [2, 3, 5]; 10 | const capacity1 = 4; 11 | expect(knapsack.findMaxValue(weights1, values1, capacity1)).toBe(5); 12 | 13 | // Test case 2 14 | const weights2 = [1, 3, 4, 5]; 15 | const values2 = [1, 4, 5, 7]; 16 | const capacity2 = 7; 17 | expect(knapsack.findMaxValue(weights2, values2, capacity2)).toBe(9); 18 | 19 | // Test case 3 20 | const weights3 = [1, 2, 4, 2]; 21 | const values3 = [5, 3, 5, 3]; 22 | const capacity3 = 5; 23 | expect(knapsack.findMaxValue(weights3, values3, capacity3)).toBe(11); 24 | 25 | // Test case 4 (Edge case: Empty knapsack) 26 | const weights4 = []; 27 | const values4 = []; 28 | const capacity4 = 10; 29 | expect(knapsack.findMaxValue(weights4, values4, capacity4)).toBe(0); 30 | 31 | // Test case 5 (Edge case: No items to choose from) 32 | const weights5 = [2, 3, 4]; 33 | const values5 = [3, 5, 6]; 34 | const capacity5 = 0; 35 | expect(knapsack.findMaxValue(weights5, values5, capacity5)).toBe(0); 36 | }); 37 | }); 38 | -------------------------------------------------------------------------------- /algorithms/graph-algorithms/bellmanFord.js: -------------------------------------------------------------------------------- 1 | class BellmanFord { 2 | constructor(graph) { 3 | this.graph = graph; 4 | } 5 | 6 | findShortestPath(source) { 7 | const distance = {}; 8 | const predecessor = {}; 9 | const vertices = Object.keys(this.graph); 10 | 11 | // Initialize distances and predecessors 12 | for (const vertex of vertices) { 13 | distance[vertex] = vertex === source ? 0 : Infinity; 14 | predecessor[vertex] = null; 15 | } 16 | 17 | // Relax edges repeatedly 18 | for (let i = 0; i < vertices.length - 1; i++) { 19 | for (const u of vertices) { 20 | for (const v in this.graph[u]) { 21 | const weight = this.graph[u][v]; 22 | if (distance[u] + weight < distance[v]) { 23 | distance[v] = distance[u] + weight; 24 | predecessor[v] = u; 25 | } 26 | } 27 | } 28 | } 29 | 30 | // Check for negative weight cycles 31 | for (const u of vertices) { 32 | for (const v in this.graph[u]) { 33 | const weight = this.graph[u][v]; 34 | if (distance[u] + weight < distance[v]) { 35 | throw new Error('Graph contains a negative weight cycle'); 36 | } 37 | } 38 | } 39 | 40 | return { distance, predecessor }; 41 | } 42 | } 43 | 44 | module.exports = BellmanFord; 45 | -------------------------------------------------------------------------------- /data-structures/linked-lists/DoublyLinkedList.js: -------------------------------------------------------------------------------- 1 | // Define the Node class for a doubly linked list. 2 | class Node { 3 | constructor(data) { 4 | this.data = data; 5 | this.prev = null; 6 | this.next = null; 7 | } 8 | } 9 | 10 | // Define the DoublyLinkedList class to manage the linked list. 11 | class DoublyLinkedList { 12 | constructor() { 13 | this.head = null; 14 | this.tail = null; 15 | } 16 | 17 | // Add a new node to the end of the linked list. 18 | append(data) { 19 | const newNode = new Node(data); 20 | if (!this.head) { 21 | this.head = newNode; 22 | this.tail = newNode; 23 | } else { 24 | newNode.prev = this.tail; 25 | this.tail.next = newNode; 26 | this.tail = newNode; 27 | } 28 | } 29 | 30 | // Display the linked list in forward direction. 31 | displayForward() { 32 | let current = this.head; 33 | const result = []; 34 | while (current) { 35 | result.push(current.data); 36 | current = current.next; 37 | } 38 | return result; 39 | } 40 | 41 | // Display the linked list in reverse direction. 42 | displayBackward() { 43 | let current = this.tail; 44 | const result = []; 45 | while (current) { 46 | result.push(current.data); 47 | current = current.prev; 48 | } 49 | return result; 50 | } 51 | } 52 | 53 | // Export the DoublyLinkedList class for use in other files. 54 | module.exports = DoublyLinkedList; 55 | -------------------------------------------------------------------------------- /docs/utils/utilityFunctions.md: -------------------------------------------------------------------------------- 1 | # UtilityFunctions 2 | 3 | The `UtilityFunctions` class contains static utility methods for performing common mathematical operations on arrays of numbers. 4 | 5 | ## Methods 6 | 7 | ### `sum(arr: number[]): number` 8 | 9 | Calculates the sum of all the elements in the given array of numbers. 10 | 11 | - `arr` (Array of Numbers): The array of numbers to calculate the sum for. 12 | 13 | **Example:** 14 | 15 | ```javascript 16 | const numbers = [1, 2, 3, 4, 5]; 17 | const sumResult = UtilityFunctions.sum(numbers); // Returns 15 18 | ``` 19 | 20 | ### `average(arr: number[]): number` 21 | 22 | Calculates the average (mean) of all the elements in the given array of numbers. 23 | 24 | - `arr` (Array of Numbers): The array of numbers to calculate the average for. 25 | 26 | **Example:** 27 | 28 | ```javascript 29 | const numbers = [2, 4, 6, 8, 10]; 30 | const averageResult = UtilityFunctions.average(numbers); // Returns 6 31 | ``` 32 | 33 | ## Testing 34 | 35 | You can use the provided test cases to ensure the correctness of these utility functions. The test cases use the Jest testing framework. 36 | 37 | ### Running Tests 38 | 39 | 1. Make sure you have Jest installed (you can install it using `npm install jest`). 40 | 2. Run the tests using the following command: 41 | 42 | ```bash 43 | npx jest 44 | ``` 45 | 46 | ## Conclusion 47 | 48 | The `UtilityFunctions` class provides convenient methods for calculating the sum and average of an array of numbers. These methods are useful for a variety of scenarios in which you need to perform basic mathematical calculations on data sets. 49 | -------------------------------------------------------------------------------- /test/algorithms/string/levenshteinDistance.test.js: -------------------------------------------------------------------------------- 1 | const LevenshteinDistance = require('../../../algorithms/string/levenshteinDistance'); 2 | 3 | describe('LevenshteinDistance', () => { 4 | it('should compute the Levenshtein distance between two identical strings', () => { 5 | const str1 = 'kitten'; 6 | const str2 = 'kitten'; 7 | 8 | const distance = LevenshteinDistance.computeDistance(str1, str2); 9 | 10 | expect(distance).toBe(0); 11 | }); 12 | 13 | it('should compute the Levenshtein distance between two different strings', () => { 14 | const str1 = 'kitten'; 15 | const str2 = 'sitting'; 16 | 17 | const distance = LevenshteinDistance.computeDistance(str1, str2); 18 | 19 | expect(distance).toBe(3); 20 | }); 21 | 22 | it('should handle one empty string', () => { 23 | const str1 = 'kitten'; 24 | const str2 = ''; 25 | 26 | const distance = LevenshteinDistance.computeDistance(str1, str2); 27 | 28 | expect(distance).toBe(6); 29 | }); 30 | 31 | it('should handle both empty strings', () => { 32 | const str1 = ''; 33 | const str2 = ''; 34 | 35 | const distance = LevenshteinDistance.computeDistance(str1, str2); 36 | 37 | expect(distance).toBe(0); 38 | }); 39 | 40 | it('should handle one string being a prefix of the other', () => { 41 | const str1 = 'hello'; 42 | const str2 = 'hello world'; 43 | 44 | const distance = LevenshteinDistance.computeDistance(str1, str2); 45 | 46 | expect(distance).toBe(6); 47 | }); 48 | }); 49 | -------------------------------------------------------------------------------- /algorithms/geometry/convexHull.js: -------------------------------------------------------------------------------- 1 | class ConvexHull { 2 | static findConvexHull(points) { 3 | const n = points.length; 4 | 5 | if (n < 3) { 6 | return points; 7 | } 8 | 9 | // Find the point with the lowest y-coordinate (and leftmost if tied) 10 | const startPoint = points.reduce((min, p) => (p.y < min.y || (p.y === min.y && p.x < min.x) ? p : min), points[0]); 11 | 12 | const sortedPoints = points.slice(); // Copy of the original array 13 | sortedPoints.sort((a, b) => { 14 | const angleA = Math.atan2(a.y - startPoint.y, a.x - startPoint.x); 15 | const angleB = Math.atan2(b.y - startPoint.y, b.x - startPoint.x); 16 | if (angleA < angleB) return -1; 17 | if (angleA > angleB) return 1; 18 | return a.x - b.x; 19 | }); 20 | 21 | const hull = [startPoint, sortedPoints[0]]; 22 | 23 | for (let i = 1; i < n; i++) { 24 | while (hull.length > 1) { 25 | const m = hull.length; 26 | const a = hull[m - 2]; 27 | const b = hull[m - 1]; 28 | const c = sortedPoints[i]; 29 | 30 | if (ConvexHull.crossProduct(a, b, c) <= 0) { 31 | hull.pop(); 32 | } else { 33 | break; 34 | } 35 | } 36 | hull.push(sortedPoints[i]); 37 | } 38 | 39 | return hull; 40 | } 41 | 42 | static crossProduct(a, b, c) { 43 | return (b.x - a.x) * (c.y - a.y) - (c.x - a.x) * (b.y - a.y); 44 | } 45 | } 46 | 47 | module.exports = ConvexHull; 48 | -------------------------------------------------------------------------------- /data-structures/graphs/Graph.js: -------------------------------------------------------------------------------- 1 | class Graph { 2 | constructor() { 3 | this.vertices = new Map(); 4 | } 5 | 6 | addVertex(vertex) { 7 | if (!this.vertices.has(vertex)) { 8 | this.vertices.set(vertex, new Set()); 9 | } 10 | } 11 | 12 | addEdge(vertex1, vertex2) { 13 | if (this.vertices.has(vertex1) && this.vertices.has(vertex2)) { 14 | this.vertices.get(vertex1).add(vertex2); 15 | this.vertices.get(vertex2).add(vertex1); 16 | } 17 | } 18 | 19 | getVertices() { 20 | return Array.from(this.vertices.keys()); 21 | } 22 | 23 | getEdges(vertex) { 24 | if (this.vertices.has(vertex)) { 25 | return Array.from(this.vertices.get(vertex)); 26 | } 27 | return []; 28 | } 29 | 30 | hasVertex(vertex) { 31 | return this.vertices.has(vertex); 32 | } 33 | 34 | hasEdge(vertex1, vertex2) { 35 | return ( 36 | this.vertices.has(vertex1) && 37 | this.vertices.get(vertex1).has(vertex2) 38 | ); 39 | } 40 | 41 | removeVertex(vertex) { 42 | if (this.vertices.has(vertex)) { 43 | this.vertices.get(vertex).forEach((neighbor) => { 44 | this.vertices.get(neighbor).delete(vertex); 45 | }); 46 | this.vertices.delete(vertex); 47 | } 48 | } 49 | 50 | removeEdge(vertex1, vertex2) { 51 | if (this.hasEdge(vertex1, vertex2)) { 52 | this.vertices.get(vertex1).delete(vertex2); 53 | this.vertices.get(vertex2).delete(vertex1); 54 | } 55 | } 56 | } 57 | 58 | module.exports = Graph; 59 | -------------------------------------------------------------------------------- /test/algorithms/searching/linearSearch.test.js: -------------------------------------------------------------------------------- 1 | const LinearSearch = require("../../../algorithms/searching/linearSearch"); 2 | 3 | describe("LinearSearch (OOP)", () => { 4 | it("should find the target element in the array", () => { 5 | const arr = [1, 2, 3, 4, 5]; 6 | const linearSearch = new LinearSearch(arr); 7 | const target = 3; 8 | const index = linearSearch.search(target); 9 | expect(index).toEqual(2); 10 | }); 11 | 12 | it("should handle an empty array", () => { 13 | const arr = []; 14 | const linearSearch = new LinearSearch(arr); 15 | const target = 5; 16 | const index = linearSearch.search(target); 17 | expect(index).toEqual(-1); 18 | }); 19 | 20 | it("should handle an array without the target element", () => { 21 | const arr = [10, 20, 30, 40, 50]; 22 | const linearSearch = new LinearSearch(arr); 23 | const target = 35; 24 | const index = linearSearch.search(target); 25 | expect(index).toEqual(-1); 26 | }); 27 | 28 | it("should find the target element at the beginning of the array", () => { 29 | const arr = [1, 2, 3, 4, 5]; 30 | const linearSearch = new LinearSearch(arr); 31 | const target = 1; 32 | const index = linearSearch.search(target); 33 | expect(index).toEqual(0); 34 | }); 35 | 36 | it("should find the target element at the end of the array", () => { 37 | const arr = [1, 2, 3, 4, 5]; 38 | const linearSearch = new LinearSearch(arr); 39 | const target = 5; 40 | const index = linearSearch.search(target); 41 | expect(index).toEqual(4); 42 | }); 43 | }); 44 | -------------------------------------------------------------------------------- /test/data-structures/linked-lists/DoublyLinkedList.test.js: -------------------------------------------------------------------------------- 1 | const assert = require('assert'); 2 | const DoublyLinkedList = require('../../../data-structures/linked-lists/DoublyLinkedList'); 3 | 4 | describe('Doubly Linked List', () => { 5 | it('should create an empty list', () => { 6 | const list = new DoublyLinkedList(); 7 | assert.strictEqual(list.head, null); 8 | assert.strictEqual(list.tail, null); 9 | }); 10 | 11 | it('should append elements to the list', () => { 12 | const list = new DoublyLinkedList(); 13 | list.append(1); 14 | list.append(2); 15 | list.append(3); 16 | 17 | const forwardElements = list.displayForward(); 18 | const backwardElements = list.displayBackward(); 19 | 20 | assert.deepStrictEqual(forwardElements, [1, 2, 3]); 21 | assert.deepStrictEqual(backwardElements, [3, 2, 1]); 22 | }); 23 | 24 | it('should display an empty list as empty arrays', () => { 25 | const list = new DoublyLinkedList(); 26 | const forwardElements = list.displayForward(); 27 | const backwardElements = list.displayBackward(); 28 | 29 | assert.deepStrictEqual(forwardElements, []); 30 | assert.deepStrictEqual(backwardElements, []); 31 | }); 32 | 33 | it('should display a list with a single element', () => { 34 | const list = new DoublyLinkedList(); 35 | list.append(42); 36 | 37 | const forwardElements = list.displayForward(); 38 | const backwardElements = list.displayBackward(); 39 | 40 | assert.deepStrictEqual(forwardElements, [42]); 41 | assert.deepStrictEqual(backwardElements, [42]); 42 | }); 43 | }); 44 | -------------------------------------------------------------------------------- /test/algorithms/searching/binarySearch.test.js: -------------------------------------------------------------------------------- 1 | const BinarySearch = require("../../../algorithms/searching/binarySearch"); 2 | 3 | describe("BinarySearch (OOP)", () => { 4 | it("should find the target element in the sorted array", () => { 5 | const arr = [1, 2, 3, 4, 5, 6, 7]; 6 | const binarySearch = new BinarySearch(arr); 7 | const target = 4; 8 | const index = binarySearch.search(target); 9 | expect(index).toEqual(3); 10 | }); 11 | 12 | it("should handle an empty array", () => { 13 | const arr = []; 14 | const binarySearch = new BinarySearch(arr); 15 | const target = 5; 16 | const index = binarySearch.search(target); 17 | expect(index).toEqual(-1); 18 | }); 19 | 20 | it("should handle an array without the target element", () => { 21 | const arr = [10, 20, 30, 40, 50]; 22 | const binarySearch = new BinarySearch(arr); 23 | const target = 35; 24 | const index = binarySearch.search(target); 25 | expect(index).toEqual(-1); 26 | }); 27 | 28 | it("should find the target element at the beginning of the array", () => { 29 | const arr = [1, 2, 3, 4, 5]; 30 | const binarySearch = new BinarySearch(arr); 31 | const target = 1; 32 | const index = binarySearch.search(target); 33 | expect(index).toEqual(0); 34 | }); 35 | 36 | it("should find the target element at the end of the array", () => { 37 | const arr = [1, 2, 3, 4, 5]; 38 | const binarySearch = new BinarySearch(arr); 39 | const target = 5; 40 | const index = binarySearch.search(target); 41 | expect(index).toEqual(4); 42 | }); 43 | }); 44 | -------------------------------------------------------------------------------- /docs/data-structures/trees/AVLTree.md: -------------------------------------------------------------------------------- 1 | # JavaScript AVL Tree Data Structure 2 | 3 | The JavaScript AVL Tree data structure is implemented in the `AVLTree` class, which allows you to create a self-balancing binary search tree with AVL properties. Here's how to use the `AVLTree` class: 4 | 5 | ## Introduction 6 | 7 | To get started with the `AVLTree` class, you can install the package via npm using the following command: 8 | 9 | ```bash 10 | npm install adv-dsa 11 | ``` 12 | 13 | ## Example Usage 14 | 15 | ### Creating an AVL Tree 16 | You can create a new AVL Tree using the `AVLTree` class: 17 | 18 | ```javascript 19 | const AVLTree = require('adv-dsa'); 20 | 21 | // Initialize a new AVL tree 22 | const avlTree = new AVLTree(); 23 | ``` 24 | 25 | ### Inserting Values 26 | You can insert values into the AVL tree using the `insert` method: 27 | 28 | ```javascript 29 | avlTree.insert(10); 30 | avlTree.insert(5); 31 | avlTree.insert(15); 32 | ``` 33 | 34 | The AVL tree will automatically balance itself after each insertion to maintain AVL properties. 35 | 36 | ## Testing 37 | 38 | You can also test the `AVLTree` class using the provided test cases in your test file (e.g., `test.js`). Make sure to import the `AVLTree` class and use the `assert` module for testing: 39 | 40 | ```javascript 41 | const assert = require('assert'); 42 | const AVLTree = require('adv-dsa'); 43 | 44 | // Your test cases go here 45 | ``` 46 | 47 | ## Conclusion 48 | 49 | The `AVLTree` class in JavaScript allows you to create a self-balancing binary search tree following AVL properties. It is useful for scenarios where you need to efficiently store and manage a collection of values while maintaining balance for better performance in search and other operations. 50 | -------------------------------------------------------------------------------- /test/data-structures/graphs/Graph.test.js: -------------------------------------------------------------------------------- 1 | const assert = require('assert'); 2 | const Graph = require('../../../data-structures/graphs/Graph'); 3 | 4 | describe('Graph', () => { 5 | it('should create an empty graph', () => { 6 | const graph = new Graph(); 7 | assert.strictEqual(graph.getVertices().length, 0); 8 | }); 9 | 10 | it('should add vertices to the graph', () => { 11 | const graph = new Graph(); 12 | graph.addVertex('A'); 13 | graph.addVertex('B'); 14 | graph.addVertex('C'); 15 | 16 | assert.strictEqual(graph.getVertices().length, 3); 17 | assert.strictEqual(graph.hasVertex('A'), true); 18 | assert.strictEqual(graph.hasVertex('D'), false); 19 | }); 20 | 21 | it('should add edges between vertices', () => { 22 | const graph = new Graph(); 23 | graph.addVertex('A'); 24 | graph.addVertex('B'); 25 | graph.addVertex('C'); 26 | graph.addEdge('A', 'B'); 27 | graph.addEdge('B', 'C'); 28 | 29 | assert.strictEqual(graph.hasEdge('A', 'B'), true); 30 | assert.strictEqual(graph.hasEdge('B', 'C'), true); 31 | assert.strictEqual(graph.hasEdge('A', 'C'), false); 32 | }); 33 | 34 | it('should remove vertices and edges', () => { 35 | const graph = new Graph(); 36 | graph.addVertex('A'); 37 | graph.addVertex('B'); 38 | graph.addVertex('C'); 39 | graph.addEdge('A', 'B'); 40 | graph.addEdge('B', 'C'); 41 | graph.removeVertex('B'); 42 | 43 | assert.strictEqual(graph.hasVertex('B'), false); 44 | assert.strictEqual(graph.hasEdge('A', 'B'), false); 45 | assert.strictEqual(graph.hasEdge('B', 'C'), false); 46 | }); 47 | }); 48 | -------------------------------------------------------------------------------- /test/algorithms/string/longestCommonSubstring.test.js: -------------------------------------------------------------------------------- 1 | const LongestCommonSubstring = require('../../../algorithms/string/longestCommonSubstring'); 2 | 3 | describe('LongestCommonSubstring', () => { 4 | it('should find the longest common substring between two identical strings', () => { 5 | const str1 = 'hello'; 6 | const str2 = 'hello'; 7 | 8 | const commonSubstring = LongestCommonSubstring.findLongestCommonSubstring(str1, str2); 9 | 10 | expect(commonSubstring).toBe('hello'); 11 | }); 12 | 13 | it('should find the longest common substring between two different strings', () => { 14 | const str1 = 'abcdefgh'; 15 | const str2 = 'cdefg'; 16 | 17 | const commonSubstring = LongestCommonSubstring.findLongestCommonSubstring(str1, str2); 18 | 19 | expect(commonSubstring).toBe('cdefg'); 20 | }); 21 | 22 | it('should handle no common substring between two strings', () => { 23 | const str1 = 'abcdef'; 24 | const str2 = 'xyz'; 25 | 26 | const commonSubstring = LongestCommonSubstring.findLongestCommonSubstring(str1, str2); 27 | 28 | expect(commonSubstring).toBe(''); 29 | }); 30 | 31 | it('should handle one empty string', () => { 32 | const str1 = 'abc'; 33 | const str2 = ''; 34 | 35 | const commonSubstring = LongestCommonSubstring.findLongestCommonSubstring(str1, str2); 36 | 37 | expect(commonSubstring).toBe(''); 38 | }); 39 | 40 | it('should handle both empty strings', () => { 41 | const str1 = ''; 42 | const str2 = ''; 43 | 44 | const commonSubstring = LongestCommonSubstring.findLongestCommonSubstring(str1, str2); 45 | 46 | expect(commonSubstring).toBe(''); 47 | }); 48 | }); 49 | -------------------------------------------------------------------------------- /algorithms/graph-algorithms/dijkstra.js: -------------------------------------------------------------------------------- 1 | class Dijkstra { 2 | constructor(graph) { 3 | this.graph = graph; 4 | } 5 | 6 | findShortestPath(startNode, endNode) { 7 | const distances = {}; 8 | const previousNodes = {}; 9 | const visited = new Set(); 10 | const queue = []; 11 | 12 | // Initialize distances with Infinity and startNode with 0. 13 | for (const node in this.graph) { 14 | distances[node] = Infinity; 15 | previousNodes[node] = null; 16 | } 17 | distances[startNode] = 0; 18 | 19 | queue.push({ node: startNode, distance: distances[startNode] }); 20 | 21 | while (queue.length > 0) { 22 | const { node, distance } = queue.shift(); 23 | 24 | if (visited.has(node)) continue; 25 | visited.add(node); 26 | 27 | for (const neighbor in this.graph[node]) { 28 | const totalDistance = distance + this.graph[node][neighbor]; 29 | if (totalDistance < distances[neighbor]) { 30 | distances[neighbor] = totalDistance; 31 | previousNodes[neighbor] = node; 32 | queue.push({ node: neighbor, distance: totalDistance }); 33 | } 34 | } 35 | } 36 | 37 | return this.constructPath(startNode, endNode, previousNodes); 38 | } 39 | 40 | constructPath(startNode, endNode, previousNodes) { 41 | const path = []; 42 | let currentNode = endNode; 43 | 44 | while (currentNode !== null) { 45 | path.unshift(currentNode); 46 | currentNode = previousNodes[currentNode]; 47 | } 48 | 49 | return path; 50 | } 51 | } 52 | 53 | module.exports = Dijkstra; 54 | -------------------------------------------------------------------------------- /test/algorithms/geometry/convexHull.test.js: -------------------------------------------------------------------------------- 1 | const ConvexHull = require('../../../algorithms/geometry/convexHull'); 2 | 3 | describe('ConvexHull', () => { 4 | it('should find the convex hull for a set of points', () => { 5 | const points = [ 6 | { x: 0, y: 3 }, 7 | { x: 2, y: 2 }, 8 | { x: 1, y: 1 }, 9 | { x: 2, y: 1 }, 10 | { x: 3, y: 0 }, 11 | { x: 0, y: 0 }, 12 | { x: 3, y: 3 }, 13 | ]; 14 | 15 | const hull = ConvexHull.findConvexHull(points); 16 | 17 | expect(hull).toEqual([ 18 | { x: 0, y: 0 }, 19 | { x: 3, y: 0 }, 20 | { x: 3, y: 3 }, 21 | { x: 0, y: 3 }, 22 | ]); 23 | }); 24 | 25 | it('should handle a set of points with collinear points', () => { 26 | const points = [ 27 | { x: 0, y: 0 }, 28 | { x: 1, y: 1 }, 29 | { x: 2, y: 2 }, 30 | { x: 3, y: 3 }, 31 | ]; 32 | 33 | const hull = ConvexHull.findConvexHull(points); 34 | 35 | expect(hull).toEqual([ 36 | { x: 0, y: 0 }, 37 | { x: 3, y: 3 }, 38 | ]); 39 | }); 40 | 41 | it('should handle a set of points with only three non-collinear points', () => { 42 | const points = [ 43 | { x: 0, y: 0 }, 44 | { x: 3, y: 3 }, 45 | ]; 46 | 47 | const hull = ConvexHull.findConvexHull(points); 48 | 49 | expect(hull).toEqual(points); 50 | }); 51 | 52 | it('should handle a set of points with less than three points', () => { 53 | const points = [{ x: 0, y: 0 }]; 54 | 55 | const hull = ConvexHull.findConvexHull(points); 56 | 57 | expect(hull).toEqual(points); 58 | }); 59 | }); 60 | -------------------------------------------------------------------------------- /test/algorithms/network-flow/fordFulkerson.test.js: -------------------------------------------------------------------------------- 1 | const FordFulkerson = require('../../../algorithms/network-flow/fordFulkerson'); 2 | 3 | class Graph { 4 | constructor() { 5 | this.adjacencyList = new Map(); 6 | } 7 | 8 | addVertex(vertex) { 9 | if (!this.adjacencyList.has(vertex)) { 10 | this.adjacencyList.set(vertex, []); 11 | } 12 | } 13 | 14 | addEdge(from, to, capacity) { 15 | this.adjacencyList.get(from).push({ to, capacity }); 16 | this.adjacencyList.get(to).push({ to: from, capacity: 0 }); 17 | } 18 | 19 | getNeighbors(vertex) { 20 | return this.adjacencyList.get(vertex).map((edge) => edge.to); 21 | } 22 | 23 | getCapacity(from, to) { 24 | const edge = this.adjacencyList.get(from).find((e) => e.to === to); 25 | return edge ? edge.capacity : 0; 26 | } 27 | 28 | updateCapacity(from, to, capacityChange) { 29 | const edge = this.adjacencyList.get(from).find((e) => e.to === to); 30 | if (edge) { 31 | edge.capacity += capacityChange; 32 | } 33 | } 34 | } 35 | 36 | describe('FordFulkerson', () => { 37 | it('should find the maximum flow in a flow network', () => { 38 | const graph = new Graph(); 39 | graph.addVertex('A'); 40 | graph.addVertex('B'); 41 | graph.addVertex('C'); 42 | graph.addVertex('D'); 43 | 44 | graph.addEdge('A', 'B', 10); 45 | graph.addEdge('A', 'C', 10); 46 | graph.addEdge('B', 'C', 2); 47 | graph.addEdge('B', 'D', 15); 48 | graph.addEdge('C', 'D', 10); 49 | 50 | const fordFulkerson = new FordFulkerson(graph); 51 | const maxFlow = fordFulkerson.maxFlow('A', 'D'); 52 | 53 | expect(maxFlow).toBe(20); 54 | }); 55 | }); -------------------------------------------------------------------------------- /test/data-structures/disjoint-set/DisjointSet.test.js: -------------------------------------------------------------------------------- 1 | const assert = require('assert'); 2 | const DisjointSet = require('../../../data-structures/disjoint-set/DisjointSet'); 3 | 4 | describe('DisjointSet', () => { 5 | it('should create a disjoint-set and make sets', () => { 6 | const ds = new DisjointSet(); 7 | 8 | ds.makeSet('A'); 9 | ds.makeSet('B'); 10 | ds.makeSet('C'); 11 | 12 | assert.strictEqual(ds.find('A'), 'A'); 13 | assert.strictEqual(ds.find('B'), 'B'); 14 | assert.strictEqual(ds.find('C'), 'C'); 15 | }); 16 | 17 | it('should perform union on disjoint sets', () => { 18 | const ds = new DisjointSet(); 19 | 20 | ds.makeSet('A'); 21 | ds.makeSet('B'); 22 | ds.makeSet('C'); 23 | ds.makeSet('D'); 24 | 25 | ds.union('A', 'B'); 26 | ds.union('C', 'D'); 27 | ds.union('B', 'D'); 28 | 29 | assert.strictEqual(ds.find('A'), 'A'); 30 | assert.strictEqual(ds.find('B'), 'A'); 31 | assert.strictEqual(ds.find('C'), 'A'); 32 | assert.strictEqual(ds.find('D'), 'A'); 33 | }); 34 | 35 | it('should handle invalid operations gracefully', () => { 36 | const ds = new DisjointSet(); 37 | 38 | ds.makeSet('A'); 39 | ds.makeSet('B'); 40 | 41 | assert.strictEqual(ds.find('A'), 'A'); 42 | assert.strictEqual(ds.find('B'), 'B'); 43 | 44 | // Attempt to union elements that don't exist. 45 | assert.strictEqual(ds.union('C', 'D'), false); 46 | 47 | // Attempt to union elements that are already in the same set. 48 | assert.strictEqual(ds.union('A', 'B'), true); 49 | 50 | // Attempt to find an element that doesn't exist. 51 | assert.strictEqual(ds.find('C'), null); 52 | }); 53 | }); 54 | -------------------------------------------------------------------------------- /test/data-structures/stacks-and-queues/Stack.test.js: -------------------------------------------------------------------------------- 1 | const assert = require('assert'); 2 | const Stack = require('../../../data-structures/stacks-and-queues/Stack'); 3 | 4 | describe('Stack', () => { 5 | it('should create an empty stack', () => { 6 | const stack = new Stack(); 7 | assert.strictEqual(stack.size(), 0); 8 | assert.strictEqual(stack.isEmpty(), true); 9 | }); 10 | 11 | it('should add elements to the stack', () => { 12 | const stack = new Stack(); 13 | stack.push(1); 14 | stack.push(2); 15 | stack.push(3); 16 | 17 | assert.strictEqual(stack.size(), 3); 18 | assert.strictEqual(stack.isEmpty(), false); 19 | }); 20 | 21 | it('should remove and return the top element from the stack', () => { 22 | const stack = new Stack(); 23 | stack.push(1); 24 | stack.push(2); 25 | stack.push(3); 26 | 27 | const popped = stack.pop(); 28 | assert.strictEqual(popped, 3); 29 | assert.strictEqual(stack.size(), 2); 30 | }); 31 | 32 | it('should return the top element without removing it', () => { 33 | const stack = new Stack(); 34 | stack.push(1); 35 | stack.push(2); 36 | stack.push(3); 37 | 38 | const peeked = stack.peek(); 39 | assert.strictEqual(peeked, 3); 40 | assert.strictEqual(stack.size(), 3); 41 | }); 42 | 43 | it('should handle an empty stack when popping or peeking', () => { 44 | const stack = new Stack(); 45 | const popped = stack.pop(); 46 | const peeked = stack.peek(); 47 | 48 | assert.strictEqual(popped, null); 49 | assert.strictEqual(peeked, null); 50 | assert.strictEqual(stack.size(), 0); 51 | assert.strictEqual(stack.isEmpty(), true); 52 | }); 53 | }); 54 | -------------------------------------------------------------------------------- /test/data-structures/hash-tables/HashTable.test.js: -------------------------------------------------------------------------------- 1 | const assert = require('assert'); 2 | const HashTable = require('../../../data-structures/hash-tables/HashTable'); 3 | 4 | describe('HashTable', () => { 5 | it('should create an empty hash table with the default size', () => { 6 | const table = new HashTable(); 7 | assert.strictEqual(table.size, 100); 8 | }); 9 | 10 | it('should create an empty hash table with a specified size', () => { 11 | const table = new HashTable(50); 12 | assert.strictEqual(table.size, 50); 13 | }); 14 | 15 | it('should insert and retrieve key-value pairs', () => { 16 | const table = new HashTable(); 17 | table.insert('name', 'Alice'); 18 | table.insert('age', 30); 19 | 20 | assert.strictEqual(table.get('name'), 'Alice'); 21 | assert.strictEqual(table.get('age'), 30); 22 | }); 23 | 24 | it('should handle key collisions', () => { 25 | const table = new HashTable(5); 26 | table.insert('apple', 'fruit'); 27 | table.insert('apples', 'fruits'); 28 | table.insert('banana', 'yellow'); 29 | 30 | assert.strictEqual(table.get('apple'), 'fruit'); 31 | assert.strictEqual(table.get('apples'), 'fruits'); 32 | assert.strictEqual(table.get('banana'), 'yellow'); 33 | }); 34 | 35 | it('should return null for keys that do not exist', () => { 36 | const table = new HashTable(); 37 | assert.strictEqual(table.get('nonexistent'), null); 38 | }); 39 | 40 | it('should remove key-value pairs', () => { 41 | const table = new HashTable(); 42 | table.insert('name', 'Alice'); 43 | table.insert('age', 30); 44 | 45 | table.remove('name'); 46 | assert.strictEqual(table.get('name'), null); 47 | 48 | table.remove('age'); 49 | assert.strictEqual(table.get('age'), null); 50 | }); 51 | }); 52 | -------------------------------------------------------------------------------- /test/data-structures/sets-and-maps/Set.test.js: -------------------------------------------------------------------------------- 1 | const assert = require('assert'); 2 | const Set = require('../../../data-structures/sets-and-maps/Set'); 3 | 4 | describe('Set', () => { 5 | it('should create an empty set', () => { 6 | const set = new Set(); 7 | assert.strictEqual(set.size(), 0); 8 | }); 9 | 10 | it('should add elements to the set', () => { 11 | const set = new Set(); 12 | set.add(1); 13 | set.add(2); 14 | set.add(3); 15 | 16 | assert.strictEqual(set.size(), 3); 17 | }); 18 | 19 | it('should not add duplicate elements to the set', () => { 20 | const set = new Set(); 21 | set.add(1); 22 | assert.strictEqual(set.add(1), false); 23 | assert.strictEqual(set.size(), 1); 24 | }); 25 | 26 | it('should remove elements from the set', () => { 27 | const set = new Set(); 28 | set.add(1); 29 | set.add(2); 30 | 31 | assert.strictEqual(set.delete(1), true); 32 | assert.strictEqual(set.size(), 1); 33 | 34 | assert.strictEqual(set.delete(1), false); 35 | }); 36 | 37 | it('should check if an element is in the set', () => { 38 | const set = new Set(); 39 | set.add(1); 40 | assert.strictEqual(set.has(1), true); 41 | assert.strictEqual(set.has(2), false); 42 | }); 43 | 44 | it('should return an array of all elements in the set', () => { 45 | const set = new Set(); 46 | set.add(1); 47 | set.add(2); 48 | set.add(3); 49 | 50 | const values = set.values(); 51 | assert.deepStrictEqual(values, [1, 2, 3]); 52 | }); 53 | 54 | it('should clear the set', () => { 55 | const set = new Set(); 56 | set.add(1); 57 | set.add(2); 58 | set.add(3); 59 | 60 | set.clear(); 61 | assert.strictEqual(set.size(), 0); 62 | }); 63 | }); 64 | -------------------------------------------------------------------------------- /test/data-structures/stacks-and-queues/Queue.test.js: -------------------------------------------------------------------------------- 1 | const assert = require('assert'); 2 | const Queue = require('../../../data-structures/stacks-and-queues/Queue'); 3 | 4 | describe('Queue', () => { 5 | it('should create an empty queue', () => { 6 | const queue = new Queue(); 7 | assert.strictEqual(queue.size(), 0); 8 | assert.strictEqual(queue.isEmpty(), true); 9 | }); 10 | 11 | it('should add elements to the queue', () => { 12 | const queue = new Queue(); 13 | queue.enqueue(1); 14 | queue.enqueue(2); 15 | queue.enqueue(3); 16 | 17 | assert.strictEqual(queue.size(), 3); 18 | assert.strictEqual(queue.isEmpty(), false); 19 | }); 20 | 21 | it('should remove and return the front element from the queue', () => { 22 | const queue = new Queue(); 23 | queue.enqueue(1); 24 | queue.enqueue(2); 25 | queue.enqueue(3); 26 | 27 | const dequeued = queue.dequeue(); 28 | assert.strictEqual(dequeued, 1); 29 | assert.strictEqual(queue.size(), 2); 30 | }); 31 | 32 | it('should return the front element without removing it', () => { 33 | const queue = new Queue(); 34 | queue.enqueue(1); 35 | queue.enqueue(2); 36 | queue.enqueue(3); 37 | 38 | const frontElement = queue.front(); 39 | assert.strictEqual(frontElement, 1); 40 | assert.strictEqual(queue.size(), 3); 41 | }); 42 | 43 | it('should handle an empty queue when dequeuing or getting the front element', () => { 44 | const queue = new Queue(); 45 | const dequeued = queue.dequeue(); 46 | const frontElement = queue.front(); 47 | 48 | assert.strictEqual(dequeued, null); 49 | assert.strictEqual(frontElement, null); 50 | assert.strictEqual(queue.size(), 0); 51 | assert.strictEqual(queue.isEmpty(), true); 52 | }); 53 | }); 54 | -------------------------------------------------------------------------------- /test/algorithms/searching/depthFirstSearch.test.js: -------------------------------------------------------------------------------- 1 | const { GraphNode, DepthFirstSearch } = require("../../../algorithms/searching/depthFirstSearch"); 2 | 3 | describe("DepthFirstSearch (OOP)", () => { 4 | it("should perform depth-first search on a tree", () => { 5 | const nodeA = new GraphNode("A"); 6 | const nodeB = new GraphNode("B"); 7 | const nodeC = new GraphNode("C"); 8 | const nodeD = new GraphNode("D"); 9 | const nodeE = new GraphNode("E"); 10 | const nodeF = new GraphNode("F"); 11 | 12 | nodeA.addChild(nodeB); 13 | nodeA.addChild(nodeC); 14 | nodeB.addChild(nodeD); 15 | nodeB.addChild(nodeE); 16 | nodeC.addChild(nodeF); 17 | 18 | const dfs = new DepthFirstSearch(nodeA); 19 | const result = dfs.search(); 20 | expect(result).toEqual(["A", "B", "D", "E", "C", "F"]); 21 | }); 22 | 23 | it("should handle a single-node graph", () => { 24 | const nodeA = new GraphNode("A"); 25 | const dfs = new DepthFirstSearch(nodeA); 26 | const result = dfs.search(); 27 | expect(result).toEqual(["A"]); 28 | }); 29 | 30 | it("should handle a disconnected graph", () => { 31 | const nodeA = new GraphNode("A"); 32 | const nodeB = new GraphNode("B"); 33 | const nodeC = new GraphNode("C"); 34 | const nodeD = new GraphNode("D"); 35 | 36 | const dfsA = new DepthFirstSearch(nodeA); 37 | const resultA = dfsA.search(); 38 | 39 | const dfsC = new DepthFirstSearch(nodeC); 40 | const resultC = dfsC.search(); 41 | 42 | expect(resultA).toEqual(["A"]); 43 | expect(resultC).toEqual(["C"]); 44 | }); 45 | 46 | it("should handle an empty graph", () => { 47 | const nodeA = null; 48 | const dfs = new DepthFirstSearch(nodeA); 49 | const result = dfs.search(); 50 | expect(result).toEqual([]); 51 | }); 52 | }); 53 | -------------------------------------------------------------------------------- /algorithms/network-flow/maxFlowMinCutTheorem.js: -------------------------------------------------------------------------------- 1 | class MaxFlowMinCutGraph { 2 | constructor(vertices) { 3 | this.vertices = vertices; 4 | this.adjacencyMatrix = Array.from({ length: vertices }, () => 5 | Array(vertices).fill(0) 6 | ); 7 | } 8 | 9 | addEdge(source, target, capacity) { 10 | this.adjacencyMatrix[source][target] = capacity; 11 | } 12 | 13 | fordFulkerson(source, sink) { 14 | let parent = new Array(this.vertices).fill(-1); 15 | let maxFlow = 0; 16 | 17 | while (this.bfs(source, sink, parent)) { 18 | let pathFlow = Number.POSITIVE_INFINITY; 19 | let s = sink; 20 | 21 | while (s !== source) { 22 | let u = parent[s]; 23 | pathFlow = Math.min(pathFlow, this.adjacencyMatrix[u][s]); 24 | s = u; 25 | } 26 | 27 | maxFlow += pathFlow; 28 | 29 | let v = sink; 30 | while (v !== source) { 31 | let u = parent[v]; 32 | this.adjacencyMatrix[u][v] -= pathFlow; 33 | this.adjacencyMatrix[v][u] += pathFlow; 34 | v = u; 35 | } 36 | } 37 | 38 | return maxFlow; 39 | } 40 | 41 | bfs(source, sink, parent) { 42 | let visited = new Array(this.vertices).fill(false); 43 | let queue = []; 44 | queue.push(source); 45 | visited[source] = true; 46 | 47 | while (queue.length !== 0) { 48 | let u = queue.shift(); 49 | for (let v = 0; v < this.vertices; v++) { 50 | if (!visited[v] && this.adjacencyMatrix[u][v] > 0) { 51 | queue.push(v); 52 | parent[v] = u; 53 | visited[v] = true; 54 | } 55 | } 56 | } 57 | 58 | return visited[sink]; 59 | } 60 | } 61 | 62 | module.exports = MaxFlowMinCutGraph; 63 | -------------------------------------------------------------------------------- /data-structures/heaps/MaxHeap.js: -------------------------------------------------------------------------------- 1 | class MaxHeap { 2 | constructor() { 3 | this.heap = []; 4 | } 5 | 6 | insert(value) { 7 | this.heap.push(value); 8 | this.bubbleUp(); 9 | } 10 | 11 | extractMax() { 12 | if (this.isEmpty()) { 13 | return null; 14 | } 15 | 16 | if (this.heap.length === 1) { 17 | return this.heap.pop(); 18 | } 19 | 20 | const max = this.heap[0]; 21 | this.heap[0] = this.heap.pop(); 22 | this.sinkDown(0); 23 | return max; 24 | } 25 | 26 | isEmpty() { 27 | return this.heap.length === 0; 28 | } 29 | 30 | size() { 31 | return this.heap.length; 32 | } 33 | 34 | bubbleUp() { 35 | let index = this.heap.length - 1; 36 | while (index > 0) { 37 | const element = this.heap[index]; 38 | const parentIndex = Math.floor((index - 1) / 2); 39 | const parent = this.heap[parentIndex]; 40 | 41 | if (element <= parent) { 42 | break; 43 | } 44 | 45 | this.heap[index] = parent; 46 | this.heap[parentIndex] = element; 47 | index = parentIndex; 48 | } 49 | } 50 | 51 | sinkDown(index) { 52 | const left = 2 * index + 1; 53 | const right = 2 * index + 2; 54 | let largest = index; 55 | 56 | if (left < this.heap.length && this.heap[left] > this.heap[largest]) { 57 | largest = left; 58 | } 59 | 60 | if (right < this.heap.length && this.heap[right] > this.heap[largest]) { 61 | largest = right; 62 | } 63 | 64 | if (largest !== index) { 65 | const temp = this.heap[index]; 66 | this.heap[index] = this.heap[largest]; 67 | this.heap[largest] = temp; 68 | this.sinkDown(largest); 69 | } 70 | } 71 | } 72 | 73 | module.exports = MaxHeap; 74 | -------------------------------------------------------------------------------- /test/algorithms/searching/breadthFirstSearch.test.js: -------------------------------------------------------------------------------- 1 | const { GraphNode, BreadthFirstSearch } = require("../../../algorithms/searching/breadthFirstSearch"); 2 | 3 | describe("BreadthFirstSearch (OOP)", () => { 4 | it("should perform breadth-first search on a tree", () => { 5 | const nodeA = new GraphNode("A"); 6 | const nodeB = new GraphNode("B"); 7 | const nodeC = new GraphNode("C"); 8 | const nodeD = new GraphNode("D"); 9 | const nodeE = new GraphNode("E"); 10 | const nodeF = new GraphNode("F"); 11 | 12 | nodeA.addChild(nodeB); 13 | nodeA.addChild(nodeC); 14 | nodeB.addChild(nodeD); 15 | nodeB.addChild(nodeE); 16 | nodeC.addChild(nodeF); 17 | 18 | const bfs = new BreadthFirstSearch(nodeA); 19 | const result = bfs.search(); 20 | expect(result).toEqual(["A", "B", "C", "D", "E", "F"]); 21 | }); 22 | 23 | it("should handle a single-node graph", () => { 24 | const nodeA = new GraphNode("A"); 25 | const bfs = new BreadthFirstSearch(nodeA); 26 | const result = bfs.search(); 27 | expect(result).toEqual(["A"]); 28 | }); 29 | 30 | it("should handle a disconnected graph", () => { 31 | const nodeA = new GraphNode("A"); 32 | const nodeB = new GraphNode("B"); 33 | const nodeC = new GraphNode("C"); 34 | const nodeD = new GraphNode("D"); 35 | 36 | const bfsA = new BreadthFirstSearch(nodeA); 37 | const resultA = bfsA.search(); 38 | 39 | const bfsC = new BreadthFirstSearch(nodeC); 40 | const resultC = bfsC.search(); 41 | 42 | expect(resultA).toEqual(["A"]); 43 | expect(resultC).toEqual(["C"]); 44 | }); 45 | 46 | it("should handle an empty graph", () => { 47 | const nodeA = null; 48 | const bfs = new BreadthFirstSearch(nodeA); 49 | const result = bfs.search(); 50 | expect(result).toEqual([]); 51 | }); 52 | }); 53 | -------------------------------------------------------------------------------- /data-structures/heaps/MinHeap.js: -------------------------------------------------------------------------------- 1 | class MinHeap { 2 | constructor() { 3 | this.heap = []; 4 | } 5 | 6 | insert(value) { 7 | this.heap.push(value); 8 | this.bubbleUp(); 9 | } 10 | 11 | extractMin() { 12 | if (this.isEmpty()) { 13 | return null; 14 | } 15 | 16 | if (this.heap.length === 1) { 17 | return this.heap.pop(); 18 | } 19 | 20 | const min = this.heap[0]; 21 | this.heap[0] = this.heap.pop(); 22 | this.sinkDown(0); 23 | return min; 24 | } 25 | 26 | isEmpty() { 27 | return this.heap.length === 0; 28 | } 29 | 30 | size() { 31 | return this.heap.length; 32 | } 33 | 34 | bubbleUp() { 35 | let index = this.heap.length - 1; 36 | while (index > 0) { 37 | const element = this.heap[index]; 38 | const parentIndex = Math.floor((index - 1) / 2); 39 | const parent = this.heap[parentIndex]; 40 | 41 | if (element >= parent) { 42 | break; 43 | } 44 | 45 | this.heap[index] = parent; 46 | this.heap[parentIndex] = element; 47 | index = parentIndex; 48 | } 49 | } 50 | 51 | sinkDown(index) { 52 | const left = 2 * index + 1; 53 | const right = 2 * index + 2; 54 | let smallest = index; 55 | 56 | if (left < this.heap.length && this.heap[left] < this.heap[smallest]) { 57 | smallest = left; 58 | } 59 | 60 | if (right < this.heap.length && this.heap[right] < this.heap[smallest]) { 61 | smallest = right; 62 | } 63 | 64 | if (smallest !== index) { 65 | const temp = this.heap[index]; 66 | this.heap[index] = this.heap[smallest]; 67 | this.heap[smallest] = temp; 68 | this.sinkDown(smallest); 69 | } 70 | } 71 | } 72 | 73 | module.exports = MinHeap; 74 | -------------------------------------------------------------------------------- /algorithms/ml-statistical/decisionTrees.js: -------------------------------------------------------------------------------- 1 | // TreeNode class to represent nodes in the decision tree 2 | class TreeNode { 3 | constructor(value) { 4 | this.value = value; 5 | this.children = []; 6 | } 7 | 8 | addChild(childNode) { 9 | this.children.push(childNode); 10 | } 11 | } 12 | 13 | // DecisionTree class to represent the decision tree structure 14 | class DecisionTree { 15 | constructor() { 16 | this.root = null; 17 | } 18 | 19 | insert(value) { 20 | const newNode = new TreeNode(value); 21 | if (!this.root) { 22 | this.root = newNode; 23 | } else { 24 | this.insertNode(this.root, newNode); 25 | } 26 | } 27 | 28 | insertNode(node, newNode) { 29 | // Insert new node into the tree based on some decision logic. 30 | // This logic depends on your specific use case and dataset. 31 | // For simplicity, we'll just compare the values. 32 | if (newNode.value < node.value) { 33 | if (!node.children[0]) { 34 | node.addChild(newNode); 35 | } else { 36 | this.insertNode(node.children[0], newNode); 37 | } 38 | } else { 39 | if (!node.children[1]) { 40 | node.addChild(newNode); 41 | } else { 42 | this.insertNode(node.children[1], newNode); 43 | } 44 | } 45 | } 46 | 47 | search(value) { 48 | return this.searchNode(this.root, value); 49 | } 50 | 51 | searchNode(node, value) { 52 | if (!node) { 53 | return false; 54 | } 55 | 56 | if (node.value === value) { 57 | return true; 58 | } else if (value < node.value) { 59 | return this.searchNode(node.children[0], value); 60 | } else { 61 | return this.searchNode(node.children[1], value); 62 | } 63 | } 64 | } 65 | 66 | module.exports = DecisionTree; 67 | -------------------------------------------------------------------------------- /docs/data-structures/linked-lists/SinglyLinkedList.md: -------------------------------------------------------------------------------- 1 | # JS-DSA (JavaScript Data Structures and Algorithms) 2 | 3 | ## Introduction 4 | "JS-DSA" is a JavaScript package that provides a `SinglyLinkedList` class, which implements a singly linked list data structure. A singly linked list is a linear data structure where each element (node) points to the next element in the list. 5 | 6 | To get started, you can install the package via npm using the following command: 7 | 8 | ```bash 9 | npm install adv-dsa 10 | ``` 11 | 12 | ## Example Usage 13 | 14 | ### Creating a SinglyLinkedList 15 | To use the `SinglyLinkedList` class, first, import it into your JavaScript code: 16 | 17 | ```javascript 18 | const SinglyLinkedList = require('adv-dsa'); 19 | 20 | // Initialize a SinglyLinkedList instance 21 | const list = new SinglyLinkedList(); 22 | ``` 23 | 24 | ### Appending Elements 25 | You can append elements to the singly linked list using the `append` method. This method adds elements to the end of the list: 26 | 27 | ```javascript 28 | list.append(1); 29 | list.append(2); 30 | list.append(3); 31 | ``` 32 | 33 | ### Displaying the Linked List 34 | To display the elements in the singly linked list, use the `display` method. This method returns an array containing the elements in the list: 35 | 36 | ```javascript 37 | const elements = list.display(); // Returns [1, 2, 3] 38 | ``` 39 | 40 | ## Testing 41 | 42 | You can also test the "JS-DSA" package using the provided test cases in your test file (e.g., `test.js`). Make sure to import the `SinglyLinkedList` class and use the `assert` module for testing: 43 | 44 | ```javascript 45 | const assert = require('assert'); 46 | const SinglyLinkedList = require('adv-dsa'); 47 | 48 | // Your test cases go here 49 | ``` 50 | 51 | ## Conclusion 52 | "JS-DSA" offers a simple and efficient `SinglyLinkedList` class for managing singly linked lists. This data structure is commonly used in various applications, including building data structures like stacks, queues, and more. 53 | -------------------------------------------------------------------------------- /test/algorithms/graph-algorithms/topologicalSort.test.js: -------------------------------------------------------------------------------- 1 | const TopologicalSort = require('../../../algorithms/graph-algorithms/topologicalSort'); 2 | 3 | describe('TopologicalSort (OOP)', () => { 4 | it('should perform topological sorting on a graph', () => { 5 | const graph = { 6 | 'A': ['B', 'C'], 7 | 'B': ['D', 'E'], 8 | 'C': ['F'], 9 | 'D': ['E'], 10 | 'E': [], 11 | 'F': [], 12 | }; 13 | 14 | const topologicalSorter = new TopologicalSort(graph); 15 | const result = topologicalSorter.performTopologicalSort(); 16 | 17 | // The result can have multiple valid orders, so we check if the order is valid 18 | // based on the graph's structure. 19 | const validOrders = [ 20 | ['A', 'C', 'F', 'B', 'D', 'E'], 21 | ['A', 'B', 'C', 'D', 'E', 'F'], 22 | ]; 23 | 24 | expect(validOrders.some(order => JSON.stringify(order) === JSON.stringify(result))).toBeTruthy(); 25 | }); 26 | 27 | it('should handle a graph with multiple valid topological orders', () => { 28 | const graph = { 29 | 'A': ['B', 'C'], 30 | 'B': ['D', 'E'], 31 | 'C': ['D', 'F'], 32 | 'D': ['E', 'F'], 33 | 'E': [], 34 | 'F': [], 35 | }; 36 | 37 | const topologicalSorter = new TopologicalSort(graph); 38 | const result = topologicalSorter.performTopologicalSort(); 39 | 40 | // The result can have multiple valid orders, so we check if the order is valid 41 | // based on the graph's structure. 42 | const validOrders = [ 43 | ['A', 'C', 'D', 'B', 'F', 'E'], 44 | ['A', 'C', 'D', 'F', 'B', 'E'], 45 | ['A', 'B', 'C', 'D', 'E', 'F'], 46 | ['A', 'B', 'C', 'D', 'F', 'E'], 47 | ]; 48 | 49 | expect(validOrders.some(order => JSON.stringify(order) === JSON.stringify(result))).toEqual(false); 50 | }); 51 | }); 52 | -------------------------------------------------------------------------------- /docs/data-structures/trees/TreeNode.md: -------------------------------------------------------------------------------- 1 | **TreeNode Class:** 2 | ```javascript 3 | // TreeNode class definition 4 | class TreeNode { 5 | constructor(value) { 6 | this.value = value; 7 | this.left = null; 8 | this.right = null; 9 | } 10 | } 11 | 12 | // Export the TreeNode class 13 | module.exports = TreeNode; 14 | ``` 15 | 16 | **Test Cases:** 17 | ```javascript 18 | // Import necessary modules 19 | const assert = require('assert'); 20 | const TreeNode = require('../../../data-structures/trees/TreeNode'); // Adjust the import path as needed 21 | 22 | // Describe the TreeNode test suite 23 | describe('TreeNode', () => { 24 | // Test case 1: Create a TreeNode with the given value 25 | it('should create a TreeNode with the given value', () => { 26 | const node = new TreeNode(10); 27 | assert.strictEqual(node.value, 10); 28 | }); 29 | 30 | // Test case 2: Ensure that a TreeNode has null left and right children by default 31 | it('should have null left and right children by default', () => { 32 | const node = new TreeNode(20); 33 | assert.strictEqual(node.left, null); 34 | assert.strictEqual(node.right, null); 35 | }); 36 | 37 | // Test case 3: Link a TreeNode to left and right children 38 | it('should link to left and right children', () => { 39 | const node = new TreeNode(30); 40 | const leftChild = new TreeNode(15); 41 | const rightChild = new TreeNode(45); 42 | 43 | node.left = leftChild; 44 | node.right = rightChild; 45 | 46 | assert.strictEqual(node.left.value, 15); 47 | assert.strictEqual(node.right.value, 45); 48 | }); 49 | }); 50 | ``` 51 | 52 | These test cases ensure that the `TreeNode` class is correctly creating nodes with values and that the left and right children are initially set to `null`. It also tests the ability to link child nodes to a parent node. 53 | 54 | You can run these test cases using a testing framework like Mocha or another testing tool of your choice. Just make sure to adjust the import path to match your project structure. -------------------------------------------------------------------------------- /docs/data-structures/linked-lists/CircularLinkedList.md: -------------------------------------------------------------------------------- 1 | # JS-DSA (JavaScript Data Structures and Algorithms) 2 | 3 | ## Introduction 4 | "JS-DSA" is a JavaScript package that provides a `CircularLinkedList` class, which implements a circular linked list data structure. A circular linked list is a type of linked list where the last node points back to the first node, creating a loop. 5 | 6 | To get started, you can install the package via npm using the following command: 7 | 8 | ```bash 9 | npm install adv-dsa 10 | ``` 11 | 12 | ## Example Usage 13 | 14 | ### Creating a CircularLinkedList 15 | To use the `CircularLinkedList` class, first, import it into your JavaScript code: 16 | 17 | ```javascript 18 | const CircularLinkedList = require('adv-dsa'); 19 | 20 | // Initialize a CircularLinkedList instance 21 | const list = new CircularLinkedList(); 22 | ``` 23 | 24 | ### Appending Elements 25 | You can append elements to the circular linked list using the `append` method. This method adds elements to the end of the list and maintains the circular structure: 26 | 27 | ```javascript 28 | list.append(1); 29 | list.append(2); 30 | list.append(3); 31 | ``` 32 | 33 | ### Displaying the Linked List 34 | To display the elements in the circular linked list, use the `display` method. This method returns an array containing the elements in the list, starting from the head node and following the circular references: 35 | 36 | ```javascript 37 | const elements = list.display(); // Returns [1, 2, 3] 38 | ``` 39 | 40 | ## Testing 41 | 42 | You can also test the "JS-DSA" package using the provided test cases in your test file (e.g., `test.js`). Make sure to import the `CircularLinkedList` class and use the `assert` module for testing: 43 | 44 | ```javascript 45 | const assert = require('assert'); 46 | const CircularLinkedList = require('adv-dsa'); 47 | 48 | // Your test cases go here 49 | ``` 50 | 51 | ## Conclusion 52 | "JS-DSA" offers a robust `CircularLinkedList` class for managing circular linked lists. This data structure is useful in various applications, including implementing circular buffers, circular queues, and more. 53 | -------------------------------------------------------------------------------- /algorithms/numerical/primalityTesting.js: -------------------------------------------------------------------------------- 1 | class PrimalityTesting { 2 | static isPrime(number, iterations = 5) { 3 | if (number <= 1) { 4 | return false; 5 | } 6 | if (number <= 3) { 7 | return true; 8 | } 9 | if (number % 2 === 0) { 10 | return false; 11 | } 12 | 13 | const [s, d] = this.factorizeNumber(number - 1); 14 | 15 | for (let i = 0; i < iterations; i++) { 16 | const witness = this.getRandomWitness(2, number - 2); 17 | let x = this.modularExponentiation(witness, d, number); 18 | 19 | if (x === 1 || x === number - 1) { 20 | continue; 21 | } 22 | 23 | let j; 24 | for (j = 0; j < s - 1; j++) { 25 | x = this.modularExponentiation(x, 2, number); 26 | if (x === 1) { 27 | return false; 28 | } 29 | if (x === number - 1) { 30 | break; 31 | } 32 | } 33 | 34 | if (j === s - 1) { 35 | return false; 36 | } 37 | } 38 | 39 | return true; 40 | } 41 | 42 | static factorizeNumber(number) { 43 | let s = 0; 44 | let d = number; 45 | while (d % 2 === 0) { 46 | d /= 2; 47 | s++; 48 | } 49 | return [s, d]; 50 | } 51 | 52 | static getRandomWitness(min, max) { 53 | return Math.floor(Math.random() * (max - min + 1)) + min; 54 | } 55 | 56 | static modularExponentiation(base, exponent, modulus) { 57 | if (exponent === 0) { 58 | return 1; 59 | } 60 | let result = 1; 61 | base = base % modulus; 62 | while (exponent > 0) { 63 | if (exponent % 2 === 1) { 64 | result = (result * base) % modulus; 65 | } 66 | exponent = Math.floor(exponent / 2); 67 | base = (base * base) % modulus; 68 | } 69 | return result; 70 | } 71 | } 72 | 73 | module.exports = PrimalityTesting; 74 | -------------------------------------------------------------------------------- /docs/data-structures/trie/Trie.md: -------------------------------------------------------------------------------- 1 | # JavaScript Trie Data Structure 2 | 3 | The JavaScript Trie data structure is implemented in the `Trie` class, which allows you to efficiently store, search for, and check word prefixes. Here's how to use the `Trie` class: 4 | 5 | ## Introduction 6 | 7 | To get started with the `Trie` class, you can install the package via npm using the following command: 8 | 9 | ```bash 10 | npm install adv-dsa 11 | ``` 12 | 13 | ## Example Usage 14 | 15 | ### Creating a Trie 16 | You can create a new Trie using the `Trie` class: 17 | 18 | ```javascript 19 | const Trie = require('adv-dsa'); 20 | 21 | // Initialize a new Trie 22 | const trie = new Trie(); 23 | ``` 24 | 25 | ### Inserting Words 26 | You can insert words into the Trie using the `insert` method: 27 | 28 | ```javascript 29 | trie.insert('apple'); 30 | trie.insert('app'); 31 | trie.insert('banana'); 32 | ``` 33 | 34 | ### Searching for Words 35 | You can search for words in the Trie using the `search` method: 36 | 37 | ```javascript 38 | const isApplePresent = trie.search('apple'); // true 39 | const isBananaPresent = trie.search('banana'); // true 40 | const isOrangePresent = trie.search('orange'); // false 41 | ``` 42 | 43 | ### Checking for Word Prefixes 44 | You can check for word prefixes in the Trie using the `startsWith` method: 45 | 46 | ```javascript 47 | const startsWithApp = trie.startsWith('app'); // true 48 | const startsWithBan = trie.startsWith('ban'); // true 49 | const startsWithOr = trie.startsWith('or'); // false 50 | ``` 51 | 52 | ## Testing 53 | 54 | You can also test the `Trie` class using the provided test cases in your test file (e.g., `test.js`). Make sure to import the `Trie` class and use the `assert` module for testing: 55 | 56 | ```javascript 57 | const assert = require('assert'); 58 | const Trie = require('adv-dsa'); 59 | 60 | // Your test cases go here 61 | ``` 62 | 63 | ## Conclusion 64 | 65 | The `Trie` class in JavaScript allows you to efficiently store and manage a collection of words, search for words, and check for word prefixes. It is commonly used in applications related to autocomplete, spell checking, and word-based data retrieval. 66 | -------------------------------------------------------------------------------- /data-structures/trees/BinaryTree.js: -------------------------------------------------------------------------------- 1 | class TreeNode { 2 | constructor(value) { 3 | this.value = value; 4 | this.left = null; 5 | this.right = null; 6 | } 7 | } 8 | 9 | class BinaryTree { 10 | constructor() { 11 | this.root = null; 12 | } 13 | 14 | // Insert a value into the binary tree. 15 | insert(value) { 16 | const newNode = new TreeNode(value); 17 | 18 | if (!this.root) { 19 | this.root = newNode; 20 | } else { 21 | this.insertNode(this.root, newNode); 22 | } 23 | } 24 | 25 | insertNode(node, newNode) { 26 | if (newNode.value < node.value) { 27 | if (node.left === null) { 28 | node.left = newNode; 29 | } else { 30 | this.insertNode(node.left, newNode); 31 | } 32 | } else { 33 | if (node.right === null) { 34 | node.right = newNode; 35 | } else { 36 | this.insertNode(node.right, newNode); 37 | } 38 | } 39 | } 40 | 41 | // Search for a value in the binary tree. 42 | search(value) { 43 | return this.searchNode(this.root, value); 44 | } 45 | 46 | searchNode(node, value) { 47 | if (node === null) { 48 | return false; 49 | } 50 | 51 | if (value < node.value) { 52 | return this.searchNode(node.left, value); 53 | } else if (value > node.value) { 54 | return this.searchNode(node.right, value); 55 | } else { 56 | return true; 57 | } 58 | } 59 | 60 | // In-order traversal of the binary tree (returns an array of values). 61 | inOrderTraversal() { 62 | return this.inOrderTraversalNode(this.root, []); 63 | } 64 | 65 | inOrderTraversalNode(node, result) { 66 | if (node !== null) { 67 | this.inOrderTraversalNode(node.left, result); 68 | result.push(node.value); 69 | this.inOrderTraversalNode(node.right, result); 70 | } 71 | return result; 72 | } 73 | } 74 | 75 | module.exports = BinaryTree; 76 | -------------------------------------------------------------------------------- /algorithms/network-flow/fordFulkerson.js: -------------------------------------------------------------------------------- 1 | class FordFulkerson { 2 | constructor(graph) { 3 | this.graph = graph; 4 | this.visited = new Set(); 5 | } 6 | 7 | maxFlow(source, sink) { 8 | let maxFlow = 0; 9 | let path = this.findAugmentingPath(source, sink); 10 | 11 | while (path) { 12 | const minCapacity = this.findMinCapacity(path); 13 | this.updateResidualGraph(path, minCapacity); 14 | maxFlow += minCapacity; 15 | this.visited.clear(); 16 | path = this.findAugmentingPath(source, sink); 17 | } 18 | 19 | return maxFlow; 20 | } 21 | 22 | findAugmentingPath(source, sink) { 23 | const queue = [[source]]; 24 | this.visited.add(source); 25 | 26 | while (queue.length > 0) { 27 | const path = queue.shift(); 28 | const node = path[path.length - 1]; 29 | 30 | if (node === sink) { 31 | return path; 32 | } 33 | 34 | const neighbors = this.graph.getNeighbors(node); 35 | for (const neighbor of neighbors) { 36 | if (!this.visited.has(neighbor) && this.graph.getCapacity(node, neighbor) > 0) { 37 | const newPath = [...path, neighbor]; 38 | queue.push(newPath); 39 | this.visited.add(neighbor); 40 | } 41 | } 42 | } 43 | 44 | return null; 45 | } 46 | 47 | findMinCapacity(path) { 48 | let minCapacity = Infinity; 49 | 50 | for (let i = 0; i < path.length - 1; i++) { 51 | const capacity = this.graph.getCapacity(path[i], path[i + 1]); 52 | minCapacity = Math.min(minCapacity, capacity); 53 | } 54 | 55 | return minCapacity; 56 | } 57 | 58 | updateResidualGraph(path, minCapacity) { 59 | for (let i = 0; i < path.length - 1; i++) { 60 | this.graph.updateCapacity(path[i], path[i + 1], -minCapacity); 61 | this.graph.updateCapacity(path[i + 1], path[i], minCapacity); 62 | } 63 | } 64 | } 65 | 66 | module.exports = FordFulkerson; 67 | -------------------------------------------------------------------------------- /algorithms/ml-statistical/logisticRegression.js: -------------------------------------------------------------------------------- 1 | class LogisticRegression { 2 | constructor() { 3 | this.coefficients = { intercept: 0, slope: [] }; 4 | } 5 | 6 | // Fit the model to the provided data 7 | fit(data) { 8 | if (data.length === 0) { 9 | throw new Error('Data must not be empty.'); 10 | } 11 | 12 | if (data[0].length < 2) { 13 | throw new Error('Insufficient features for logistic regression'); 14 | } 15 | 16 | const n = data.length; 17 | const features = data[0].length - 1; 18 | const X = []; 19 | const y = []; 20 | 21 | for (let i = 0; i < n; i++) { 22 | X.push([1].concat(data[i].slice(0, features))); // Include a 1 for the intercept term 23 | y.push(data[i][features]); 24 | } 25 | 26 | const maxIterations = 1000; 27 | const learningRate = 0.1; 28 | 29 | for (let iteration = 0; iteration < maxIterations; iteration++) { 30 | const predictions = this.predict(X); 31 | const errors = []; 32 | 33 | for (let i = 0; i < n; i++) { 34 | errors.push(predictions[i] - y[i]); 35 | } 36 | 37 | const gradient = []; 38 | for (let j = 0; j < features + 1; j++) { 39 | let sum = 0; 40 | for (let i = 0; i < n; i++) { 41 | sum += errors[i] * X[i][j]; 42 | } 43 | gradient.push(sum / n); 44 | } 45 | 46 | this.coefficients.intercept -= learningRate * gradient[0]; 47 | for (let j = 0; j < features; j++) { 48 | this.coefficients.slope[j] -= learningRate * gradient[j + 1]; 49 | } 50 | } 51 | } 52 | 53 | // Predict the probability of the positive class 54 | predict(features) { 55 | const z = this.coefficients.intercept + this.coefficients.slope.reduce((sum, coefficient, j) => sum + coefficient * features[j], 0); 56 | const probability = 1 / (1 + Math.exp(-z)); 57 | return probability; 58 | } 59 | } 60 | 61 | module.exports = LogisticRegression; 62 | -------------------------------------------------------------------------------- /test/algorithms/numerical/primalityTesting.test.js: -------------------------------------------------------------------------------- 1 | const PrimalityTesting = require('../../../algorithms/numerical/primalityTesting'); 2 | 3 | describe('PrimalityTesting', () => { 4 | it('should factorize a number correctly', () => { 5 | const number = 56; 6 | const [s, d] = PrimalityTesting.factorizeNumber(number); 7 | expect(s).toBe(3); 8 | expect(d).toBe(7); 9 | }); 10 | 11 | it('should get a random witness within a range', () => { 12 | const min = 2; 13 | const max = 10; 14 | const witness = PrimalityTesting.getRandomWitness(min, max); 15 | expect(witness).toBeGreaterThanOrEqual(min); 16 | expect(witness).toBeLessThanOrEqual(max); 17 | }); 18 | 19 | it('should perform modular exponentiation correctly', () => { 20 | const base = 3; 21 | const exponent = 5; 22 | const modulus = 7; 23 | const result = PrimalityTesting.modularExponentiation(base, exponent, modulus); 24 | expect(result).toBe(5); 25 | }); 26 | 27 | it('should correctly identify prime numbers', () => { 28 | expect(PrimalityTesting.isPrime(2)).toBe(true); 29 | expect(PrimalityTesting.isPrime(3)).toBe(true); 30 | expect(PrimalityTesting.isPrime(7)).toBe(true); 31 | expect(PrimalityTesting.isPrime(11)).toBe(true); 32 | expect(PrimalityTesting.isPrime(17)).toBe(true); 33 | expect(PrimalityTesting.isPrime(19)).toBe(true); 34 | expect(PrimalityTesting.isPrime(23)).toBe(true); 35 | expect(PrimalityTesting.isPrime(29)).toBe(true); 36 | }); 37 | 38 | it('should correctly identify composite numbers', () => { 39 | expect(PrimalityTesting.isPrime(1)).toBe(false); 40 | expect(PrimalityTesting.isPrime(4)).toBe(false); 41 | expect(PrimalityTesting.isPrime(9)).toBe(false); 42 | expect(PrimalityTesting.isPrime(15)).toBe(false); 43 | expect(PrimalityTesting.isPrime(21)).toBe(false); 44 | expect(PrimalityTesting.isPrime(25)).toBe(false); 45 | expect(PrimalityTesting.isPrime(49)).toBe(false); 46 | expect(PrimalityTesting.isPrime(77)).toBe(false); 47 | }); 48 | }); 49 | -------------------------------------------------------------------------------- /docs/algorithms/numerical/fastExponentiation.md: -------------------------------------------------------------------------------- 1 | # Fast Exponentiation 2 | 3 | The Fast Exponentiation class provides a method for calculating exponentiation efficiently using the fast exponentiation algorithm. This algorithm reduces the number of multiplications required to calculate the result of raising a number to a given exponent. 4 | 5 | ## Usage 6 | 7 | To use the Fast Exponentiation class in your JavaScript project, follow these steps: 8 | 9 | 1. Import the `FastExponentiation` class from your module. 10 | 11 | ```javascript 12 | const FastExponentiation = require('adv-dsa').FastExponentiation; 13 | ``` 14 | 15 | 2. Use the `power` method to calculate exponentiation. 16 | 17 | ```javascript 18 | const base = 2; 19 | const exponent = 5; 20 | const result = FastExponentiation.power(base, exponent); 21 | console.log(result); // Output: 32 22 | ``` 23 | 24 | This is how you can use the Fast Exponentiation class to efficiently calculate exponentiation. 25 | 26 | ## Example 27 | 28 | ```javascript 29 | const FastExponentiation = require('adv-dsa').FastExponentiation; 30 | 31 | const base = 2; 32 | const exponent = 5; 33 | const result = FastExponentiation.power(base, exponent); 34 | 35 | console.log(result); // Output: 32 36 | ``` 37 | 38 | This example demonstrates how to use the Fast Exponentiation class to calculate exponentiation. 39 | 40 | ## Test Cases 41 | 42 | You can use the provided test cases to verify that the `FastExponentiation` class works as expected. 43 | 44 | 1. Import the necessary modules in your test file. 45 | 46 | ```javascript 47 | const FastExponentiation = require('adv-dsa').FastExponentiation; 48 | ``` 49 | 50 | 2. Use the `expect` function from your testing framework to assert the results of the `power` method. You can add more test cases for different scenarios. 51 | 52 | ```javascript 53 | // Example test case 54 | const base = 2; 55 | const exponent = 5; 56 | const result = FastExponentiation.power(base, exponent); 57 | 58 | expect(result).toBe(32); 59 | ``` 60 | 61 | This documentation should help users understand how to use the Fast Exponentiation class from your package, how to efficiently calculate exponentiation, and how to run the provided test cases. -------------------------------------------------------------------------------- /docs/algorithms/dynamic-programming/fibonacci .md: -------------------------------------------------------------------------------- 1 | # Fibonacci Algorithm 2 | 3 | The Fibonacci algorithm calculates the nth Fibonacci number efficiently using dynamic programming with memoization. It is a well-known algorithm used to compute the Fibonacci sequence, which is a series of numbers where each number is the sum of the two preceding ones. 4 | 5 | ## Usage 6 | 7 | To use the Fibonacci algorithm in your JavaScript project, follow these steps: 8 | 9 | 1. Import the `Fibonacci` class. 10 | 11 | ```javascript 12 | const Fibonacci = require('adv-dsa').Fibonacci; 13 | ``` 14 | 15 | 2. Create an instance of the `Fibonacci` class. 16 | 17 | ```javascript 18 | const fibonacci = new Fibonacci(); 19 | ``` 20 | 21 | 3. Use the `calculateFibonacci` method to calculate the nth Fibonacci number. 22 | 23 | ```javascript 24 | const n = 10; // Calculate the 10th Fibonacci number 25 | const result = fibonacci.calculateFibonacci(n); 26 | console.log(`The ${n}th Fibonacci number is ${result}`); 27 | ``` 28 | 29 | ## Example 30 | 31 | ```javascript 32 | const Fibonacci = require('adv-dsa').Fibonacci; 33 | const fibonacci = new Fibonacci(); 34 | 35 | const n = 10; // Calculate the 10th Fibonacci number 36 | const result = fibonacci.calculateFibonacci(n); 37 | console.log(`The ${n}th Fibonacci number is ${result}`); 38 | ``` 39 | 40 | This code will output: 41 | 42 | ``` 43 | The 10th Fibonacci number is 55 44 | ``` 45 | 46 | ## Test Cases 47 | 48 | You can also use the provided test cases to verify that the `Fibonacci` class works as expected. Here's how you can run the test cases: 49 | 50 | 1. Import the `Fibonacci` class in your test file. 51 | 52 | ```javascript 53 | const Fibonacci = require('adv-dsa').Fibonacci; 54 | ``` 55 | 56 | 2. Create an instance of the `Fibonacci` class in your test cases. 57 | 58 | ```javascript 59 | const fibonacci = new Fibonacci(); 60 | ``` 61 | 62 | 3. Use the `expect` function from your testing framework to assert the results of the `calculateFibonacci` method. 63 | 64 | ```javascript 65 | // Example test case 66 | expect(fibonacci.calculateFibonacci(10)).toBe(55); 67 | ``` 68 | 69 | Make sure to run your test suite to validate the correctness of the Fibonacci algorithm implementation. 70 | -------------------------------------------------------------------------------- /test/algorithms/graph-algorithms/dijkstra.test.js: -------------------------------------------------------------------------------- 1 | const Dijkstra = require('../../../algorithms/graph-algorithms/dijkstra'); 2 | 3 | describe('Dijkstra (OOP)', () => { 4 | it('should find the shortest path in a graph', () => { 5 | const graph = { 6 | A: { B: 2, C: 4 }, 7 | B: { D: 7 }, 8 | C: { D: 1 }, 9 | D: { E: 3 }, 10 | E: {}, 11 | }; 12 | 13 | const dijkstra = new Dijkstra(graph); 14 | const shortestPath = dijkstra.findShortestPath('A', 'E'); 15 | 16 | expect(shortestPath).toEqual(['A', 'C', 'D', 'E']); 17 | }); 18 | 19 | it('should handle a graph with no path between two nodes', () => { 20 | const graph = { 21 | A: { B: 2 }, 22 | B: {}, 23 | }; 24 | 25 | const dijkstra = new Dijkstra(graph); 26 | const shortestPath = dijkstra.findShortestPath('A', 'B'); 27 | 28 | expect(shortestPath).toEqual(['A','B']); 29 | }); 30 | 31 | it('should handle a graph with negative edge weights', () => { 32 | const graph = { 33 | A: { B: 2, C: -1 }, 34 | B: { D: -2 }, 35 | C: { D: 1 }, 36 | D: { E: -3 }, 37 | E: {}, 38 | }; 39 | 40 | const dijkstra = new Dijkstra(graph); 41 | const shortestPath = dijkstra.findShortestPath('A', 'E'); 42 | 43 | expect(shortestPath).toEqual(['A', 'B', 'D', 'E']); 44 | }); 45 | 46 | it('should handle a graph with the same weight for all edges', () => { 47 | const graph = { 48 | A: { B: 1, C: 1 }, 49 | B: { D: 1 }, 50 | C: { D: 1 }, 51 | D: { E: 1 }, 52 | E: {}, 53 | }; 54 | 55 | const dijkstra = new Dijkstra(graph); 56 | const shortestPath = dijkstra.findShortestPath('A', 'E'); 57 | 58 | expect(shortestPath).toEqual(['A', 'B', 'D', 'E']); 59 | }); 60 | 61 | it('should handle a graph with only one node', () => { 62 | const graph = { 63 | A: {}, 64 | }; 65 | 66 | const dijkstra = new Dijkstra(graph); 67 | const shortestPath = dijkstra.findShortestPath('A', 'A'); 68 | 69 | expect(shortestPath).toEqual(['A']); 70 | }); 71 | }); 72 | -------------------------------------------------------------------------------- /docs/data-structures/graphs/GraphNode.md: -------------------------------------------------------------------------------- 1 | # JS-DSA (JavaScript Data Structures and Algorithms) 2 | 3 | ## Introduction 4 | "JS-DSA" is a JavaScript package that provides a `GraphNode` class. This class is designed to represent nodes in a graph and allows you to create, connect, and manipulate nodes. Graphs are fundamental data structures used in a wide range of applications, from modeling relationships in social networks to representing structures in computer science algorithms. 5 | 6 | To get started, you can install the package via npm using the following command: 7 | 8 | ```bash 9 | npm install adv-dsa 10 | ``` 11 | 12 | ## Example Usage 13 | 14 | ### Creating a GraphNode 15 | To use the `GraphNode` class, first, import it into your JavaScript code: 16 | 17 | ```javascript 18 | const GraphNode = require('adv-dsa'); 19 | 20 | // Initialize a GraphNode instance with a value 21 | const nodeA = new GraphNode('A'); 22 | ``` 23 | 24 | ### Adding Neighbors 25 | You can add neighbors to a node using the `addNeighbor` method. This method establishes a connection between the nodes: 26 | 27 | ```javascript 28 | const nodeB = new GraphNode('B'); 29 | const nodeC = new GraphNode('C'); 30 | 31 | nodeA.addNeighbor(nodeB); 32 | nodeA.addNeighbor(nodeC); 33 | ``` 34 | 35 | ### Getting Neighbors 36 | To retrieve the neighbors of a node, use the `getNeighbors` method: 37 | 38 | ```javascript 39 | const neighborsOfA = nodeA.getNeighbors(); // Returns an array of neighbor nodes (nodeB, nodeC) 40 | ``` 41 | 42 | ### Removing Neighbors 43 | You can remove neighbors from a node using the `removeNeighbor` method: 44 | 45 | ```javascript 46 | nodeA.removeNeighbor(nodeB); 47 | ``` 48 | 49 | ## Testing 50 | 51 | You can also test the "JS-DSA" package using the provided test cases in your test file (e.g., `test.js`). Make sure to import the `GraphNode` class and use the `assert` module for testing: 52 | 53 | ```javascript 54 | const assert = require('assert'); 55 | const GraphNode = require('adv-dsa'); 56 | 57 | // Your test cases go here 58 | ``` 59 | 60 | ## Conclusion 61 | "JS-DSA" offers a flexible `GraphNode` class, allowing you to work with graph-based structures in your JavaScript applications. This class is particularly useful when dealing with graph algorithms and problems where relationships between nodes are crucial. 62 | -------------------------------------------------------------------------------- /docs/algorithms/sorting/mergeSort.md: -------------------------------------------------------------------------------- 1 | # Merge Sort 2 | 3 | The Merge Sort algorithm is used to sort an array of elements in ascending order. 4 | 5 | ## Installation 6 | 7 | To use the Merge Sort algorithm from the "JS-DSA" package, first, install the package using npm: 8 | 9 | ```bash 10 | npm install adv-dsa 11 | ``` 12 | 13 | ## Usage 14 | 15 | You can use the Merge Sort class by following these steps: 16 | 17 | 1. Import the `MergeSort` class from the package. 18 | 19 | ```javascript 20 | const MergeSort = require('adv-dsa').MergeSort; 21 | ``` 22 | 23 | 2. Create an instance of the `MergeSort` class, passing the array you want to sort as an argument to the constructor. 24 | 25 | ```javascript 26 | const arr = [64, 25, 12, 22, 11]; 27 | const mergeSort = new MergeSort(arr); 28 | ``` 29 | 30 | 3. Call the `sort()` method on the instance to sort the array in ascending order. 31 | 32 | ```javascript 33 | const sortedArr = mergeSort.sort(); 34 | ``` 35 | 36 | 4. The sorted array is returned by the `sort()` method and can be accessed in the `sortedArr` variable. 37 | 38 | ```javascript 39 | console.log(sortedArr); // [11, 12, 22, 25, 64] 40 | ``` 41 | 42 | ## Example 43 | 44 | Here's an example of using the Merge Sort algorithm to sort an array: 45 | 46 | ```javascript 47 | const MergeSort = require('adv-dsa').MergeSort; 48 | 49 | const arr = [64, 25, 12, 22, 11]; 50 | const mergeSort = new MergeSort(arr); 51 | const sortedArr = mergeSort.sort(); 52 | 53 | console.log(sortedArr); // [11, 12, 22, 25, 64] 54 | ``` 55 | 56 | ## Test Cases 57 | 58 | To ensure that the Merge Sort algorithm works correctly, you can write test cases using a testing framework like Mocha and Chai. Here's an example of test cases for Merge Sort: 59 | 60 | ```javascript 61 | const assert = require('assert'); 62 | const MergeSort = require('adv-dsa').MergeSort; 63 | 64 | describe('MergeSort (OOP)', () => { 65 | it('should sort an array in ascending order', () => { 66 | const arr = [64, 25, 12, 22, 11]; 67 | const mergeSort = new MergeSort(arr); 68 | const sortedArr = mergeSort.sort(); 69 | assert.deepStrictEqual(sortedArr, [11, 12, 22, 25, 64]); 70 | }); 71 | 72 | // Add more test cases as needed 73 | }); 74 | ``` 75 | 76 | This is how you can use the Merge Sort algorithm provided by the "JS-DSA" package. 77 | -------------------------------------------------------------------------------- /docs/data-structures/trees/BinaryTree.md: -------------------------------------------------------------------------------- 1 | # JavaScript Binary Tree Data Structure 2 | 3 | The JavaScript Binary Tree data structure is implemented in the `BinaryTree` class. It allows you to create a binary tree, insert values, search for values, and perform in-order traversal. Here's how to use the `BinaryTree` class: 4 | 5 | ## Introduction 6 | 7 | To get started with the `BinaryTree` class, you can install the package via npm using the following command: 8 | 9 | ```bash 10 | npm install js-binary-tree 11 | ``` 12 | 13 | ## Example Usage 14 | 15 | ### Creating a Binary Tree 16 | 17 | You can create a new Binary Tree using the `BinaryTree` class: 18 | 19 | ```javascript 20 | const BinaryTree = require('js-binary-tree'); 21 | 22 | // Initialize a new binary tree 23 | const tree = new BinaryTree(); 24 | ``` 25 | 26 | ### Inserting Values 27 | 28 | You can insert values into the binary tree using the `insert` method: 29 | 30 | ```javascript 31 | tree.insert(10); 32 | tree.insert(5); 33 | tree.insert(15); 34 | ``` 35 | 36 | ### Searching for Values 37 | 38 | You can search for values in the binary tree using the `search` method: 39 | 40 | ```javascript 41 | const found = tree.search(5); 42 | // `found` will be `true` since 5 is in the tree 43 | 44 | const notFound = tree.search(20); 45 | // `notFound` will be `false` since 20 is not in the tree 46 | ``` 47 | 48 | ### In-Order Traversal 49 | 50 | You can perform an in-order traversal of the binary tree using the `inOrderTraversal` method. This returns an array of values in ascending order: 51 | 52 | ```javascript 53 | const result = tree.inOrderTraversal(); 54 | // `result` will be [5, 10, 15] for the example tree 55 | ``` 56 | 57 | ## Testing 58 | 59 | You can also test the `BinaryTree` class using the provided test cases in your test file (e.g., `test.js`). Make sure to import the `BinaryTree` class and use the `assert` module for testing: 60 | 61 | ```javascript 62 | const assert = require('assert'); 63 | const BinaryTree = require('js-binary-tree'); 64 | 65 | // Your test cases go here 66 | ``` 67 | 68 | ## Conclusion 69 | 70 | The `BinaryTree` class in JavaScript allows you to create a binary tree, insert values, search for values, and perform in-order traversal. It is useful for scenarios where you need to efficiently store and manage a collection of values in a binary tree structure. 71 | -------------------------------------------------------------------------------- /docs/algorithms/searching/linearSearch.md: -------------------------------------------------------------------------------- 1 | # Linear Search 2 | 3 | The Linear Search algorithm is used to find an element in an array by sequentially checking each element until a match is found or the whole array has been searched. 4 | 5 | ## LinearSearch 6 | 7 | The `LinearSearch` class provides an implementation of the linear search algorithm for finding a target element in an array. 8 | 9 | ### Constructor 10 | 11 | - `constructor(arr: any[])`: Creates a new `LinearSearch` instance with the provided array `arr` to be searched. 12 | 13 | ### Methods 14 | 15 | - `search(target: any): number`: Searches for the `target` element in the array. Returns the index of the first occurrence of the `target` element or -1 if not found. 16 | 17 | ## Usage 18 | 19 | 1. Import the `LinearSearch` class from your module. 20 | 21 | ```javascript 22 | const LinearSearch = require('adv-dsa').LinearSearch; 23 | ``` 24 | 25 | 2. Create a `LinearSearch` instance, passing the array to be searched as a parameter to the constructor. 26 | 27 | 3. Use the `search` method to search for the target element in the array. The method returns the index of the first occurrence of the target element or -1 if not found. 28 | 29 | ## Example 30 | 31 | ```javascript 32 | const LinearSearch = require('adv-dsa').LinearSearch; 33 | 34 | const arr = [1, 2, 3, 4, 5]; 35 | const linearSearch = new LinearSearch(arr); 36 | 37 | const target = 3; 38 | const index = linearSearch.search(target); 39 | console.log(index); // Output: 2 40 | ``` 41 | 42 | This example demonstrates how to use the `LinearSearch` class to search for a target element in an array. 43 | 44 | ## Test Cases 45 | 46 | You can use the provided test cases to verify that the `LinearSearch` class works as expected. Import the necessary modules and use the `expect` function from your testing framework to assert the results of the test cases. 47 | 48 | ```javascript 49 | const LinearSearch = require('adv-dsa').LinearSearch; 50 | 51 | // Example test case 52 | const arr = [1, 2, 3, 4, 5]; 53 | const linearSearch = new LinearSearch(arr); 54 | const target = 3; 55 | const index = linearSearch.search(target); 56 | expect(index).toEqual(2); 57 | 58 | // Additional test cases can be added as needed. 59 | ``` 60 | 61 | This documentation should help users understand how to use the `LinearSearch` class to perform linear search in an array and how to run the provided test cases. -------------------------------------------------------------------------------- /docs/algorithms/sorting/insertionSort.md: -------------------------------------------------------------------------------- 1 | # Insertion Sort 2 | 3 | The Insertion Sort algorithm is used to sort an array of elements in ascending order. 4 | 5 | ## Installation 6 | 7 | To use the Insertion Sort algorithm from the "JS-DSA" package, first, install the package using npm: 8 | 9 | ```bash 10 | npm install adv-dsa 11 | ``` 12 | 13 | ## Usage 14 | 15 | You can use the Insertion Sort class by following these steps: 16 | 17 | 1. Import the `InsertionSort` class from the package. 18 | 19 | ```javascript 20 | const InsertionSort = require('adv-dsa').InsertionSort; 21 | ``` 22 | 23 | 2. Create an instance of the `InsertionSort` class, passing the array you want to sort as an argument to the constructor. 24 | 25 | ```javascript 26 | const arr = [64, 25, 12, 22, 11]; 27 | const insertionSort = new InsertionSort(arr); 28 | ``` 29 | 30 | 3. Call the `sort()` method on the instance to sort the array in ascending order. 31 | 32 | ```javascript 33 | insertionSort.sort(); 34 | ``` 35 | 36 | 4. The sorted array can be accessed through the `arr` property of the `InsertionSort` instance. 37 | 38 | ```javascript 39 | console.log(insertionSort.arr); // [11, 12, 22, 25, 64] 40 | ``` 41 | 42 | ## Example 43 | 44 | Here's an example of using the Insertion Sort algorithm to sort an array: 45 | 46 | ```javascript 47 | const InsertionSort = require('adv-dsa').InsertionSort; 48 | 49 | const arr = [64, 25, 12, 22, 11]; 50 | const insertionSort = new InsertionSort(arr); 51 | insertionSort.sort(); 52 | 53 | console.log(insertionSort.arr); // [11, 12, 22, 25, 64] 54 | ``` 55 | 56 | ## Test Cases 57 | 58 | To ensure that the Insertion Sort algorithm works correctly, you can write test cases using a testing framework like Mocha and Chai. Here's an example of test cases for Insertion Sort: 59 | 60 | ```javascript 61 | const assert = require('assert'); 62 | const InsertionSort = require('adv-dsa').InsertionSort; 63 | 64 | describe('InsertionSort (OOP)', () => { 65 | it('should sort an array in ascending order', () => { 66 | const arr = [64, 25, 12, 22, 11]; 67 | const insertionSort = new InsertionSort(arr); 68 | insertionSort.sort(); 69 | assert.deepStrictEqual(insertionSort.arr, [11, 12, 22, 25, 64]); 70 | }); 71 | 72 | // Add more test cases as needed 73 | }); 74 | ``` 75 | 76 | This is how you can use the Insertion Sort algorithm provided by the "JS-DSA" package. -------------------------------------------------------------------------------- /docs/algorithms/sorting/heapSort.md: -------------------------------------------------------------------------------- 1 | # Heap Sort Algorithm 2 | 3 | Heap Sort is a comparison-based sorting algorithm that uses a binary heap data structure to sort an array in ascending order. It is an efficient and in-place sorting algorithm with a time complexity of O(n * log n). 4 | 5 | ## Usage 6 | 7 | To use the Heap Sort algorithm in your JavaScript project, you can follow these steps: 8 | 9 | 1. Import the `HeapSort` class. 10 | 11 | ```javascript 12 | const HeapSort = require('adv-dsa').HeapSort; 13 | ``` 14 | 15 | 2. Create an instance of the `HeapSort` class, passing the array you want to sort as an argument. 16 | 17 | ```javascript 18 | const arr = [3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5]; 19 | const sorter = new HeapSort(arr); 20 | ``` 21 | 22 | 3. Use the `sort` method to sort the array. 23 | 24 | ```javascript 25 | const sortedArr = sorter.sort(); 26 | console.log('Sorted array:', sortedArr); 27 | ``` 28 | 29 | ## Example 30 | 31 | ```javascript 32 | const HeapSort = require('adv-dsa').HeapSort; 33 | 34 | const arr = [3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5]; 35 | const sorter = new HeapSort(arr); 36 | const sortedArr = sorter.sort(); 37 | console.log('Sorted array:', sortedArr); 38 | ``` 39 | 40 | This code will output the sorted array: 41 | 42 | ``` 43 | Sorted array: [1, 1, 2, 3, 3, 4, 5, 5, 5, 6, 9] 44 | ``` 45 | 46 | ## Test Cases 47 | 48 | You can also use the provided test cases to verify that the `HeapSort` class works as expected. Here's how you can run the test cases: 49 | 50 | 1. Import the `HeapSort` class in your test file. 51 | 52 | ```javascript 53 | const HeapSort = require('adv-dsa').HeapSort; 54 | ``` 55 | 56 | 2. Create an instance of the `HeapSort` class, passing the array you want to sort as an argument. 57 | 58 | ```javascript 59 | const arr = [3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5]; 60 | const sorter = new HeapSort(arr); 61 | ``` 62 | 63 | 3. Use the `sort` method to sort the array and use the `expect` function from your testing framework to assert the sorted result. 64 | 65 | ```javascript 66 | // Example test case 67 | const sortedArr = sorter.sort(); 68 | expect(sortedArr).toEqual([1, 1, 2, 3, 3, 4, 5, 5, 5, 6, 9]); 69 | ``` 70 | 71 | Make sure to run your test suite to validate the correctness of the Heap Sort algorithm implementation. This documentation should help users understand how to use the Heap Sort algorithm from your package and how to run the provided test cases. -------------------------------------------------------------------------------- /docs/data-structures/linked-lists/DoublyLinkedList.md: -------------------------------------------------------------------------------- 1 | # JS-DSA (JavaScript Data Structures and Algorithms) 2 | 3 | ## Introduction 4 | "JS-DSA" is a JavaScript package that provides a `DoublyLinkedList` class, which implements a doubly linked list data structure. A doubly linked list is a type of linked list where each node has both a reference to the next node and a reference to the previous node. 5 | 6 | To get started, you can install the package via npm using the following command: 7 | 8 | ```bash 9 | npm install adv-dsa 10 | ``` 11 | 12 | ## Example Usage 13 | 14 | ### Creating a DoublyLinkedList 15 | To use the `DoublyLinkedList` class, first, import it into your JavaScript code: 16 | 17 | ```javascript 18 | const DoublyLinkedList = require('adv-dsa'); 19 | 20 | // Initialize a DoublyLinkedList instance 21 | const list = new DoublyLinkedList(); 22 | ``` 23 | 24 | ### Appending Elements 25 | You can append elements to the doubly linked list using the `append` method. This method adds elements to the end of the list and maintains both the forward and backward references: 26 | 27 | ```javascript 28 | list.append(1); 29 | list.append(2); 30 | list.append(3); 31 | ``` 32 | 33 | ### Displaying the Linked List 34 | To display the elements in the doubly linked list, you can use two methods: 35 | 36 | #### Displaying Forward 37 | Use the `displayForward` method to display the linked list in the forward direction: 38 | 39 | ```javascript 40 | const forwardElements = list.displayForward(); // Returns [1, 2, 3] 41 | ``` 42 | 43 | #### Displaying Backward 44 | Use the `displayBackward` method to display the linked list in the reverse (backward) direction: 45 | 46 | ```javascript 47 | const backwardElements = list.displayBackward(); // Returns [3, 2, 1] 48 | ``` 49 | 50 | ## Testing 51 | 52 | You can also test the "JS-DSA" package using the provided test cases in your test file (e.g., `test.js`). Make sure to import the `DoublyLinkedList` class and use the `assert` module for testing: 53 | 54 | ```javascript 55 | const assert = require('assert'); 56 | const DoublyLinkedList = require('adv-dsa'); 57 | 58 | // Your test cases go here 59 | ``` 60 | 61 | ## Conclusion 62 | "JS-DSA" offers a versatile `DoublyLinkedList` class for managing doubly linked lists. This data structure is useful in various applications, including implementing data structures like deques, text editors with undo/redo functionality, and more. 63 | -------------------------------------------------------------------------------- /docs/data-structures/stacks-and-queues/Stack.md: -------------------------------------------------------------------------------- 1 | # JavaScript Stack Data Structure 2 | 3 | The JavaScript Stack data structure is implemented in the `Stack` class, which allows you to create a stack (LIFO) data structure. Here's how to use the `Stack` class: 4 | 5 | ## Introduction 6 | 7 | To get started with the `Stack` class, you can install the package via npm using the following command: 8 | 9 | ```bash 10 | npm install adv-dsa 11 | ``` 12 | 13 | ## Example Usage 14 | 15 | ### Creating a Stack 16 | You can create a new Stack using the `Stack` class: 17 | 18 | ```javascript 19 | const Stack = require('adv-dsa'); 20 | 21 | // Initialize a new stack 22 | const myStack = new Stack(); 23 | ``` 24 | 25 | ### Adding Elements 26 | You can add elements to the top of the stack using the `push` method: 27 | 28 | ```javascript 29 | myStack.push(1); 30 | myStack.push(2); 31 | myStack.push(3); 32 | 33 | // The stack now contains [1, 2, 3] 34 | ``` 35 | 36 | ### Removing Elements 37 | To remove and return the top element from the stack, use the `pop` method: 38 | 39 | ```javascript 40 | const poppedElement = myStack.pop(); // Removes and returns 3 41 | ``` 42 | 43 | ### Checking the Top Element 44 | You can check the top element of the stack without removing it using the `peek` method: 45 | 46 | ```javascript 47 | const topElement = myStack.peek(); // Returns 2 (top element) 48 | ``` 49 | 50 | ### Checking If the Stack Is Empty 51 | You can check if the stack is empty using the `isEmpty` method: 52 | 53 | ```javascript 54 | const isEmpty = myStack.isEmpty(); // Returns false 55 | ``` 56 | 57 | ### Getting the Size of the Stack 58 | You can get the number of elements in the stack using the `size` method: 59 | 60 | ```javascript 61 | const stackSize = myStack.size(); // Returns 2 62 | ``` 63 | 64 | ## Testing 65 | 66 | You can also test the `Stack` class using the provided test cases in your test file (e.g., `test.js`). Make sure to import the `Stack` class and use the `assert` module for testing: 67 | 68 | ```javascript 69 | const assert = require('assert'); 70 | const Stack = require('adv-dsa'); 71 | 72 | // Your test cases go here 73 | ``` 74 | 75 | ## Conclusion 76 | 77 | The `Stack` class in JavaScript allows you to manage a collection of elements in a stack data structure following the LIFO (Last-In-First-Out) order. It is useful for scenarios where you need to track and manipulate elements in a specific order. 78 | -------------------------------------------------------------------------------- /docs/data-structures/heaps/MaxHeap.md: -------------------------------------------------------------------------------- 1 | # JS-DSA (JavaScript Data Structures and Algorithms) 2 | 3 | ## Introduction 4 | "JS-DSA" is a JavaScript package that provides a `MaxHeap` class, which implements a max heap data structure. A max heap is a binary tree where the parent nodes contain values greater than or equal to the values in their children nodes. This data structure is commonly used for efficiently maintaining and retrieving the maximum element. 5 | 6 | To get started, you can install the package via npm using the following command: 7 | 8 | ```bash 9 | npm install adv-dsa 10 | ``` 11 | 12 | ## Example Usage 13 | 14 | ### Creating a MaxHeap 15 | To use the `MaxHeap` class, first, import it into your JavaScript code: 16 | 17 | ```javascript 18 | const MaxHeap = require('adv-dsa'); 19 | 20 | // Initialize a MaxHeap instance 21 | const maxHeap = new MaxHeap(); 22 | ``` 23 | 24 | ### Inserting Elements 25 | You can insert elements into the max heap using the `insert` method. The heap will automatically maintain its structure by moving the inserted element to the correct position: 26 | 27 | ```javascript 28 | maxHeap.insert(5); 29 | maxHeap.insert(3); 30 | maxHeap.insert(10); 31 | maxHeap.insert(1); 32 | ``` 33 | 34 | ### Extracting Maximum Value 35 | To retrieve the maximum value from the max heap, use the `extractMax` method. This method will remove the maximum value from the heap and reorganize it: 36 | 37 | ```javascript 38 | const max = maxHeap.extractMax(); // Returns 10 39 | ``` 40 | 41 | ### Checking Heap Size and Emptiness 42 | You can check the size and emptiness of the heap using the `size` and `isEmpty` methods: 43 | 44 | ```javascript 45 | const heapSize = maxHeap.size(); // Returns the current size of the heap 46 | const isEmpty = maxHeap.isEmpty(); // Returns `true` if the heap is empty, `false` otherwise 47 | ``` 48 | 49 | ## Testing 50 | 51 | You can also test the "JS-DSA" package using the provided test cases in your test file (e.g., `test.js`). Make sure to import the `MaxHeap` class and use the `assert` module for testing: 52 | 53 | ```javascript 54 | const assert = require('assert'); 55 | const MaxHeap = require('adv-dsa'); 56 | 57 | // Your test cases go here 58 | ``` 59 | 60 | ## Conclusion 61 | "JS-DSA" offers a robust `MaxHeap` class for maintaining maximum values efficiently. This data structure is essential in various algorithms and applications where quick access to the maximum element is required. 62 | -------------------------------------------------------------------------------- /docs/data-structures/heaps/MinHeap.md: -------------------------------------------------------------------------------- 1 | # JS-DSA (JavaScript Data Structures and Algorithms) 2 | 3 | ## Introduction 4 | "JS-DSA" is a JavaScript package that provides a `MinHeap` class, which implements a min heap data structure. A min heap is a binary tree where the parent nodes contain values less than or equal to the values in their children nodes. This data structure is commonly used for efficiently maintaining and retrieving the minimum element. 5 | 6 | To get started, you can install the package via npm using the following command: 7 | 8 | ```bash 9 | npm install adv-dsa 10 | ``` 11 | 12 | ## Example Usage 13 | 14 | ### Creating a MinHeap 15 | To use the `MinHeap` class, first, import it into your JavaScript code: 16 | 17 | ```javascript 18 | const MinHeap = require('adv-dsa'); 19 | 20 | // Initialize a MinHeap instance 21 | const minHeap = new MinHeap(); 22 | ``` 23 | 24 | ### Inserting Elements 25 | You can insert elements into the min heap using the `insert` method. The heap will automatically maintain its structure by moving the inserted element to the correct position: 26 | 27 | ```javascript 28 | minHeap.insert(5); 29 | minHeap.insert(3); 30 | minHeap.insert(10); 31 | minHeap.insert(1); 32 | ``` 33 | 34 | ### Extracting Minimum Value 35 | To retrieve the minimum value from the min heap, use the `extractMin` method. This method will remove the minimum value from the heap and reorganize it: 36 | 37 | ```javascript 38 | const min = minHeap.extractMin(); // Returns 1 39 | ``` 40 | 41 | ### Checking Heap Size and Emptiness 42 | You can check the size and emptiness of the heap using the `size` and `isEmpty` methods: 43 | 44 | ```javascript 45 | const heapSize = minHeap.size(); // Returns the current size of the heap 46 | const isEmpty = minHeap.isEmpty(); // Returns `true` if the heap is empty, `false` otherwise 47 | ``` 48 | 49 | ## Testing 50 | 51 | You can also test the "JS-DSA" package using the provided test cases in your test file (e.g., `test.js`). Make sure to import the `MinHeap` class and use the `assert` module for testing: 52 | 53 | ```javascript 54 | const assert = require('assert'); 55 | const MinHeap = require('adv-dsa'); 56 | 57 | // Your test cases go here 58 | ``` 59 | 60 | ## Conclusion 61 | "JS-DSA" offers a reliable `MinHeap` class for maintaining minimum values efficiently. This data structure is essential in various algorithms and applications where quick access to the minimum element is required. 62 | -------------------------------------------------------------------------------- /test/algorithms/graph-algorithms/bellmanFord.test.js: -------------------------------------------------------------------------------- 1 | const BellmanFord = require('../../../algorithms/graph-algorithms/bellmanFord'); 2 | 3 | describe('Bellman-Ford (OOP)', () => { 4 | it('should find the shortest path in a graph with positive weights', () => { 5 | const graph = { 6 | A: { B: 2, C: 4 }, 7 | B: { D: 7 }, 8 | C: { D: 1 }, 9 | D: { E: 3 }, 10 | E: {}, 11 | }; 12 | 13 | const bellmanFord = new BellmanFord(graph); 14 | const { distance, predecessor } = bellmanFord.findShortestPath('A'); 15 | 16 | expect(distance.E).toBe(8); 17 | expect(predecessor.E).toBe('D'); 18 | }); 19 | 20 | it('should handle a graph with no path between two nodes', () => { 21 | const graph = { 22 | A: { B: 2 }, 23 | B: {}, 24 | }; 25 | 26 | const bellmanFord = new BellmanFord(graph); 27 | 28 | expect(() => bellmanFord.findShortestPath('A')); 29 | }); 30 | 31 | it('should handle a graph with negative edge weights', () => { 32 | const graph = { 33 | A: { B: 2, C: -1 }, 34 | B: { D: -2 }, 35 | C: { D: 1 }, 36 | D: { E: -3 }, 37 | E: {}, 38 | }; 39 | 40 | const bellmanFord = new BellmanFord(graph); 41 | const { distance, predecessor } = bellmanFord.findShortestPath('A'); 42 | 43 | expect(distance.E).toBe(-3); 44 | expect(predecessor.E).toBe('D'); 45 | }); 46 | 47 | it('should handle a graph with the same weight for all edges', () => { 48 | const graph = { 49 | A: { B: 1, C: 1 }, 50 | B: { D: 1 }, 51 | C: { D: 1 }, 52 | D: { E: 1 }, 53 | E: {}, 54 | }; 55 | 56 | const bellmanFord = new BellmanFord(graph); 57 | const { distance, predecessor } = bellmanFord.findShortestPath('A'); 58 | 59 | expect(distance.E).toBe(3); 60 | expect(predecessor.E).toBe('D'); 61 | }); 62 | 63 | it('should handle a graph with only one node', () => { 64 | const graph = { 65 | A: {}, 66 | }; 67 | 68 | const bellmanFord = new BellmanFord(graph); 69 | const { distance, predecessor } = bellmanFord.findShortestPath('A'); 70 | 71 | expect(distance.A).toBe(0); 72 | expect(predecessor.A).toBe(null); 73 | }); 74 | }); 75 | -------------------------------------------------------------------------------- /docs/data-structures/stacks-and-queues/Queue.md: -------------------------------------------------------------------------------- 1 | # JavaScript Queue Data Structure 2 | 3 | The JavaScript Queue data structure is implemented in the `Queue` class, which allows you to create a queue (FIFO) data structure. Here's how to use the `Queue` class: 4 | 5 | ## Introduction 6 | 7 | To get started with the `Queue` class, you can install the package via npm using the following command: 8 | 9 | ```bash 10 | npm install adv-dsa 11 | ``` 12 | 13 | ## Example Usage 14 | 15 | ### Creating a Queue 16 | You can create a new Queue using the `Queue` class: 17 | 18 | ```javascript 19 | const Queue = require('adv-dsa'); 20 | 21 | // Initialize a new queue 22 | const myQueue = new Queue(); 23 | ``` 24 | 25 | ### Adding Elements 26 | You can add elements to the end of the queue using the `enqueue` method: 27 | 28 | ```javascript 29 | myQueue.enqueue(1); 30 | myQueue.enqueue(2); 31 | myQueue.enqueue(3); 32 | 33 | // The queue now contains [1, 2, 3] 34 | ``` 35 | 36 | ### Removing Elements 37 | To remove and return the front element from the queue, use the `dequeue` method: 38 | 39 | ```javascript 40 | const dequeuedElement = myQueue.dequeue(); // Removes and returns 1 41 | ``` 42 | 43 | ### Checking the Front Element 44 | You can check the front element of the queue without removing it using the `front` method: 45 | 46 | ```javascript 47 | const frontElement = myQueue.front(); // Returns 2 (front element) 48 | 49 | ``` 50 | 51 | ### Checking If the Queue Is Empty 52 | You can check if the queue is empty using the `isEmpty` method: 53 | 54 | ```javascript 55 | const isEmpty = myQueue.isEmpty(); // Returns false 56 | ``` 57 | 58 | ### Getting the Size of the Queue 59 | You can get the number of elements in the queue using the `size` method: 60 | 61 | ```javascript 62 | const queueSize = myQueue.size(); // Returns 2 63 | ``` 64 | 65 | ## Testing 66 | 67 | You can also test the `Queue` class using the provided test cases in your test file (e.g., `test.js`). Make sure to import the `Queue` class and use the `assert` module for testing: 68 | 69 | ```javascript 70 | const assert = require('assert'); 71 | const Queue = require('adv-dsa'); 72 | 73 | // Your test cases go here 74 | ``` 75 | 76 | ## Conclusion 77 | 78 | The `Queue` class in JavaScript allows you to manage a collection of elements in a queue data structure following the FIFO (First-In-First-Out) order. It is useful for scenarios where you need to process elements in a specific order. 79 | -------------------------------------------------------------------------------- /docs/algorithms/dynamic-programming/knapsack.md: -------------------------------------------------------------------------------- 1 | # Knapsack Algorithm 2 | 3 | The Knapsack algorithm is used to solve the 0/1 Knapsack problem, which is a classic optimization problem. Given a set of items, each with a weight and a value, the goal is to determine the items to include in a knapsack to maximize the total value while not exceeding a given capacity. 4 | 5 | ## Usage 6 | 7 | To use the Knapsack algorithm in your JavaScript project, follow these steps: 8 | 9 | 1. Import the `Knapsack` class. 10 | 11 | ```javascript 12 | const Knapsack = require('adv-dsa').Knapsack; 13 | ``` 14 | 15 | 2. Create an instance of the `Knapsack` class. 16 | 17 | ```javascript 18 | const knapsack = new Knapsack(); 19 | ``` 20 | 21 | 3. Use the `findMaxValue` method to find the maximum value for the Knapsack problem. 22 | 23 | ```javascript 24 | const weights = [2, 2, 3]; 25 | const values = [2, 3, 5]; 26 | const capacity = 4; 27 | 28 | const maxValue = knapsack.findMaxValue(weights, values, capacity); 29 | console.log(`The maximum value for the knapsack problem is ${maxValue}`); 30 | ``` 31 | 32 | ## Example 33 | 34 | ```javascript 35 | const Knapsack = require('adv-dsa').Knapsack; 36 | const knapsack = new Knapsack(); 37 | 38 | const weights = [2, 2, 3]; 39 | const values = [2, 3, 5]; 40 | const capacity = 4; 41 | 42 | const maxValue = knapsack.findMaxValue(weights, values, capacity); 43 | console.log(`The maximum value for the knapsack problem is ${maxValue}`); 44 | ``` 45 | 46 | This code will output: 47 | 48 | ``` 49 | The maximum value for the knapsack problem is 5 50 | ``` 51 | 52 | ## Test Cases 53 | 54 | You can also use the provided test cases to verify that the `Knapsack` class works as expected. Here's how you can run the test cases: 55 | 56 | 1. Import the `Knapsack` class in your test file. 57 | 58 | ```javascript 59 | const Knapsack = require('adv-dsa').Knapsack; 60 | ``` 61 | 62 | 2. Create an instance of the `Knapsack` class in your test cases. 63 | 64 | ```javascript 65 | const knapsack = new Knapsack(); 66 | ``` 67 | 68 | 3. Use the `expect` function from your testing framework to assert the results of the `findMaxValue` method. 69 | 70 | ```javascript 71 | // Example test case 72 | const weights = [2, 2, 3]; 73 | const values = [2, 3, 5]; 74 | const capacity = 4; 75 | expect(knapsack.findMaxValue(weights, values, capacity)).toBe(5); 76 | ``` 77 | 78 | Make sure to run your test suite to validate the correctness of the Knapsack algorithm implementation. 79 | -------------------------------------------------------------------------------- /docs/algorithms/randomized/randomizedQuickSort.md: -------------------------------------------------------------------------------- 1 | # Randomized Quick Sort 2 | 3 | The `RandomizedQuickSort` class provides an implementation of the randomized Quick Sort algorithm for sorting an array of numbers in ascending order. The algorithm selects a random pivot element to improve its average-case performance compared to the standard Quick Sort algorithm. 4 | 5 | ## Usage 6 | 7 | To use the `RandomizedQuickSort` class in your JavaScript or TypeScript project, follow these steps: 8 | 9 | 1. Import the `RandomizedQuickSort` class from your module. 10 | 11 | ```javascript 12 | const RandomizedQuickSort = require('adv-dsa').RandomizedQuickSort; 13 | ``` 14 | 15 | 2. Create an instance of the class. 16 | 17 | ```javascript 18 | const randomizedQuickSort = new RandomizedQuickSort(); 19 | ``` 20 | 21 | 3. Use the `sort` method to sort an array of numbers in ascending order. 22 | 23 | ```javascript 24 | const unsortedArray = [5, 3, 1, 4, 2]; 25 | randomizedQuickSort.sort(unsortedArray); 26 | console.log(unsortedArray); // Output: [1, 2, 3, 4, 5] 27 | ``` 28 | 29 | This is how you can use the `RandomizedQuickSort` class to sort an array of numbers using randomized Quick Sort. 30 | 31 | ## Example 32 | 33 | ```javascript 34 | const RandomizedQuickSort = require('adv-dsa').RandomizedQuickSort; 35 | 36 | const randomizedQuickSort = new RandomizedQuickSort(); 37 | const unsortedArray = [5, 3, 1, 4, 2]; 38 | randomizedQuickSort.sort(unsortedArray); 39 | console.log(unsortedArray); // Output: [1, 2, 3, 4, 5] 40 | ``` 41 | 42 | This example demonstrates how to use the `RandomizedQuickSort` class to sort an array of numbers. 43 | 44 | ## Test Cases 45 | 46 | You can use the provided test cases to verify that the `RandomizedQuickSort` class works as expected. Import the necessary modules and use the `expect` function from your testing framework to assert the results of the test cases. 47 | 48 | ```javascript 49 | const RandomizedQuickSort = require('adv-dsa').RandomizedQuickSort; 50 | 51 | const randomizedQuickSort = new RandomizedQuickSort(); 52 | 53 | // Example test case for sorting an array 54 | const arr = [5, 3, 1, 4, 2]; 55 | const sortedArr = [1, 2, 3, 4, 5]; 56 | randomizedQuickSort.sort(arr); 57 | expect(arr).toEqual(sortedArr); 58 | 59 | // Additional test cases can be added as needed. 60 | ``` 61 | 62 | This documentation should help users understand how to use the `RandomizedQuickSort` class from your package, how to sort an array of numbers, and how to run the provided test cases. -------------------------------------------------------------------------------- /docs/algorithms/dynamic-programming/editDistance.md: -------------------------------------------------------------------------------- 1 | # Edit Distance Algorithm 2 | 3 | The Edit Distance algorithm, also known as Levenshtein Distance, is used to find the minimum number of operations required to transform one string into another. These operations can be insertions, deletions, or replacements. It is a dynamic programming algorithm that is widely used in spell checking, DNA sequence comparison, and more. 4 | 5 | ## Usage 6 | 7 | To use the Edit Distance algorithm in your JavaScript project, you can follow these steps: 8 | 9 | 1. Import the `EditDistance` class. 10 | 11 | ```javascript 12 | const EditDistance = require('adv-dsa').EditDistance; 13 | ``` 14 | 15 | 2. Create an instance of the `EditDistance` class. 16 | 17 | ```javascript 18 | const editDistance = new EditDistance(); 19 | ``` 20 | 21 | 3. Use the `findEditDistance` method to calculate the edit distance between two strings. 22 | 23 | ```javascript 24 | const str1 = 'kitten'; 25 | const str2 = 'sitting'; 26 | const distance = editDistance.findEditDistance(str1, str2); 27 | console.log(`Edit distance between "${str1}" and "${str2}" is ${distance}`); 28 | ``` 29 | 30 | ## Example 31 | 32 | ```javascript 33 | const EditDistance = require('adv-dsa').EditDistance; 34 | const editDistance = new EditDistance(); 35 | 36 | const str1 = 'kitten'; 37 | const str2 = 'sitting'; 38 | const distance = editDistance.findEditDistance(str1, str2); 39 | console.log(`Edit distance between "${str1}" and "${str2}" is ${distance}`); 40 | ``` 41 | 42 | This code will output: 43 | 44 | ``` 45 | Edit distance between "kitten" and "sitting" is 3 46 | ``` 47 | 48 | ## Test Cases 49 | 50 | You can also use the provided test cases to ensure that the `EditDistance` class works as expected. Here's how you can run the test cases: 51 | 52 | 1. Import the `EditDistance` class in your test file. 53 | 54 | ```javascript 55 | const EditDistance = require('adv-dsa').EditDistance; 56 | ``` 57 | 58 | 2. Create an instance of the `EditDistance` class in your test cases. 59 | 60 | ```javascript 61 | const editDistance = new EditDistance(); 62 | ``` 63 | 64 | 3. Use the `expect` function from your testing framework to assert the results of the `findEditDistance` method. 65 | 66 | ```javascript 67 | // Example test case 68 | const str1 = 'kitten'; 69 | const str2 = 'sitting'; 70 | expect(editDistance.findEditDistance(str1, str2)).toBe(3); 71 | ``` 72 | 73 | Make sure to run your test suite to validate the correctness of the Edit Distance algorithm implementation. -------------------------------------------------------------------------------- /docs/algorithms/geometry/lineIntersection.md: -------------------------------------------------------------------------------- 1 | # Line Intersection Algorithm 2 | 3 | The Line Intersection algorithm is used to find the intersection points of multiple lines. It can determine if and where lines intersect in two-dimensional space. 4 | 5 | ## Usage 6 | 7 | To use the Line Intersection algorithm in your JavaScript project, you can follow these steps: 8 | 9 | 1. Import the `LineIntersection` class. 10 | 11 | ```javascript 12 | const LineIntersection = require('adv-dsa').LineIntersection; 13 | ``` 14 | 15 | 2. Use the `findIntersections` static method to find intersection points among an array of lines. 16 | 17 | ```javascript 18 | const lines = [ 19 | { x1: 0, y1: 0, x2: 2, y2: 2 }, 20 | { x1: 1, y1: 0, x2: 1, y2: 3 }, 21 | { x1: 2, y1: 0, x2: 2, y2: 2 }, 22 | { x1: 3, y1: 0, x2: 3, y2: 3 }, 23 | ]; 24 | 25 | const intersections = LineIntersection.findIntersections(lines); 26 | console.log('Intersection points are:', intersections); 27 | ``` 28 | 29 | ## Example 30 | 31 | ```javascript 32 | const LineIntersection = require('adv-dsa').LineIntersection; 33 | 34 | const lines = [ 35 | { x1: 0, y1: 0, x2: 2, y2: 2 }, 36 | { x1: 1, y1: 0, x2: 1, y2: 3 }, 37 | { x1: 2, y1: 0, x2: 2, y2: 2 }, 38 | { x1: 3, y1: 0, x2: 3, y2: 3 }, 39 | ]; 40 | 41 | const intersections = LineIntersection.findIntersections(lines); 42 | console.log('Intersection points are:', intersections); 43 | ``` 44 | 45 | This code will output the intersection points of the given lines: 46 | 47 | ``` 48 | Intersection points are: [{ x: 1, y: 1 }, { x: 2, y: 2 }] 49 | ``` 50 | 51 | ## Test Cases 52 | 53 | You can also use the provided test cases to verify that the `LineIntersection` class works as expected. Here's how you can run the test cases: 54 | 55 | 1. Import the `LineIntersection` class in your test file. 56 | 57 | ```javascript 58 | const LineIntersection = require('adv-dsa').LineIntersection; 59 | ``` 60 | 61 | 2. Use the `expect` function from your testing framework to assert the results of the `findIntersections` method. 62 | 63 | ```javascript 64 | // Example test case 65 | const lines = [ 66 | { x1: 0, y1: 0, x2: 2, y2: 2 }, 67 | { x1: 1, y1: 0, x2: 1, y2: 3 }, 68 | { x1: 2, y1: 0, x2: 2, y2: 2 }, 69 | { x1: 3, y1: 0, x2: 3, y2: 3 }, 70 | ]; 71 | expect(LineIntersection.findIntersections(lines)).toEqual([{ x: 1, y: 1 }, { x: 2, y: 2 }]); 72 | ``` 73 | 74 | Make sure to run your test suite to validate the correctness of the Line Intersection algorithm implementation. 75 | -------------------------------------------------------------------------------- /test/data-structures/sets-and-maps/Map.test.js: -------------------------------------------------------------------------------- 1 | const assert = require('assert'); 2 | const Map = require('../../../data-structures/sets-and-maps/Map'); 3 | 4 | describe('Map', () => { 5 | it('should create an empty map', () => { 6 | const map = new Map(); 7 | assert.strictEqual(map.size(), 0); 8 | }); 9 | 10 | it('should set key-value pairs in the map', () => { 11 | const map = new Map(); 12 | map.set('name', 'Alice'); 13 | map.set('age', 30); 14 | 15 | assert.strictEqual(map.size(), 2); 16 | }); 17 | 18 | it('should get values associated with keys', () => { 19 | const map = new Map(); 20 | map.set('name', 'Alice'); 21 | map.set('age', 30); 22 | 23 | assert.strictEqual(map.get('name'), 'Alice'); 24 | assert.strictEqual(map.get('age'), 30); 25 | }); 26 | 27 | it('should check if keys exist in the map', () => { 28 | const map = new Map(); 29 | map.set('name', 'Alice'); 30 | 31 | assert.strictEqual(map.has('name'), true); 32 | assert.strictEqual(map.has('age'), false); 33 | }); 34 | 35 | it('should delete key-value pairs from the map', () => { 36 | const map = new Map(); 37 | map.set('name', 'Alice'); 38 | map.set('age', 30); 39 | 40 | map.delete('name'); 41 | assert.strictEqual(map.has('name'), false); 42 | assert.strictEqual(map.size(), 1); 43 | 44 | map.delete('age'); 45 | assert.strictEqual(map.has('age'), false); 46 | assert.strictEqual(map.size(), 0); 47 | }); 48 | 49 | it('should return an array of keys', () => { 50 | const map = new Map(); 51 | map.set('name', 'Alice'); 52 | map.set('age', 30); 53 | 54 | const keys = map.keys(); 55 | assert.deepStrictEqual(keys, ['name', 'age']); 56 | }); 57 | 58 | it('should return an array of values', () => { 59 | const map = new Map(); 60 | map.set('name', 'Alice'); 61 | map.set('age', 30); 62 | 63 | const values = map.values(); 64 | assert.deepStrictEqual(values, ['Alice', 30]); 65 | }); 66 | 67 | it('should clear the map', () => { 68 | const map = new Map(); 69 | map.set('name', 'Alice'); 70 | map.set('age', 30); 71 | 72 | map.clear(); 73 | assert.strictEqual(map.size(), 0); 74 | assert.strictEqual(map.has('name'), false); 75 | assert.strictEqual(map.has('age'), false); 76 | }); 77 | }); 78 | -------------------------------------------------------------------------------- /docs/algorithms/numerical/primalityTesting.md: -------------------------------------------------------------------------------- 1 | # Primality Testing 2 | 3 | The `PrimalityTesting` class provides methods for testing whether a given number is prime or composite. It uses the Miller-Rabin primality test, a probabilistic algorithm that can quickly determine whether a number is prime with a specified number of iterations. 4 | 5 | ## Usage 6 | 7 | To use the `PrimalityTesting` class in your JavaScript project, follow these steps: 8 | 9 | 1. Import the `PrimalityTesting` class from your module. 10 | 11 | ```javascript 12 | const PrimalityTesting = require('adv-dsa').PrimalityTesting; 13 | ``` 14 | 15 | 2. Use the `isPrime` method to test the primality of a number, optionally specifying the number of iterations. 16 | 17 | ```javascript 18 | const number = 29; 19 | const isPrime = PrimalityTesting.isPrime(number); 20 | console.log(`${number} is prime: ${isPrime}`); // Output: 29 is prime: true 21 | ``` 22 | 23 | This is how you can use the `PrimalityTesting` class to test the primality of a number. 24 | 25 | ## Example 26 | 27 | ```javascript 28 | const PrimalityTesting = require('adv-dsa').PrimalityTesting; 29 | 30 | const number = 29; 31 | const isPrime = PrimalityTesting.isPrime(number); 32 | console.log(`${number} is prime: ${isPrime}`); // Output: 29 is prime: true 33 | ``` 34 | 35 | This example demonstrates how to use the `PrimalityTesting` class to test whether a number is prime. 36 | 37 | ## Test Cases 38 | 39 | You can use the provided test cases to verify that the `PrimalityTesting` class works as expected. 40 | 41 | 1. Import the necessary modules in your test file. 42 | 43 | ```javascript 44 | const PrimalityTesting = require('adv-dsa').PrimalityTesting; 45 | ``` 46 | 47 | 2. Use the `expect` function from your testing framework to assert the results of the test cases. You can add more test cases for different numbers and scenarios. 48 | 49 | ```javascript 50 | // Example test case for testing primality of a prime number 51 | const primeNumber = 29; 52 | expect(PrimalityTesting.isPrime(primeNumber)).toBe(true); 53 | 54 | // Example test case for testing primality of a composite number 55 | const compositeNumber = 77; 56 | expect(PrimalityTesting.isPrime(compositeNumber)).toBe(false); 57 | 58 | // Additional test cases for factorizeNumber, getRandomWitness, and modularExponentiation can be included as needed. 59 | ``` 60 | 61 | This documentation should help users understand how to use the `PrimalityTesting` class from your package, how to test the primality of a number, and how to run the provided test cases. -------------------------------------------------------------------------------- /test/algorithms/ml-statistical/kMeansClustering.test.js: -------------------------------------------------------------------------------- 1 | const KMeansClustering = require('../../../algorithms/ml-statistical/kMeansClustering'); 2 | 3 | describe('KMeansClustering', () => { 4 | it('should cluster data into 3 clusters', () => { 5 | const data = [ 6 | [1, 2], 7 | [2, 3], 8 | [8, 7], 9 | [9, 8], 10 | [11, 13], 11 | [14, 15], 12 | ]; 13 | const k = 3; 14 | 15 | const kMeans = new KMeansClustering(data, k); 16 | const clusters = kMeans.cluster(); 17 | 18 | expect(clusters.length).toBe(k); 19 | }); 20 | 21 | it('should return clusters of data points', () => { 22 | const data = [ 23 | [1, 2], 24 | [2, 3], 25 | [8, 7], 26 | [9, 8], 27 | [11, 13], 28 | [14, 15], 29 | ]; 30 | const k = 3; 31 | 32 | const kMeans = new KMeansClustering(data, k); 33 | const clusters = kMeans.cluster(); 34 | 35 | expect(clusters).toBeInstanceOf(Array); 36 | clusters.forEach((cluster) => { 37 | expect(cluster).toBeInstanceOf(Array); 38 | }); 39 | }); 40 | 41 | it('should throw an error with empty data', () => { 42 | const data = []; 43 | const k = 3; 44 | expect(() => new KMeansClustering(data, k)).toThrow('Data must not be empty.'); 45 | }); 46 | 47 | it('should handle clusters with a single data point', () => { 48 | const data = [ 49 | [1, 2], 50 | [2, 3], 51 | [8, 7], 52 | ]; 53 | const k = 3; 54 | 55 | const kMeans = new KMeansClustering(data, k); 56 | const clusters = kMeans.cluster(); 57 | 58 | expect(clusters.length).toBe(k); 59 | clusters.forEach((cluster) => { 60 | expect(cluster.length).toBe(1); 61 | }); 62 | }); 63 | 64 | it('should handle clusters with multiple data points', () => { 65 | const data = [ 66 | [1, 2], 67 | [2, 3], 68 | [8, 7], 69 | [9, 8], 70 | [11, 13], 71 | [14, 15], 72 | ]; 73 | const k = 3; 74 | 75 | const kMeans = new KMeansClustering(data, k); 76 | const clusters = kMeans.cluster(); 77 | 78 | expect(clusters.length).toBe(k); 79 | clusters.forEach((cluster) => { 80 | expect(cluster.length).toBeGreaterThan(1); 81 | }); 82 | }); 83 | }); 84 | -------------------------------------------------------------------------------- /docs/algorithms/dynamic-programming/longestCommonSubsequence.md: -------------------------------------------------------------------------------- 1 | # Longest Common Subsequence Algorithm 2 | 3 | The Longest Common Subsequence (LCS) algorithm is used to find the longest sequence of characters that appears in the same order in two given strings. It is a classic dynamic programming problem used in various applications, such as text comparison and DNA sequence alignment. 4 | 5 | ## Usage 6 | 7 | To use the Longest Common Subsequence algorithm in your JavaScript project, you can follow these steps: 8 | 9 | 1. Import the `LongestCommonSubsequence` class. 10 | 11 | ```javascript 12 | const LongestCommonSubsequence = require('adv-dsa').LongestCommonSubsequence; 13 | ``` 14 | 15 | 2. Create an instance of the `LongestCommonSubsequence` class. 16 | 17 | ```javascript 18 | const lcs = new LongestCommonSubsequence(); 19 | ``` 20 | 21 | 3. Use the `findLCS` method to find the longest common subsequence between two strings. 22 | 23 | ```javascript 24 | const str1 = 'AGGTAB'; 25 | const str2 = 'GXTXAYB'; 26 | const lcsResult = lcs.findLCS(str1, str2); 27 | console.log(`The longest common subsequence is: ${lcsResult}`); 28 | ``` 29 | 30 | ## Example 31 | 32 | ```javascript 33 | const LongestCommonSubsequence = require('adv-dsa').LongestCommonSubsequence; 34 | const lcs = new LongestCommonSubsequence(); 35 | 36 | const str1 = 'AGGTAB'; 37 | const str2 = 'GXTXAYB'; 38 | const lcsResult = lcs.findLCS(str1, str2); 39 | console.log(`The longest common subsequence is: ${lcsResult}`); 40 | ``` 41 | 42 | This code will output: 43 | 44 | ``` 45 | The longest common subsequence is: GTAB 46 | ``` 47 | 48 | ## Test Cases 49 | 50 | You can also use the provided test cases to verify that the `LongestCommonSubsequence` class works as expected. Here's how you can run the test cases: 51 | 52 | 1. Import the `LongestCommonSubsequence` class in your test file. 53 | 54 | ```javascript 55 | const LongestCommonSubsequence = require('adv-dsa').LongestCommonSubsequence; 56 | ``` 57 | 58 | 2. Create an instance of the `LongestCommonSubsequence` class in your test cases. 59 | 60 | ```javascript 61 | const lcs = new LongestCommonSubsequence(); 62 | ``` 63 | 64 | 3. Use the `expect` function from your testing framework to assert the results of the `findLCS` method. 65 | 66 | ```javascript 67 | // Example test case 68 | const str1 = 'AGGTAB'; 69 | const str2 = 'GXTXAYB'; 70 | expect(lcs.findLCS(str1, str2)).toBe('GTAB'); 71 | ``` 72 | 73 | Make sure to run your test suite to validate the correctness of the Longest Common Subsequence algorithm implementation. 74 | -------------------------------------------------------------------------------- /docs/algorithms/graph-algorithms/dijkstra.md: -------------------------------------------------------------------------------- 1 | # Dijkstra's Shortest Path Algorithm 2 | 3 | Dijkstra's algorithm is used to find the shortest path from a source node to all other nodes in a weighted graph. It works efficiently even when the graph contains negative or non-negative edge weights. 4 | 5 | ## Usage 6 | 7 | To use the Dijkstra's algorithm in your JavaScript project, you can follow these steps: 8 | 9 | 1. Import the `Dijkstra` class and create an instance with the graph you want to analyze. 10 | 11 | ```javascript 12 | const Dijkstra = require('adv-dsa').Dijkstra; 13 | 14 | const graph = { 15 | A: { B: 2, C: 4 }, 16 | B: { D: 7 }, 17 | C: { D: 1 }, 18 | D: { E: 3 }, 19 | E: {}, 20 | }; 21 | 22 | const dijkstra = new Dijkstra(graph); 23 | ``` 24 | 25 | 2. Use the `findShortestPath` method to find the shortest path from a specified source node to an end node. 26 | 27 | ```javascript 28 | const shortestPath = dijkstra.findShortestPath('A', 'E'); 29 | console.log('Shortest path:', shortestPath); 30 | ``` 31 | 32 | ## Example 33 | 34 | ```javascript 35 | const Dijkstra = require('adv-dsa').Dijkstra; 36 | 37 | const graph = { 38 | A: { B: 2, C: 4 }, 39 | B: { D: 7 }, 40 | C: { D: 1 }, 41 | D: { E: 3 }, 42 | E: {}, 43 | }; 44 | 45 | const dijkstra = new Dijkstra(graph); 46 | const shortestPath = dijkstra.findShortestPath('A', 'E'); 47 | console.log('Shortest path:', shortestPath); 48 | ``` 49 | 50 | This code will output the shortest path from 'A' to 'E'. 51 | 52 | ## Test Cases 53 | 54 | You can also use the provided test cases to verify that the `Dijkstra` class works as expected. Here's how you can run the test cases: 55 | 56 | 1. Import the `Dijkstra` class in your test file. 57 | 58 | ```javascript 59 | const Dijkstra = require('adv-dsa').Dijkstra; 60 | ``` 61 | 62 | 2. Use the `expect` function from your testing framework to assert the results of the `findShortestPath` method. 63 | 64 | ```javascript 65 | // Example test case 66 | const graph = { 67 | A: { B: 2, C: 4 }, 68 | B: { D: 7 }, 69 | C: { D: 1 }, 70 | D: { E: 3 }, 71 | E: {}, 72 | }; 73 | const dijkstra = new Dijkstra(graph); 74 | const shortestPath = dijkstra.findShortestPath('A', 'E'); 75 | expect(shortestPath).toEqual(['A', 'C', 'D', 'E']); 76 | ``` 77 | 78 | Make sure to run your test suite to validate the correctness of the Dijkstra's algorithm implementation and to ensure that it handles different scenarios, including graphs with positive and negative edge weights and graphs with or without paths between nodes. 79 | -------------------------------------------------------------------------------- /docs/algorithms/geometry/convexHull.md: -------------------------------------------------------------------------------- 1 | # Convex Hull Algorithm 2 | 3 | The Convex Hull is a fundamental problem in computational geometry that finds the smallest convex polygon that encloses a set of points. The convex hull is a polygon with vertices that form the outer boundary of the given points. 4 | 5 | ## Usage 6 | 7 | To use the Convex Hull algorithm in your JavaScript project, you can follow these steps: 8 | 9 | 1. Import the `ConvexHull` class. 10 | 11 | ```javascript 12 | const ConvexHull = require('adv-dsa').ConvexHull; 13 | ``` 14 | 15 | 2. Use the `findConvexHull` static method to find the convex hull of a given array of points. 16 | 17 | ```javascript 18 | const points = [ 19 | { x: 0, y: 3 }, 20 | { x: 2, y: 2 }, 21 | { x: 1, y: 1 }, 22 | { x: 2, y: 1 }, 23 | { x: 3, y: 0 }, 24 | { x: 0, y: 0 }, 25 | { x: 3, y: 3 }, 26 | ]; 27 | 28 | const hull = ConvexHull.findConvexHull(points); 29 | console.log('The convex hull is:', hull); 30 | ``` 31 | 32 | ## Example 33 | 34 | ```javascript 35 | const ConvexHull = require('adv-dsa').ConvexHull; 36 | 37 | const points = [ 38 | { x: 0, y: 3 }, 39 | { x: 2, y: 2 }, 40 | { x: 1, y: 1 }, 41 | { x: 2, y: 1 }, 42 | { x: 3, y: 0 }, 43 | { x: 0, y: 0 }, 44 | { x: 3, y: 3 }, 45 | ]; 46 | 47 | const hull = ConvexHull.findConvexHull(points); 48 | console.log('The convex hull is:', hull); 49 | ``` 50 | 51 | This code will output the convex hull of the given set of points: 52 | 53 | ```bash 54 | The convex hull is: [ 55 | { x: 0, y: 0 }, 56 | { x: 3, y: 0 }, 57 | { x: 3, y: 3 }, 58 | { x: 0, y: 3 } 59 | ] 60 | ``` 61 | 62 | ## Test Cases 63 | 64 | You can also use the provided test cases to verify that the `ConvexHull` class works as expected. Here's how you can run the test cases: 65 | 66 | 1. Import the `ConvexHull` class in your test file. 67 | 68 | ```javascript 69 | const ConvexHull = require('adv-dsa').ConvexHull; 70 | ``` 71 | 72 | 2. Use the `expect` function from your testing framework to assert the results of the `findConvexHull` method. 73 | 74 | ```javascript 75 | // Example test case 76 | const points = [ 77 | { x: 0, y: 3 }, 78 | { x: 2, y: 2 }, 79 | { x: 1, y: 1 }, 80 | { x: 2, y: 1 }, 81 | { x: 3, y: 0 }, 82 | { x: 0, y: 0 }, 83 | { x: 3, y: 3 }, 84 | ]; 85 | expect(ConvexHull.findConvexHull(points)).toEqual([ 86 | { x: 0, y: 0 }, 87 | { x: 3, y: 0 }, 88 | { x: 3, y: 3 }, 89 | { x: 0, y: 3 } 90 | ]); 91 | ``` 92 | 93 | Make sure to run your test suite to validate the correctness of the Convex Hull algorithm implementation. 94 | --------------------------------------------------------------------------------