From 74331030d40c5d2318b98bb76e5b10ff18779298 Mon Sep 17 00:00:00 2001
From: Rohit Chaudhari <100275369+rohitkbc@users.noreply.github.com>
Date: Sun, 3 Dec 2023 21:22:24 +0530
Subject: [PATCH 01/26] feat: Add Gitpod setup (#216)
* Add gitpod setup
* Update yml file
* modified: .gitpod.yml
* Modified : .gitpod.yml
---
.gitpod.yml | 5 +++++
README.md | 5 +++--
2 files changed, 8 insertions(+), 2 deletions(-)
create mode 100644 .gitpod.yml
diff --git a/.gitpod.yml b/.gitpod.yml
new file mode 100644
index 00000000..46209a0a
--- /dev/null
+++ b/.gitpod.yml
@@ -0,0 +1,5 @@
+tasks:
+ - init: |
+ npm install && npm test
+
+
diff --git a/README.md b/README.md
index 930e83b4..5412c60a 100644
--- a/README.md
+++ b/README.md
@@ -9,8 +9,9 @@ TypeScript Repository of TheAlgorithms, which implements various algorithms and
[![Contributions Welcome][welcome]](CONTRIBUTING.md)
[![Discord chat][chat]][discord-server]
-
-
+
+
+
---
From e0ae74498376dbbc7e309e9b4b8a6fcad5e863a2 Mon Sep 17 00:00:00 2001
From: tamaf96 <80266356+tamaf96@users.noreply.github.com>
Date: Fri, 15 Dec 2023 13:25:29 +0100
Subject: [PATCH 02/26] feat: add treesort algorithm (#217)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* feat: add treesort algorithm
* use existing data structure
* make generic and add tests for string and date
* fix typo
* Fix typo
---------
Co-authored-by: tamaf96
Co-authored-by: Lars Müller <34514239+appgurueu@users.noreply.github.com>
---
DIRECTORY.md | 1 +
sorts/test/tree_sort.test.ts | 33 +++++++++++++++++++++++++++++++++
sorts/tree_sort.ts | 18 ++++++++++++++++++
3 files changed, 52 insertions(+)
create mode 100644 sorts/test/tree_sort.test.ts
create mode 100644 sorts/tree_sort.ts
diff --git a/DIRECTORY.md b/DIRECTORY.md
index 92c92ff3..de534ede 100644
--- a/DIRECTORY.md
+++ b/DIRECTORY.md
@@ -166,3 +166,4 @@
* [Selection Sort](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/sorts/selection_sort.ts)
* [Shell Sort](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/sorts/shell_sort.ts)
* [Swap Sort](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/sorts/swap_sort.ts)
+ * [Tree Sort](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/sorts/tree_sort.ts)
diff --git a/sorts/test/tree_sort.test.ts b/sorts/test/tree_sort.test.ts
new file mode 100644
index 00000000..07cbca56
--- /dev/null
+++ b/sorts/test/tree_sort.test.ts
@@ -0,0 +1,33 @@
+import { treeSort } from "../tree_sort";
+
+describe('TreeSort (numbers)', () => {
+ it.each([
+ { input: [], expected: [] },
+ { input: [1, 18, 3, 4, -5, 6], expected: [-5, 1, 3, 4, 6, 18] },
+ { input: [7, 6, 2, 5.2, 11, 0], expected: [0, 2, 5.2, 6, 7, 11] },
+ { input: [3, 3, -2, 1, 0], expected: [-2, 0, 1, 3, 3] },
+ { input: [3, 0, -2.4, 1, 9, 8, -7, 6], expected: [-7, -2.4, 0, 1, 3, 6, 8, 9] },
+ { input: [1, 0, -14, 0, 8.6, 6, 8], expected: [-14, 0, 0, 1, 6, 8, 8.6] },
+ ])('should work for given input', ({ input, expected }) => {
+ expect(treeSort(input)).toEqual(expected);
+ });
+});
+
+describe('TreeSort (strings)', () => {
+ it.each([
+ { input: ["e","egr","sse","aas", "as","abs"], expected: ["aas","abs","as","e","egr","sse"] },
+ ])('should work for given input', ({ input, expected }) => {
+ expect(treeSort(input)).toEqual(expected);
+ });
+});
+
+describe('TreeSort (dates)', () => {
+ it.each([
+ { input: [new Date("2019-01-16"),new Date("2019-01-01"),new Date("2022-05-20")], expected: [new Date("2019-01-01"),new Date("2019-01-16"),new Date("2022-05-20")] },
+ ])('should work for given input', ({ input, expected }) => {
+ expect(treeSort(input)).toEqual(expected);
+ });
+});
+
+
+
\ No newline at end of file
diff --git a/sorts/tree_sort.ts b/sorts/tree_sort.ts
new file mode 100644
index 00000000..e4369e52
--- /dev/null
+++ b/sorts/tree_sort.ts
@@ -0,0 +1,18 @@
+/**
+ * @author : tamaf96
+ * @description
+ * Tree Sort sorts a list by building a binary search tree and traversing it.
+ * @param {T[]} arr - Array of comparable items
+ * @return {T[]} - The sorted Array.
+ * @see
+ */
+
+import { BinarySearchTree } from "../data_structures/tree/binary_search_tree";
+
+export const treeSort = (arr: T[]): T[] => {
+ const searchTree = new BinarySearchTree();
+ for (const item of arr) {
+ searchTree.insert(item);
+ }
+ return searchTree.inOrderTraversal();
+};
From 4acf117fa277538feaed8d4c3ac4ca706a006ea3 Mon Sep 17 00:00:00 2001
From: Joshua Cao
Date: Sat, 30 Dec 2023 10:43:02 -0800
Subject: [PATCH 03/26] fix: document heap sorts space complexity to O(1)
(#219)
---
sorts/heap_sort.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/sorts/heap_sort.ts b/sorts/heap_sort.ts
index ecc42995..e5541a77 100644
--- a/sorts/heap_sort.ts
+++ b/sorts/heap_sort.ts
@@ -4,7 +4,7 @@
* @see [Heap Sort](https://www.geeksforgeeks.org/heap-sort/)
* @example MergeSort([7, 3, 5, 1, 4, 2]) = [1, 2, 3, 4, 5, 7]
* @Complexity_Analysis
- * Space complexity - O(n)
+ * Space complexity - O(1)
* Time complexity
* Best case - O(nlogn)
* Worst case - O(nlogn)
From 6e78b6c2540d9d50b0f310cdfacb3a9fc979806f Mon Sep 17 00:00:00 2001
From: Joshua Cao
Date: Sat, 30 Dec 2023 22:17:01 -0800
Subject: [PATCH 04/26] feat: Add kosajura algorithm for finding strong
connected components (#218)
---
graph/kosajaru.ts | 75 +++++++++++++++++++++++++++++++++++++
graph/test/kosajaru.test.ts | 72 +++++++++++++++++++++++++++++++++++
2 files changed, 147 insertions(+)
create mode 100644 graph/kosajaru.ts
create mode 100644 graph/test/kosajaru.test.ts
diff --git a/graph/kosajaru.ts b/graph/kosajaru.ts
new file mode 100644
index 00000000..32338e76
--- /dev/null
+++ b/graph/kosajaru.ts
@@ -0,0 +1,75 @@
+// Compute the node priorities, which will be used to determine the order in which we perform transposed DFS.
+const getNodePriorities = (graph: number[][], visited: boolean[], stack: number[], node: number) => {
+ if (visited[node]) {
+ return;
+ }
+ visited[node] = true;
+
+ for (const dest of graph[node]) {
+ getNodePriorities(graph, visited, stack, dest);
+ }
+ // Nodes that end their DFS earlier are pushed onto the stack first and have lower priority.
+ stack.push(node);
+}
+
+// Return the transpose of graph. The tranpose of a directed graph is a graph where each of the edges are flipped.
+const transpose = (graph: number[][]): number[][] => {
+ let transposedGraph = Array(graph.length);
+ for (let i = 0; i < graph.length; ++i) {
+ transposedGraph[i] = [];
+ }
+
+ for (let i = 0; i < graph.length; ++i) {
+ for (let j = 0; j < graph[i].length; ++j) {
+ transposedGraph[graph[i][j]].push(i);
+ }
+ }
+
+ return transposedGraph;
+}
+
+// Computes the SCC that contains the given node
+const gatherScc = (graph: number[][], visited: boolean[], node: number, scc: number[]) => {
+ if (visited[node]) {
+ return;
+ }
+ visited[node] = true;
+ scc.push(node);
+
+ for (const dest of graph[node]) {
+ gatherScc(graph, visited, dest, scc);
+ }
+}
+
+/**
+ * @function kosajaru
+ * @description Given a graph, find the strongly connected components(SCC). A set of nodes form a SCC if there is a path between all pairs of points within that set.
+ * @Complexity_Analysis
+ * Time complexity: O(V + E). We perform two DFS twice, and make sure to visit each disconnected graph. Each DFS is O(V + E).
+ * Space Complexity: O(V + E). This space is required for the transposed graph.
+ * @param {[number, number][][]} graph - The graph in adjacency list form
+ * @return {number[][]} - An array of SCCs, where an SCC is an array with the indices of each node within that SCC.
+ * @see https://en.wikipedia.org/wiki/Kosaraju%27s_algorithm
+ */
+export const kosajaru = (graph: number[][]): number[][] => {
+ let visited = Array(graph.length).fill(false);
+
+ let stack: number[] = [];
+ for (let i = 0; i < graph.length; ++i) {
+ getNodePriorities(graph, visited, stack, i);
+ }
+
+ const transposedGraph = transpose(graph);
+
+ let sccs = [];
+ visited.fill(false);
+ for (let i = stack.length - 1; i >= 0; --i) {
+ if (!visited[stack[i]]) {
+ let scc: number[] = [];
+ gatherScc(transposedGraph, visited, stack[i], scc);
+ sccs.push(scc);
+ }
+ }
+ return sccs;
+}
+
diff --git a/graph/test/kosajaru.test.ts b/graph/test/kosajaru.test.ts
new file mode 100644
index 00000000..946b0201
--- /dev/null
+++ b/graph/test/kosajaru.test.ts
@@ -0,0 +1,72 @@
+import { kosajaru } from "../kosajaru";
+
+describe("kosajaru", () => {
+
+ it("it should return no sccs for empty graph", () => {
+ expect(kosajaru([])).toStrictEqual([]);
+ });
+
+ it("it should return one scc for graph with one element", () => {
+ expect(kosajaru([[]])).toStrictEqual([[0]]);
+ });
+
+ it("it should return one scc for graph with element that points to itself", () => {
+ expect(kosajaru([[0]])).toStrictEqual([[0]]);
+ });
+
+ it("it should return one scc for two element graph with cycle", () => {
+ expect(kosajaru([[1], [0]])).toStrictEqual([[0, 1]]);
+ });
+
+ it("should return one scc for each element for straight line", () => {
+ expect(kosajaru([[1], [2], [3], []])).toStrictEqual([[0], [1], [2], [3]]);
+ });
+
+ it("should return sccs for straight line with backedge in middle", () => {
+ expect(kosajaru([[1], [2], [3, 0], []])).toStrictEqual([[0, 2, 1], [3]]);
+ });
+
+ it("should return sccs for straight line with backedge from end to middle", () => {
+ expect(kosajaru([[1], [2], [3], [1]])).toStrictEqual([[0], [1, 3, 2]]);
+ });
+
+ it("should return scc for each element for graph with no edges", () => {
+ expect(kosajaru([[], [], [], []])).toStrictEqual([[3], [2], [1], [0]]);
+ });
+
+ it("should return sccs disconnected graph", () => {
+ expect(kosajaru([[1, 2], [0, 2], [0, 1], []])).toStrictEqual([[3], [0, 1, 2]]);
+ });
+
+ it("should return sccs disconnected graph", () => {
+ expect(kosajaru([[1, 2], [0, 2], [0, 1], [4], [5], [3]])).toStrictEqual([[3, 5, 4], [0, 1, 2]]);
+ });
+
+ it("should return single scc", () => {
+ expect(kosajaru([[1], [2], [3], [0, 4], [3]])).toStrictEqual([[0, 3, 2, 1, 4]]);
+ });
+
+ it("should return one scc for complete connected graph", () => {
+ const input = [[1, 2, 3, 4], [0, 2, 3, 4], [0, 1, 3, 4], [0, 1, 2, 4], [0, 1, 2, 3]];
+ expect(kosajaru(input)).toStrictEqual([[0, 1, 2, 3, 4]]);
+ });
+
+ it("should return sccs", () => {
+ const input = [[1], [2], [0, 3], [4], []];
+ expect(kosajaru(input)).toStrictEqual([[0, 2, 1], [3], [4]]);
+ });
+
+ it("should return sccs", () => {
+ const input = [[1], [2], [0, 3, 4], [0], [5], [6, 7], [2, 4], [8], [5, 9], [5]];
+ const expected = [[0, 2, 1, 6, 5, 4, 8, 7, 9, 3]];
+ expect(kosajaru(input)).toStrictEqual(expected);
+ });
+
+ it("should return sccs", () => {
+ const input = [[1], [0, 2], [0, 3], [4], [5, 7], [6], [4, 7], []];
+ const expected = [[0, 1, 2], [3], [4, 6, 5], [7]];
+ expect(kosajaru(input)).toStrictEqual(expected);
+ });
+
+})
+
From 90212facc1759cf32bff51a220c3d34f086e2572 Mon Sep 17 00:00:00 2001
From: Joshua Cao
Date: Sat, 13 Jan 2024 07:24:46 -0800
Subject: [PATCH 05/26] feat: add tarjan algorithm for strongly connected
components (#220)
* feat: add tarjan algorithm for strongly connected components
* Address review. Add notes on topological sort.
---
graph/tarjan.ts | 70 +++++++++++++++++++++++++++++++++++
graph/test/tarjan.test.ts | 78 +++++++++++++++++++++++++++++++++++++++
2 files changed, 148 insertions(+)
create mode 100644 graph/tarjan.ts
create mode 100644 graph/test/tarjan.test.ts
diff --git a/graph/tarjan.ts b/graph/tarjan.ts
new file mode 100644
index 00000000..7f2a2454
--- /dev/null
+++ b/graph/tarjan.ts
@@ -0,0 +1,70 @@
+/**
+ * @function tarjan
+ * @description Given a graph, find the strongly connected components(SCC) in reverse topological order. A set of nodes form a SCC if there is a path between all pairs of points within that set.
+ * @Complexity_Analysis
+ * Time complexity: O(V + E). We perform a DFS of (V + E)
+ * Space Complexity: O(V). We hold numerous structures all of which at worst holds O(V) nodes.
+ * @param {[number, number][][]} graph - The graph in adjacency list form
+ * @return {number[][]} - An array of SCCs, where an SCC is an array with the indices of each node within that SCC. The order of SCCs in the array are in reverse topological order.
+ * @see https://en.wikipedia.org/wiki/Tarjan%27s_strongly_connected_components_algorithm
+ */
+export const tarjan = (graph: number[][]): number[][] => {
+ if (graph.length === 0) {
+ return [];
+ }
+
+ let index = 0;
+ // The order in which we discover nodes
+ let discovery: number[] = Array(graph.length);
+ // For each node, holds the furthest ancestor it can reach
+ let low: number[] = Array(graph.length).fill(undefined);
+ // Holds the nodes we have visited in a DFS traversal and are considering to group into a SCC
+ let stack: number[] = [];
+ // Holds the elements in the stack.
+ let stackContains = Array(graph.length).fill(false);
+ let sccs: number[][] = [];
+
+ const dfs = (node: number) => {
+ discovery[node] = index;
+ low[node] = index;
+ ++index;
+ stack.push(node);
+ stackContains[node] = true;
+
+ for (const child of graph[node]) {
+ if (low[child] === undefined) {
+ dfs(child);
+ if (low[child] < low[node]) {
+ // Child node loops back to this node's ancestor. Update the low node.
+ low[node] = low[child];
+ }
+ } else if (stackContains[child] && low[node] > discovery[child]) {
+ // Found a backedge. Update the low for this node if needed.
+ low[node] = discovery[child];
+ }
+ }
+
+ if (discovery[node] == low[node]) {
+ // node is the root of a SCC. Gather the SCC's nodes from the stack.
+ let scc: number[] = [];
+ let i;
+ for (i = stack.length - 1; stack[i] != node; --i) {
+ scc.push(stack[i]);
+ stackContains[stack[i]] = false;
+ stack.pop();
+ }
+ scc.push(stack[i]);
+ stackContains[stack[i]] = false;
+ stack.pop();
+ sccs.push(scc);
+ }
+ }
+
+ for (let i = 0; i < graph.length; ++i) {
+ if (low[i] === undefined) {
+ dfs(i);
+ }
+ }
+ return sccs;
+}
+
diff --git a/graph/test/tarjan.test.ts b/graph/test/tarjan.test.ts
new file mode 100644
index 00000000..f2eca081
--- /dev/null
+++ b/graph/test/tarjan.test.ts
@@ -0,0 +1,78 @@
+import { tarjan } from "../tarjan";
+
+describe("tarjan", () => {
+
+ it("it should return no sccs for empty graph", () => {
+ expect(tarjan([])).toStrictEqual([]);
+ });
+
+ it("it should return one scc for graph with one element", () => {
+ expect(tarjan([[]])).toStrictEqual([[0]]);
+ });
+
+ it("it should return one scc for graph with element that points to itself", () => {
+ expect(tarjan([[0]])).toStrictEqual([[0]]);
+ });
+
+ it("it should return one scc for two element graph with cycle", () => {
+ expect(tarjan([[1], [0]])).toStrictEqual([[1, 0]]);
+ });
+
+ it("should return one scc for each element for straight line", () => {
+ expect(tarjan([[1], [2], [3], []])).toStrictEqual([[3], [2], [1], [0]]);
+ });
+
+ it("should return sccs for straight line with backedge in middle", () => {
+ expect(tarjan([[1], [2], [3, 0], []])).toStrictEqual([[3], [2, 1, 0]]);
+ });
+
+ it("should return sccs for straight line with backedge from end to middle", () => {
+ expect(tarjan([[1], [2], [3], [1]])).toStrictEqual([[3, 2, 1], [0]]);
+ });
+
+ it("should return scc for each element for graph with no edges", () => {
+ expect(tarjan([[], [], [], []])).toStrictEqual([[0], [1], [2], [3]]);
+ });
+
+ it("should return sccs disconnected graph", () => {
+ expect(tarjan([[1, 2], [0, 2], [0, 1], []])).toStrictEqual([[2, 1, 0], [3]]);
+ });
+
+ it("should return sccs disconnected graph", () => {
+ expect(tarjan([[1, 2], [0, 2], [0, 1], [4], [5], [3]])).toStrictEqual([[2, 1, 0], [5, 4, 3]]);
+ });
+
+ it("should return single scc", () => {
+ expect(tarjan([[1], [2], [3], [0, 4], [3]])).toStrictEqual([[4, 3, 2, 1, 0]]);
+ });
+
+ it("should return one scc for complete connected graph", () => {
+ const input = [[1, 2, 3, 4], [0, 2, 3, 4], [0, 1, 3, 4], [0, 1, 2, 4], [0, 1, 2, 3]];
+ expect(tarjan(input)).toStrictEqual([[4, 3, 2, 1, 0]]);
+ });
+
+ it("should return sccs", () => {
+ const input = [[1], [2], [0, 3], [4], []];
+ expect(tarjan(input)).toStrictEqual([[4], [3], [2, 1, 0]]);
+ });
+
+ it("should return sccs", () => {
+ const input = [[1], [2], [0, 3, 4], [0], [5], [6, 7], [2, 4], [8], [5, 9], [5]];
+ const expected = [[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]];
+ expect(tarjan(input)).toStrictEqual(expected);
+ });
+
+ it("should return sccs", () => {
+ const input = [[1], [0, 2], [0, 3], [4], [5, 7], [6], [4, 7], []];
+ const expected = [[7], [6, 5, 4], [3], [2, 1, 0]];
+ expect(tarjan(input)).toStrictEqual(expected);
+ });
+
+ it("should return sccs where first scc cannot reach second scc", () => {
+ const input = [[1], [2], [0], [4], [5], [2, 3]];
+ const expected = [[2, 1, 0], [5, 4, 3]];
+ expect(tarjan(input)).toStrictEqual(expected);
+ });
+
+})
+
From c8a4b9827e6d44ec216355cc4186d636703a3816 Mon Sep 17 00:00:00 2001
From: Omar Ferreiro <27824673+IcarusTheFly@users.noreply.github.com>
Date: Mon, 15 Jan 2024 23:41:22 +0100
Subject: [PATCH 06/26] docs: Remove not needed whitespaces in markdown files
(#197)
Co-authored-by: IcarusTheFly
Co-authored-by: David Leal
---
CONTRIBUTING.md | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 920486e7..5af6436d 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -63,14 +63,14 @@ should add unique value.
#### Commit Messages Formatting
- Prefer to use the [Conventional Commits](https://www.conventionalcommits.org/) format: `: `. If necessary, put any extra information in the description.
-- Commit types include (but are not limited to):
+- Commit types include (but are not limited to):
- **docs**: Documentation only changes
- **feat**: A new feature
- **fix**: A bug fix
- **test**: Adding or fixing tests
- **chore**: CI / code quality / minor quality of life improvements
-- **Examples**:
+- **Examples**:
- `feat: add quicksort algorithm`
- `chore: fix spelling`
- `fix: improper error message`
From 9bea1357aa1605d20c02f75b62a0fae5f63709fd Mon Sep 17 00:00:00 2001
From: Piotr Idzik <65706193+vil02@users.noreply.github.com>
Date: Wed, 31 Jan 2024 07:08:17 +0100
Subject: [PATCH 07/26] chore: add `upload_coverage_report.yml` (#224)
* chore: add `upload_coverage_report.yml`
* Update DIRECTORY.md
---------
Co-authored-by: autoprettier
---
.github/workflows/upload_coverage_report.yml | 32 ++++++++++++++++++++
.gitignore | 2 ++
DIRECTORY.md | 7 +++++
3 files changed, 41 insertions(+)
create mode 100644 .github/workflows/upload_coverage_report.yml
diff --git a/.github/workflows/upload_coverage_report.yml b/.github/workflows/upload_coverage_report.yml
new file mode 100644
index 00000000..0993cf49
--- /dev/null
+++ b/.github/workflows/upload_coverage_report.yml
@@ -0,0 +1,32 @@
+---
+name: upload_coverage_report
+
+'on':
+ workflow_dispatch:
+ push:
+ branches:
+ - master
+ pull_request:
+
+jobs:
+ upload_coverage_report:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+
+ - uses: actions/setup-node@v4
+ with:
+ node-version: "18.x"
+
+ - name: Install dependencies
+ run: npm ci
+
+ - name: Generate coverage report
+ run: npm test -- --coverage
+
+ - name: Upload coverage to codecov
+ uses: codecov/codecov-action@v3
+ with:
+ files: "coverage/coverage-final.json"
+ fail_ci_if_error: true
+...
diff --git a/.gitignore b/.gitignore
index 1714facb..1cc076e7 100644
--- a/.gitignore
+++ b/.gitignore
@@ -14,3 +14,5 @@ yarn-error.log*
# intelliJ workspace folder
.idea
+
+/coverage
diff --git a/DIRECTORY.md b/DIRECTORY.md
index de534ede..3e6e6418 100644
--- a/DIRECTORY.md
+++ b/DIRECTORY.md
@@ -73,6 +73,7 @@
* [Tries](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/data_structures/tries/tries.ts)
## Dynamic Programming
+ * [Coin Change](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/dynamic_programming/coin_change.ts)
* [Knapsack](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/dynamic_programming/knapsack.ts)
* [Lcs](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/dynamic_programming/lcs.ts)
@@ -82,16 +83,20 @@
* [Dijkstra](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/graph/dijkstra.ts)
* [Floyd Warshall](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/graph/floyd_warshall.ts)
* [Johnson](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/graph/johnson.ts)
+ * [Kosajaru](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/graph/kosajaru.ts)
* [Kruskal](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/graph/kruskal.ts)
* [Prim](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/graph/prim.ts)
+ * [Tarjan](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/graph/tarjan.ts)
* Test
* [Bellman Ford.Test](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/graph/test/bellman_ford.test.ts)
* [Bipartite Graph.Test](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/graph/test/bipartite_graph.test.ts)
* [Dijkstra.Test](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/graph/test/dijkstra.test.ts)
* [Floyd Warshall.Test](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/graph/test/floyd_warshall.test.ts)
* [Johnson.Test](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/graph/test/johnson.test.ts)
+ * [Kosajaru.Test](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/graph/test/kosajaru.test.ts)
* [Kruskal.Test](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/graph/test/kruskal.test.ts)
* [Prim.Test](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/graph/test/prim.test.ts)
+ * [Tarjan.Test](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/graph/test/tarjan.test.ts)
## Maths
* [Absolute Value](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/maths/absolute_value.ts)
@@ -103,6 +108,7 @@
* [Calculate Median](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/maths/calculate_median.ts)
* [Degrees To Radians](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/maths/degrees_to_radians.ts)
* [Digit Sum](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/maths/digit_sum.ts)
+ * [Euler Totient](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/maths/euler_totient.ts)
* [Factorial](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/maths/factorial.ts)
* [Factors](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/maths/factors.ts)
* [Fibonacci](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/maths/fibonacci.ts)
@@ -123,6 +129,7 @@
* [Pascals Triangle](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/maths/pascals_triangle.ts)
* [Perfect Cube](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/maths/perfect_cube.ts)
* [Perfect Square](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/maths/perfect_square.ts)
+ * [Prime Factorization](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/maths/prime_factorization.ts)
* [Primes](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/maths/primes.ts)
* [Pronic Number](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/maths/pronic_number.ts)
* [Radians To Degrees](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/maths/radians_to_degrees.ts)
From 296e4a5af4bf4dc3a921db96bd95e82112d0bb38 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E3=81=86=E3=81=86=E3=81=86?=
<143775446+ei-sugimoto@users.noreply.github.com>
Date: Wed, 31 Jan 2024 23:01:30 +0900
Subject: [PATCH 08/26] feat: add perfect number (#221)
* feat: add perfect numbers
* Optimize isPerfectNumber function and update tests
---
maths/perfect_number.ts | 27 +++++++++++++++++++++++++++
maths/test/perfect_numbers.test.ts | 18 ++++++++++++++++++
2 files changed, 45 insertions(+)
create mode 100644 maths/perfect_number.ts
create mode 100644 maths/test/perfect_numbers.test.ts
diff --git a/maths/perfect_number.ts b/maths/perfect_number.ts
new file mode 100644
index 00000000..c528321a
--- /dev/null
+++ b/maths/perfect_number.ts
@@ -0,0 +1,27 @@
+/**
+ * @function isPerfectNumber
+ * @abstract A function to determine if a number is a perfect number
+ * @param {number} n
+ *
+ * @example console.log(isPerfectNumber(6)) => true
+ * @example console.log(isPerfectNumber(28)) => true
+ * @example console.log(isPerfectNumber(12))=> false
+ */
+
+export const isPerfectNumber = (n: number): boolean => {
+ if (n <= 0 || !Number.isInteger(n)) {
+ return false;
+ }
+ let sum = 1;
+ let sqrt = Math.sqrt(n);
+ for (let i = 2; i < sqrt; i++) {
+ if (n % i === 0) {
+ sum += i + n / i;
+ }
+ }
+ if (sqrt === Math.floor(sqrt)) {
+ sum += sqrt;
+ }
+
+ return sum === n;
+};
\ No newline at end of file
diff --git a/maths/test/perfect_numbers.test.ts b/maths/test/perfect_numbers.test.ts
new file mode 100644
index 00000000..7d2e92c9
--- /dev/null
+++ b/maths/test/perfect_numbers.test.ts
@@ -0,0 +1,18 @@
+import { isPerfectNumber } from "../perfect_number";
+
+describe('perfect Numbers tests', () => {
+ it.each([
+ [6, true],
+ [28, true],
+ [496, true],
+ [8128, true],
+ [12, false],
+ [42, false],
+ [100, false],
+ [0, false],
+ [-1, false],
+ [1.5, false],
+ ])('The return value of %i should be %s', (n, expectation) => {
+ expect(isPerfectNumber(n)).toBe(expectation);
+ });
+});
From 4f6cd6c264d047dcc1bf1045765f4d8968fee6d2 Mon Sep 17 00:00:00 2001
From: Piotr Idzik <65706193+vil02@users.noreply.github.com>
Date: Fri, 9 Feb 2024 18:01:56 +0100
Subject: [PATCH 09/26] tests: add missing tests of `isPalindrome` (#227)
---
maths/test/is_palindrome.test.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/maths/test/is_palindrome.test.ts b/maths/test/is_palindrome.test.ts
index 23911cbf..ea15f48a 100644
--- a/maths/test/is_palindrome.test.ts
+++ b/maths/test/is_palindrome.test.ts
@@ -1,7 +1,7 @@
import { isPalindrome } from "../is_palindrome";
describe("isPalindrome", () => {
- test.each([[5, true], [1234, false], [12321, true], [31343, false]])(
+ test.each([[0, true], [1, true], [5, true], [1234, false], [12321, true], [31343, false], [-1, false], [-11, false], [10, false]])(
"correct output for %i",
(nums, expected) => {
expect(isPalindrome(nums)).toBe(expected);
From 650d553366ad943ea7b12ea715cd46575a002d4a Mon Sep 17 00:00:00 2001
From: Piotr Idzik <65706193+vil02@users.noreply.github.com>
Date: Wed, 14 Feb 2024 16:43:06 +0100
Subject: [PATCH 10/26] fix: handle squares properly in `isSquareFree` (#228)
---
maths/is_square_free.ts | 2 +-
maths/test/is_square_free.test.ts | 17 ++++++++++-------
2 files changed, 11 insertions(+), 8 deletions(-)
diff --git a/maths/is_square_free.ts b/maths/is_square_free.ts
index 0e55ab7f..79958a7a 100644
--- a/maths/is_square_free.ts
+++ b/maths/is_square_free.ts
@@ -14,7 +14,7 @@ export const isSquareFree = (n: number): boolean => {
if (n % 2 === 0) n = n / 2;
if (n % 2 === 0) return false;
- for (let i: number = 3; i < Math.sqrt(n); i = i + 2) {
+ for (let i: number = 3; i <= Math.sqrt(n); i = i + 2) {
if (n % i === 0) {
n = n / i;
if (n % i === 0) return false;
diff --git a/maths/test/is_square_free.test.ts b/maths/test/is_square_free.test.ts
index bbb16991..c2eeb99d 100644
--- a/maths/test/is_square_free.test.ts
+++ b/maths/test/is_square_free.test.ts
@@ -1,11 +1,14 @@
import { isSquareFree } from '../is_square_free';
describe('isSquareFree', () => {
- test('should return correct boolean value', () => {
- expect(isSquareFree(1)).toBe(true);
- expect(isSquareFree(10)).toBe(true);
- expect(isSquareFree(20)).toBe(false);
- expect(isSquareFree(26)).toBe(true);
- expect(isSquareFree(48)).toBe(false);
+ test.each([1, 2, 3, 5, 7, 10, 26, 2*3, 3*5*7, 11*13*17*19])(
+ "%i is square free",
+ (input) => {
+ expect(isSquareFree(input)).toBe(true);
});
-});
\ No newline at end of file
+ test.each([20, 48, 2*7*7, 2*3*3, 5*5*7, 2*3*13*13*17, 4*4*4, 2*2, 3*3, 5*5, 100, 0])(
+ "%i is not square free",
+ (input) => {
+ expect(isSquareFree(input)).toBe(false);
+ });
+});
From 24cbb3bc5e7cbc75e50dace885fd9feed2a4ef1c Mon Sep 17 00:00:00 2001
From: Piotr Idzik <65706193+vil02@users.noreply.github.com>
Date: Wed, 14 Feb 2024 16:44:43 +0100
Subject: [PATCH 11/26] test: cleanup `square_root.test.ts` (#229)
---
maths/test/square_root.test.ts | 16 ++++++----------
1 file changed, 6 insertions(+), 10 deletions(-)
diff --git a/maths/test/square_root.test.ts b/maths/test/square_root.test.ts
index 3dbd8658..366f867c 100644
--- a/maths/test/square_root.test.ts
+++ b/maths/test/square_root.test.ts
@@ -9,20 +9,16 @@ describe("squareRoot", () => {
);
test.each([0, 1, 4, 9, 16, 25])(
- "should return correct rational square root value",
- () => {
- (n: number) => {
- expect(() => squareRoot(n)).toBeCloseTo(Math.sqrt(n));
- };
+ "should return correct rational square root value for %i",
+ (n: number) => {
+ expect(squareRoot(n)).toBeCloseTo(Math.sqrt(n));
}
);
test.each([2, 15, 20, 40, 99, 10032])(
- "should return correct irrational square root value",
- () => {
- (n: number) => {
- expect(() => squareRoot(n)).toBeCloseTo(Math.sqrt(n));
- };
+ "should return correct irrational square root value %i",
+ (n: number) => {
+ expect(squareRoot(n)).toBeCloseTo(Math.sqrt(n));
}
);
});
From 23ba61bf2aa8462786310d9b20d070c69d6a1743 Mon Sep 17 00:00:00 2001
From: Piotr Idzik <65706193+vil02@users.noreply.github.com>
Date: Wed, 14 Feb 2024 16:45:20 +0100
Subject: [PATCH 12/26] style: fix basic eslint warnings (#230)
---
backtracking/all_combinations_of_size_k.ts | 4 ++--
bit_manipulation/add_binary.ts | 2 +-
data_structures/heap/heap.ts | 8 +++----
data_structures/heap/test/heap.test.ts | 6 ++---
data_structures/queue/linked_queue.ts | 2 +-
.../stack/test/linked_list_stack.test.ts | 2 +-
dynamic_programming/knapsack.ts | 2 +-
graph/bellman_ford.ts | 2 +-
graph/dijkstra.ts | 6 ++---
graph/floyd_warshall.ts | 4 ++--
graph/johnson.ts | 14 +++++------
graph/kosajaru.ts | 10 ++++----
graph/kruskal.ts | 6 ++---
graph/prim.ts | 10 ++++----
graph/tarjan.ts | 12 +++++-----
graph/test/bellman_ford.test.ts | 12 +++++-----
graph/test/dijkstra.test.ts | 8 +++----
graph/test/floyd_warshall.test.ts | 10 ++++----
graph/test/johnson.test.ts | 22 ++++++++---------
graph/test/kruskal.test.ts | 22 ++++++++---------
graph/test/prim.test.ts | 24 +++++++++----------
maths/calculate_median.ts | 4 ++--
maths/matrix_multiplication.ts | 2 +-
maths/pascals_triangle.ts | 6 ++---
maths/perfect_number.ts | 2 +-
maths/prime_factorization.ts | 2 +-
sorts/bubble_sort.ts | 2 +-
sorts/quick_select.ts | 2 +-
sorts/swap_sort.ts | 2 +-
sorts/test/merge_sort.test.ts | 6 ++---
30 files changed, 108 insertions(+), 108 deletions(-)
diff --git a/backtracking/all_combinations_of_size_k.ts b/backtracking/all_combinations_of_size_k.ts
index c2316982..23ee3760 100644
--- a/backtracking/all_combinations_of_size_k.ts
+++ b/backtracking/all_combinations_of_size_k.ts
@@ -10,8 +10,8 @@
* and repeat the same process for the next number.
*/
export function generateCombinations(n: number, k: number): number[][] {
- let combinationsAcc: number[][] = [];
- let currentCombination: number[] = [];
+ const combinationsAcc: number[][] = [];
+ const currentCombination: number[] = [];
function generateAllCombos(
n: number,
diff --git a/bit_manipulation/add_binary.ts b/bit_manipulation/add_binary.ts
index ebc05440..38ca43af 100644
--- a/bit_manipulation/add_binary.ts
+++ b/bit_manipulation/add_binary.ts
@@ -8,7 +8,7 @@
export function addBinary(firstBinaryNo: string, secondBinaryNo: string): string {
let lengthOfFirstNumber: number = firstBinaryNo.length - 1;
let lengthOfSecondNumber: number = secondBinaryNo.length - 1;
- let solution: string[] = [];
+ const solution: string[] = [];
let carry: number = 0;
while ( lengthOfFirstNumber >= 0 || lengthOfSecondNumber >= 0) {
diff --git a/data_structures/heap/heap.ts b/data_structures/heap/heap.ts
index 5f8e8974..b5ab0ebc 100644
--- a/data_structures/heap/heap.ts
+++ b/data_structures/heap/heap.ts
@@ -50,7 +50,7 @@ export abstract class Heap {
}
public extract(): T {
- let maxElement = this.heap[0];
+ const maxElement = this.heap[0];
this.heap[0] = this.heap[this.size() - 1];
this.heap.pop();
this.sinkDown();
@@ -162,8 +162,8 @@ export class PriorityQueue extends MinHeap {
}
protected swap(a: number, b: number) {
- let akey = this.keys_index(this.heap[a]);
- let bkey = this.keys_index(this.heap[b]);
+ const akey = this.keys_index(this.heap[a]);
+ const bkey = this.keys_index(this.heap[b]);
[this.keys[akey], this.keys[bkey]] = [this.keys[bkey], this.keys[akey]];
super.swap(a, b);
}
@@ -188,7 +188,7 @@ export class PriorityQueue extends MinHeap {
this.insert(value);
return;
}
- let key = this.keys[idx];
+ const key = this.keys[idx];
if (this.compare(this.heap[key], value)) {
// Do not do anything if the value in the heap already has a higher priority.
return;
diff --git a/data_structures/heap/test/heap.test.ts b/data_structures/heap/test/heap.test.ts
index 9dc8f041..3b90fc9b 100644
--- a/data_structures/heap/test/heap.test.ts
+++ b/data_structures/heap/test/heap.test.ts
@@ -8,7 +8,7 @@ describe("MaxHeap", () => {
beforeEach(() => {
heap = new MaxHeap();
- for (let element of elements) {
+ for (const element of elements) {
heap.insert(element);
}
});
@@ -61,7 +61,7 @@ describe("MinHeap", () => {
beforeEach(() => {
heap = new MinHeap();
- for (let element of elements) {
+ for (const element of elements) {
heap.insert(element);
}
});
@@ -106,7 +106,7 @@ describe("MinHeap", () => {
});
it("should increase priority", () => {
- let heap = new PriorityQueue((a: number) => { return a; }, elements.length);
+ const heap = new PriorityQueue((a: number) => { return a; }, elements.length);
elements.forEach((element: number) => {
heap.insert(element);
});
diff --git a/data_structures/queue/linked_queue.ts b/data_structures/queue/linked_queue.ts
index c67c8285..bc90bd52 100644
--- a/data_structures/queue/linked_queue.ts
+++ b/data_structures/queue/linked_queue.ts
@@ -55,7 +55,7 @@ export class LinkedQueue implements Queue {
}
this.size--;
- let head = this.head; // We store the head in order not to lose track of it
+ const head = this.head; // We store the head in order not to lose track of it
this.head = this.head.next; // Update the the head to the next node
return head.value; // Return the value of the head
}
diff --git a/data_structures/stack/test/linked_list_stack.test.ts b/data_structures/stack/test/linked_list_stack.test.ts
index 2efc03d3..54f47c48 100644
--- a/data_structures/stack/test/linked_list_stack.test.ts
+++ b/data_structures/stack/test/linked_list_stack.test.ts
@@ -1,7 +1,7 @@
import { LinkedListStack } from "../linked_list_stack";
describe("Linked List Stack", () => {
- let stack: LinkedListStack = new LinkedListStack(4);
+ const stack: LinkedListStack = new LinkedListStack(4);
stack.push(1);
stack.push(2);
diff --git a/dynamic_programming/knapsack.ts b/dynamic_programming/knapsack.ts
index 9be8a41a..f4026b1d 100644
--- a/dynamic_programming/knapsack.ts
+++ b/dynamic_programming/knapsack.ts
@@ -23,7 +23,7 @@ export const knapsack = (
const numberOfItems = weights.length;
// Declaring a data structure to store calculated states/values
- let dp: number[][] = new Array(numberOfItems + 1);
+ const dp: number[][] = new Array(numberOfItems + 1);
for (let i = 0; i < dp.length; i++) {
// Placing an array at each index of dp to make it a 2d matrix
diff --git a/graph/bellman_ford.ts b/graph/bellman_ford.ts
index 70e326d2..d3a901b3 100644
--- a/graph/bellman_ford.ts
+++ b/graph/bellman_ford.ts
@@ -12,7 +12,7 @@
export const bellmanFord = (graph: [number, number][][], start: number): number[] | undefined => {
// We save the shortest distance to each node in `distances`. If a node is
// unreachable from the start node, its distance is Infinity.
- let distances = Array(graph.length).fill(Infinity);
+ const distances = Array(graph.length).fill(Infinity);
distances[start] = 0;
// On the i'th iteration, we compute all shortest paths that consists of i+1
diff --git a/graph/dijkstra.ts b/graph/dijkstra.ts
index 1d5c05ae..edec2746 100644
--- a/graph/dijkstra.ts
+++ b/graph/dijkstra.ts
@@ -13,17 +13,17 @@ import { MinHeap, PriorityQueue } from '../data_structures/heap/heap';
export const dijkstra = (graph: [number, number][][], start: number): number[] => {
// We use a priority queue to make sure we always visit the closest node. The
// queue makes comparisons based on path weights.
- let priorityQueue = new PriorityQueue((a: [number, number]) => { return a[0] }, graph.length, (a: [number, number], b: [number, number]) => { return a[1] < b[1] });
+ const priorityQueue = new PriorityQueue((a: [number, number]) => { return a[0] }, graph.length, (a: [number, number], b: [number, number]) => { return a[1] < b[1] });
priorityQueue.insert([start, 0]);
// We save the shortest distance to each node in `distances`. If a node is
// unreachable from the start node, its distance is Infinity.
- let distances = Array(graph.length).fill(Infinity);
+ const distances = Array(graph.length).fill(Infinity);
distances[start] = 0;
while (priorityQueue.size() > 0) {
const [node, _] = priorityQueue.extract();
graph[node].forEach(([child, weight]) => {
- let new_distance = distances[node] + weight;
+ const new_distance = distances[node] + weight;
if (new_distance < distances[child]) {
// Found a new shortest path to child node. Record its distance and add child to the queue.
// If the child already exists in the queue, the priority will be updated. This will make sure the queue will be at most size V (number of vertices).
diff --git a/graph/floyd_warshall.ts b/graph/floyd_warshall.ts
index c8addc46..372b6712 100644
--- a/graph/floyd_warshall.ts
+++ b/graph/floyd_warshall.ts
@@ -10,12 +10,12 @@
*/
export const floydWarshall = (graph: number[][]): number[][] => {
let distances = structuredClone(graph);
- let N = graph.length;
+ const N = graph.length;
// We begin by setting the weighted adjacency matrix as the shortest paths.
// For the k'th iteration, we try to relax the shortest paths by including node k in the path.
for (let k = 0; k < N; ++k) {
- let newDistances = [];
+ const newDistances = [];
for (let i = 0; i < N; ++i) {
newDistances.push(Array(N).fill(Infinity));
}
diff --git a/graph/johnson.ts b/graph/johnson.ts
index 7eac28ac..ea0204c7 100644
--- a/graph/johnson.ts
+++ b/graph/johnson.ts
@@ -12,25 +12,25 @@ import { dijkstra } from './dijkstra'
* @see https://en.wikipedia.org/wiki/Johnson%27s_algorithm
*/
export const johnson = (graph: [number, number][][]): number[][] | undefined => {
- let N = graph.length;
+ const N = graph.length;
// Add a new node and 0 weighted edges from the new node to all existing nodes.
- let newNodeGraph = structuredClone(graph);
- let newNode: [number, number][] = [];
+ const newNodeGraph = structuredClone(graph);
+ const newNode: [number, number][] = [];
for (let i = 0; i < N; ++i) {
newNode.push([i, 0]);
}
newNodeGraph.push(newNode);
// Compute distances from the new node to existing nodes using the Bellman-Ford algorithm.
- let adjustedGraph = bellmanFord(newNodeGraph, N);
+ const adjustedGraph = bellmanFord(newNodeGraph, N);
if (adjustedGraph === undefined) {
// Found a negative weight cycle.
return undefined;
}
for (let i = 0; i < N; ++i) {
- for (let edge of graph[i]) {
+ for (const edge of graph[i]) {
// Adjust edge weights using the Bellman Ford output weights. This ensure that:
// 1. Each weight is non-negative. This is required for the Dijkstra algorithm.
// 2. The shortest path from node i to node j consists of the same nodes with or without adjustment.
@@ -38,10 +38,10 @@ export const johnson = (graph: [number, number][][]): number[][] | undefined =>
}
}
- let shortestPaths: number[][] = [];
+ const shortestPaths: number[][] = [];
for (let i = 0; i < N; ++i) {
// Compute Dijkstra weights for each node and re-adjust weights to their original values.
- let dijkstraShorestPaths = dijkstra(graph, i);
+ const dijkstraShorestPaths = dijkstra(graph, i);
for (let j = 0; j < N; ++j) {
dijkstraShorestPaths[j] += adjustedGraph[j] - adjustedGraph[i];
}
diff --git a/graph/kosajaru.ts b/graph/kosajaru.ts
index 32338e76..d1498b0b 100644
--- a/graph/kosajaru.ts
+++ b/graph/kosajaru.ts
@@ -14,7 +14,7 @@ const getNodePriorities = (graph: number[][], visited: boolean[], stack: number[
// Return the transpose of graph. The tranpose of a directed graph is a graph where each of the edges are flipped.
const transpose = (graph: number[][]): number[][] => {
- let transposedGraph = Array(graph.length);
+ const transposedGraph = Array(graph.length);
for (let i = 0; i < graph.length; ++i) {
transposedGraph[i] = [];
}
@@ -52,20 +52,20 @@ const gatherScc = (graph: number[][], visited: boolean[], node: number, scc: num
* @see https://en.wikipedia.org/wiki/Kosaraju%27s_algorithm
*/
export const kosajaru = (graph: number[][]): number[][] => {
- let visited = Array(graph.length).fill(false);
+ const visited = Array(graph.length).fill(false);
- let stack: number[] = [];
+ const stack: number[] = [];
for (let i = 0; i < graph.length; ++i) {
getNodePriorities(graph, visited, stack, i);
}
const transposedGraph = transpose(graph);
- let sccs = [];
+ const sccs = [];
visited.fill(false);
for (let i = stack.length - 1; i >= 0; --i) {
if (!visited[stack[i]]) {
- let scc: number[] = [];
+ const scc: number[] = [];
gatherScc(transposedGraph, visited, stack[i], scc);
sccs.push(scc);
}
diff --git a/graph/kruskal.ts b/graph/kruskal.ts
index 073b62b1..750eb15f 100644
--- a/graph/kruskal.ts
+++ b/graph/kruskal.ts
@@ -13,15 +13,15 @@ import { DisjointSet } from '../data_structures/disjoint_set/disjoint_set';
*/
export const kruskal = (edges: Edge[], num_vertices: number): [Edge[], number] => {
let cost = 0;
- let minimum_spanning_tree = [];
+ const minimum_spanning_tree = [];
// Use a disjoint set to quickly join sets and find if vertices live in different sets
- let sets = new DisjointSet(num_vertices);
+ const sets = new DisjointSet(num_vertices);
// Sort the edges in ascending order by weight so that we can greedily add cheaper edges to the tree
edges.sort((a, b) => a.weight - b.weight);
- for (let edge of edges) {
+ for (const edge of edges) {
if (sets.find(edge.a) !== sets.find(edge.b)) {
// Node A and B live in different sets. Add edge(a, b) to the tree and join the nodes' sets together.
minimum_spanning_tree.push(edge);
diff --git a/graph/prim.ts b/graph/prim.ts
index 5c36479a..722c1e16 100644
--- a/graph/prim.ts
+++ b/graph/prim.ts
@@ -13,11 +13,11 @@ export const prim = (graph: [number, number][][]): [Edge[], number] => {
if (graph.length == 0) {
return [[], 0];
}
- let minimum_spanning_tree: Edge[] = [];
+ const minimum_spanning_tree: Edge[] = [];
let total_weight = 0;
- let priorityQueue = new PriorityQueue((e: Edge) => { return e.b }, graph.length, (a: Edge, b: Edge) => { return a.weight < b.weight });
- let visited = new Set();
+ const priorityQueue = new PriorityQueue((e: Edge) => { return e.b }, graph.length, (a: Edge, b: Edge) => { return a.weight < b.weight });
+ const visited = new Set();
// Start from the 0'th node. For fully connected graphs, we can start from any node and still produce the MST.
visited.add(0);
@@ -25,7 +25,7 @@ export const prim = (graph: [number, number][][]): [Edge[], number] => {
while (!priorityQueue.isEmpty()) {
// We have already visited vertex `edge.a`. If we have not visited `edge.b` yet, we add its outgoing edges to the PriorityQueue.
- let edge = priorityQueue.extract();
+ const edge = priorityQueue.extract();
if (visited.has(edge.b)) {
continue;
}
@@ -40,7 +40,7 @@ export const prim = (graph: [number, number][][]): [Edge[], number] => {
const add_children = (graph: [number, number][][], priorityQueue: PriorityQueue, node: number) => {
for (let i = 0; i < graph[node].length; ++i) {
- let out_edge = graph[node][i];
+ const out_edge = graph[node][i];
// By increasing the priority, we ensure we only add each vertex to the queue one time, and the queue will be at most size V.
priorityQueue.increasePriority(out_edge[0], new Edge(node, out_edge[0], out_edge[1]));
}
diff --git a/graph/tarjan.ts b/graph/tarjan.ts
index 7f2a2454..27de35a7 100644
--- a/graph/tarjan.ts
+++ b/graph/tarjan.ts
@@ -15,14 +15,14 @@ export const tarjan = (graph: number[][]): number[][] => {
let index = 0;
// The order in which we discover nodes
- let discovery: number[] = Array(graph.length);
+ const discovery: number[] = Array(graph.length);
// For each node, holds the furthest ancestor it can reach
- let low: number[] = Array(graph.length).fill(undefined);
+ const low: number[] = Array(graph.length).fill(undefined);
// Holds the nodes we have visited in a DFS traversal and are considering to group into a SCC
- let stack: number[] = [];
+ const stack: number[] = [];
// Holds the elements in the stack.
- let stackContains = Array(graph.length).fill(false);
- let sccs: number[][] = [];
+ const stackContains = Array(graph.length).fill(false);
+ const sccs: number[][] = [];
const dfs = (node: number) => {
discovery[node] = index;
@@ -46,7 +46,7 @@ export const tarjan = (graph: number[][]): number[][] => {
if (discovery[node] == low[node]) {
// node is the root of a SCC. Gather the SCC's nodes from the stack.
- let scc: number[] = [];
+ const scc: number[] = [];
let i;
for (i = stack.length - 1; stack[i] != node; --i) {
scc.push(stack[i]);
diff --git a/graph/test/bellman_ford.test.ts b/graph/test/bellman_ford.test.ts
index 77928a63..f99ee907 100644
--- a/graph/test/bellman_ford.test.ts
+++ b/graph/test/bellman_ford.test.ts
@@ -1,7 +1,7 @@
import { bellmanFord } from "../bellman_ford";
const init_graph = (N: number): [number, number][][] => {
- let graph = Array(N);
+ const graph = Array(N);
for (let i = 0; i < N; ++i) {
graph[i] = [];
}
@@ -16,7 +16,7 @@ describe("bellmanFord", () => {
}
it("should return the correct value", () => {
- let graph = init_graph(9);
+ const graph = init_graph(9);
add_edge(graph, 0, 1, 4);
add_edge(graph, 0, 7, 8);
add_edge(graph, 1, 2, 8);
@@ -38,7 +38,7 @@ describe("bellmanFord", () => {
expect(bellmanFord([[]], 0)).toStrictEqual([0]);
});
- let linear_graph = init_graph(4);
+ const linear_graph = init_graph(4);
add_edge(linear_graph, 0, 1, 1);
add_edge(linear_graph, 1, 2, 2);
add_edge(linear_graph, 2, 3, 3);
@@ -49,7 +49,7 @@ describe("bellmanFord", () => {
}
);
- let unreachable_graph = init_graph(3);
+ const unreachable_graph = init_graph(3);
add_edge(unreachable_graph, 0, 1, 1);
test.each([[0, [0, 1, Infinity]], [1, [1, 0, Infinity]], [2, [Infinity, Infinity, 0]]])(
"correct result for graph with unreachable nodes with source node %i",
@@ -61,7 +61,7 @@ describe("bellmanFord", () => {
describe("bellmanFord negative cycle graphs", () => {
it("should returned undefined for 2-node graph with negative cycle", () => {
- let basic = init_graph(2);
+ const basic = init_graph(2);
basic[0].push([1, 2]);
basic[1].push([0, -3]);
expect(bellmanFord(basic, 0)).toStrictEqual(undefined);
@@ -69,7 +69,7 @@ describe("bellmanFord negative cycle graphs", () => {
});
it("should returned undefined for graph with negative cycle", () => {
- let negative = init_graph(5);
+ const negative = init_graph(5);
negative[0].push([1, 6]);
negative[0].push([3, 7]);
negative[1].push([2, 5]);
diff --git a/graph/test/dijkstra.test.ts b/graph/test/dijkstra.test.ts
index eacf2e68..dfd0f436 100644
--- a/graph/test/dijkstra.test.ts
+++ b/graph/test/dijkstra.test.ts
@@ -3,7 +3,7 @@ import { dijkstra } from "../dijkstra";
describe("dijkstra", () => {
const init_graph = (N: number): [number, number][][] => {
- let graph = Array(N);
+ const graph = Array(N);
for (let i = 0; i < N; ++i) {
graph[i] = [];
}
@@ -16,7 +16,7 @@ describe("dijkstra", () => {
}
it("should return the correct value", () => {
- let graph = init_graph(9);
+ const graph = init_graph(9);
add_edge(graph, 0, 1, 4);
add_edge(graph, 0, 7, 8);
add_edge(graph, 1, 2, 8);
@@ -38,7 +38,7 @@ describe("dijkstra", () => {
expect(dijkstra([[]], 0)).toStrictEqual([0]);
});
- let linear_graph = init_graph(4);
+ const linear_graph = init_graph(4);
add_edge(linear_graph, 0, 1, 1);
add_edge(linear_graph, 1, 2, 2);
add_edge(linear_graph, 2, 3, 3);
@@ -49,7 +49,7 @@ describe("dijkstra", () => {
}
);
- let unreachable_graph = init_graph(3);
+ const unreachable_graph = init_graph(3);
add_edge(unreachable_graph, 0, 1, 1);
test.each([[0, [0, 1, Infinity]], [1, [1, 0, Infinity]], [2, [Infinity, Infinity, 0]]])(
"correct result for graph with unreachable nodes with source node %i",
diff --git a/graph/test/floyd_warshall.test.ts b/graph/test/floyd_warshall.test.ts
index 33cc67dc..81c04bdf 100644
--- a/graph/test/floyd_warshall.test.ts
+++ b/graph/test/floyd_warshall.test.ts
@@ -14,16 +14,16 @@ describe("floydWarshall", () => {
});
it("should return the correct value", () => {
- let graph = [];
+ const graph = [];
for (let i = 1; i <= 5; ++i) {
- let arr = [];
+ const arr = [];
for (let j = 1; j <= 5; ++j) {
arr.push(i * j);
}
graph.push(arr);
}
- let expected = [
+ const expected = [
[ 1, 2, 3, 4, 5 ],
[ 2, 4, 5, 6, 7 ],
[ 3, 5, 6, 7, 8 ],
@@ -34,7 +34,7 @@ describe("floydWarshall", () => {
});
it("should return the correct value", () => {
- let graph = [
+ const graph = [
[0, 4, Infinity, Infinity, Infinity, Infinity, Infinity, 8, Infinity],
[4, 0, 8, Infinity, Infinity, Infinity, Infinity, 11, Infinity],
[Infinity, 8, 0, 7, Infinity, 4, Infinity, Infinity, 2],
@@ -46,7 +46,7 @@ describe("floydWarshall", () => {
[Infinity, Infinity, 2, Infinity, Infinity, Infinity, 6, 7, 0]
];
- let expected = [
+ const expected = [
[0, 4, 12, 19, 21, 11, 9, 8, 14],
[4, 0, 8, 15, 22, 12, 12, 11, 10],
[12, 8, 0, 7, 14, 4, 6, 7, 2],
diff --git a/graph/test/johnson.test.ts b/graph/test/johnson.test.ts
index 24600879..625bb993 100644
--- a/graph/test/johnson.test.ts
+++ b/graph/test/johnson.test.ts
@@ -3,7 +3,7 @@ import { johnson } from "../johnson";
describe("johnson", () => {
const init_graph = (N: number): [number, number][][] => {
- let graph = Array(N);
+ const graph = Array(N);
for (let i = 0; i < N; ++i) {
graph[i] = [];
}
@@ -16,7 +16,7 @@ describe("johnson", () => {
}
it("should return the correct value", () => {
- let graph = init_graph(9);
+ const graph = init_graph(9);
add_edge(graph, 0, 1, 4);
add_edge(graph, 0, 7, 8);
add_edge(graph, 1, 2, 8);
@@ -32,7 +32,7 @@ describe("johnson", () => {
add_edge(graph, 6, 8, 6);
add_edge(graph, 7, 8, 7);
- let expected = [
+ const expected = [
[0, 4, 12, 19, 21, 11, 9, 8, 14],
[4, 0, 8, 15, 22, 12, 12, 11, 10],
[12, 8, 0, 7, 14, 4, 6, 7, 2],
@@ -47,14 +47,14 @@ describe("johnson", () => {
});
it("should return the correct value for graph with negative weights", () => {
- let graph = init_graph(4);
+ const graph = init_graph(4);
graph[0].push([1, -5]);
graph[0].push([2, 2]);
graph[0].push([3, 3]);
graph[1].push([2, 4]);
graph[2].push([3, 1]);
- let expected = [
+ const expected = [
[ 0, -5, -1, 0 ],
[ Infinity, 0, 4, 5 ],
[ Infinity, Infinity, 0, 1 ],
@@ -64,13 +64,13 @@ describe("johnson", () => {
});
it("should return the undefined for two node graph with negative-weight cycle", () => {
- let graph = init_graph(2);
+ const graph = init_graph(2);
add_edge(graph, 0, 1, -1);
expect(johnson(graph)).toStrictEqual(undefined);
});
it("should return the undefined for three node graph with negative-weight cycle", () => {
- let graph = init_graph(3);
+ const graph = init_graph(3);
graph[0].push([1, -1]);
graph[0].push([2, 7]);
graph[1].push([2, -5]);
@@ -87,20 +87,20 @@ describe("johnson", () => {
});
it("should return the correct value for a linear graph", () => {
- let linear_graph = init_graph(4);
+ const linear_graph = init_graph(4);
add_edge(linear_graph, 0, 1, 1);
add_edge(linear_graph, 1, 2, 2);
add_edge(linear_graph, 2, 3, 3);
- let expected = [[0, 1, 3, 6 ], [1, 0, 2, 5], [3, 2, 0, 3], [6, 5, 3, 0]];
+ const expected = [[0, 1, 3, 6 ], [1, 0, 2, 5], [3, 2, 0, 3], [6, 5, 3, 0]];
expect(johnson(linear_graph)).toStrictEqual(expected);
});
it("should return the correct value for a linear graph with unreachable node", () => {
- let linear_graph = init_graph(3);
+ const linear_graph = init_graph(3);
add_edge(linear_graph, 0, 1, 1);
- let expected = [[0, 1, Infinity], [1, 0, Infinity], [Infinity, Infinity, 0]];
+ const expected = [[0, 1, Infinity], [1, 0, Infinity], [Infinity, Infinity, 0]];
expect(johnson(linear_graph)).toStrictEqual(expected);
});
})
diff --git a/graph/test/kruskal.test.ts b/graph/test/kruskal.test.ts
index 7f3db6c0..f5490931 100644
--- a/graph/test/kruskal.test.ts
+++ b/graph/test/kruskal.test.ts
@@ -1,12 +1,12 @@
import { Edge, kruskal } from "../kruskal";
-let test_graph = (expected_tree_edges: Edge[], other_edges: Edge[], num_vertices: number, expected_cost: number) => {
- let [tree_edges, cost] = kruskal(expected_tree_edges.concat(other_edges), num_vertices);
+const test_graph = (expected_tree_edges: Edge[], other_edges: Edge[], num_vertices: number, expected_cost: number) => {
+ const [tree_edges, cost] = kruskal(expected_tree_edges.concat(other_edges), num_vertices);
expect(cost).toStrictEqual(expected_cost);
- for (let expected_edge of expected_tree_edges) {
+ for (const expected_edge of expected_tree_edges) {
expect(tree_edges.includes(expected_edge)).toBeTruthy();
}
- for (let unexpected_edge of other_edges) {
+ for (const unexpected_edge of other_edges) {
expect(tree_edges.includes(unexpected_edge)).toBeFalsy();
}
};
@@ -28,13 +28,13 @@ describe("kruskal", () => {
});
it("should return the correct value", () => {
- let expected_tree_edges = [
+ const expected_tree_edges = [
new Edge(0, 1, 1),
new Edge(1, 3, 2),
new Edge(2, 3, 3),
];
- let other_edges = [
+ const other_edges = [
new Edge(0, 2, 4),
new Edge(0, 3, 5),
new Edge(1, 2, 6),
@@ -44,7 +44,7 @@ describe("kruskal", () => {
});
it("should return the correct value", () => {
- let expected_tree_edges = [
+ const expected_tree_edges = [
new Edge(0, 2, 2),
new Edge(1, 3, 9),
new Edge(2, 6, 74),
@@ -56,7 +56,7 @@ describe("kruskal", () => {
new Edge(8, 9, 2),
]
- let other_edges = [
+ const other_edges = [
new Edge(0, 1, 10),
new Edge(2, 4, 47),
new Edge(4, 5, 42),
@@ -69,12 +69,12 @@ describe("kruskal", () => {
describe("kruskal forest", () => {
it("should return empty tree for forest of 2 node trees", () => {
- let edges = [new Edge(0, 1, 10), new Edge(2, 3, 15)];
+ const edges = [new Edge(0, 1, 10), new Edge(2, 3, 15)];
test_graph(edges, [], 4, 25);
});
it("should return the correct value", () => {
- let expected_tree_edges = [
+ const expected_tree_edges = [
// Tree 1
new Edge(0, 2, 2),
new Edge(1, 3, 9),
@@ -92,7 +92,7 @@ describe("kruskal forest", () => {
new Edge(12, 13, 3),
]
- let other_edges = [
+ const other_edges = [
// Tree 1
new Edge(0, 1, 10),
new Edge(2, 4, 47),
diff --git a/graph/test/prim.test.ts b/graph/test/prim.test.ts
index 763f1716..b9dac96c 100644
--- a/graph/test/prim.test.ts
+++ b/graph/test/prim.test.ts
@@ -1,30 +1,30 @@
import { Edge, prim } from "../prim";
-let edge_equal = (x: Edge, y: Edge): boolean => {
+const edge_equal = (x: Edge, y: Edge): boolean => {
return (x.a == y.a && x.b == y.b) || (x.a == y.b && x.b == y.a) && x.weight == y.weight;
}
-let test_graph = (expected_tree_edges: Edge[], other_edges: Edge[], num_vertices: number, expected_cost: number) => {
+const test_graph = (expected_tree_edges: Edge[], other_edges: Edge[], num_vertices: number, expected_cost: number) => {
// First make sure the graph is undirected
- let graph: [number, number][][] = [];
+ const graph: [number, number][][] = [];
for (let _ = 0; _ < num_vertices; ++_) {
graph.push([]);
}
- for (let edge of expected_tree_edges) {
+ for (const edge of expected_tree_edges) {
graph[edge.a].push([edge.b, edge.weight]);
graph[edge.b].push([edge.a, edge.weight]);
}
- for (let edge of other_edges) {
+ for (const edge of other_edges) {
graph[edge.a].push([edge.b, edge.weight]);
graph[edge.b].push([edge.a, edge.weight]);
}
- let [tree_edges, cost] = prim(graph);
+ const [tree_edges, cost] = prim(graph);
expect(cost).toStrictEqual(expected_cost);
- for (let expected_edge of expected_tree_edges) {
+ for (const expected_edge of expected_tree_edges) {
expect(tree_edges.find(edge => edge_equal(edge, expected_edge))).toBeTruthy();
}
- for (let unexpected_edge of other_edges) {
+ for (const unexpected_edge of other_edges) {
expect(tree_edges.find(edge => edge_equal(edge, unexpected_edge))).toBeFalsy();
}
};
@@ -45,13 +45,13 @@ describe("prim", () => {
});
it("should return the correct value", () => {
- let expected_tree_edges = [
+ const expected_tree_edges = [
new Edge(0, 1, 1),
new Edge(1, 3, 2),
new Edge(3, 2, 3),
];
- let other_edges = [
+ const other_edges = [
new Edge(0, 2, 4),
new Edge(0, 3, 5),
new Edge(1, 2, 6),
@@ -61,7 +61,7 @@ describe("prim", () => {
});
it("should return the correct value", () => {
- let expected_tree_edges = [
+ const expected_tree_edges = [
new Edge(0, 2, 2),
new Edge(1, 3, 9),
new Edge(2, 6, 74),
@@ -73,7 +73,7 @@ describe("prim", () => {
new Edge(8, 9, 2),
]
- let other_edges = [
+ const other_edges = [
new Edge(0, 1, 10),
new Edge(2, 4, 47),
new Edge(4, 5, 42),
diff --git a/maths/calculate_median.ts b/maths/calculate_median.ts
index 5a6c98bc..27c8cac4 100644
--- a/maths/calculate_median.ts
+++ b/maths/calculate_median.ts
@@ -16,10 +16,10 @@ export const calculateMedian = (numbers: number[]): number => {
const totalNumbers = numbers.length;
if (totalNumbers % 2 === 0) {
- let index = totalNumbers / 2;
+ const index = totalNumbers / 2;
return (numbers[index - 1] + numbers[index]) / 2;
} else {
- let index = (totalNumbers + 1) / 2;
+ const index = (totalNumbers + 1) / 2;
return numbers[index - 1];
}
};
diff --git a/maths/matrix_multiplication.ts b/maths/matrix_multiplication.ts
index 78b861aa..99a475f9 100644
--- a/maths/matrix_multiplication.ts
+++ b/maths/matrix_multiplication.ts
@@ -13,7 +13,7 @@ function matrixMultiplication(matA: number[][], b: number[][]): number[][];
function matrixMultiplication(matA: number[][], b: number): number[][];
function matrixMultiplication(matA: number[][], b: number[]): number[];
-function matrixMultiplication(matA: number[][], b: any): Number[][] | Number[] | null {
+function matrixMultiplication(matA: number[][], b: any): number[][] | number[] | null {
let matC: any = null;
if (typeof b === 'number') {
diff --git a/maths/pascals_triangle.ts b/maths/pascals_triangle.ts
index cce4bfd1..337c77c6 100644
--- a/maths/pascals_triangle.ts
+++ b/maths/pascals_triangle.ts
@@ -15,15 +15,15 @@
* @see https://en.wikipedia.org/wiki/Pascal's_triangle
*/
export const pascalsTriangle = (n: number): number[] => {
- let arr: number[][] = [];
+ const arr: number[][] = [];
for (let i: number = 0; i < n; i++) {
if (i === 0) {
arr.push([1]);
continue;
}
- let lastRow: number[] = arr[i - 1];
- let temp: number[] = [];
+ const lastRow: number[] = arr[i - 1];
+ const temp: number[] = [];
for (let j: number = 0; j < lastRow.length + 1; j++) {
if (j === 0 || j === lastRow.length) {
temp.push(1);
diff --git a/maths/perfect_number.ts b/maths/perfect_number.ts
index c528321a..9dec9024 100644
--- a/maths/perfect_number.ts
+++ b/maths/perfect_number.ts
@@ -13,7 +13,7 @@ export const isPerfectNumber = (n: number): boolean => {
return false;
}
let sum = 1;
- let sqrt = Math.sqrt(n);
+ const sqrt = Math.sqrt(n);
for (let i = 2; i < sqrt; i++) {
if (n % i === 0) {
sum += i + n / i;
diff --git a/maths/prime_factorization.ts b/maths/prime_factorization.ts
index 19032730..872422e1 100644
--- a/maths/prime_factorization.ts
+++ b/maths/prime_factorization.ts
@@ -7,7 +7,7 @@
* @example factorize(5) = Map {5 => 1}
*/
export const factorize = (n: number): Map => {
- let result: Map = new Map();
+ const result: Map = new Map();
for (let i = 2; i * i <= n; i++) {
while (n % i == 0) {
diff --git a/sorts/bubble_sort.ts b/sorts/bubble_sort.ts
index 8bbd1a21..3086051e 100644
--- a/sorts/bubble_sort.ts
+++ b/sorts/bubble_sort.ts
@@ -22,7 +22,7 @@ export const bubbleSort = (arr: number[]): number[] => {
for (let i = 0; i < arr.length; i++) {
for (let j = 0; j < arr.length-1; j++) { //iterating till the 2nd last element of array
if (arr[j] > arr[j+1]) { //current indexed number > next indexed number
- let temp: number = arr[j]; //swapping two numbers
+ const temp: number = arr[j]; //swapping two numbers
arr[j] = arr[j+1];
arr[j+1] = temp;
}
diff --git a/sorts/quick_select.ts b/sorts/quick_select.ts
index 23381ee2..91d03bfc 100644
--- a/sorts/quick_select.ts
+++ b/sorts/quick_select.ts
@@ -25,7 +25,7 @@ export const QuickSelect = (
}
// Partition the array
- let pivotIndex = partition(array, left, right);
+ const pivotIndex = partition(array, left, right);
// The pivot is in its final sorted position
if (k === pivotIndex) {
diff --git a/sorts/swap_sort.ts b/sorts/swap_sort.ts
index 68a83ced..722c33b5 100644
--- a/sorts/swap_sort.ts
+++ b/sorts/swap_sort.ts
@@ -12,7 +12,7 @@ export const minSwapsToSort = (inputArr: number[]): number => {
sortedArray.sort()
- let indexMap = new Map();
+ const indexMap = new Map();
for (let i = 0; i < inputArr.length; i++)
indexMap.set(inputArr[i],i);
diff --git a/sorts/test/merge_sort.test.ts b/sorts/test/merge_sort.test.ts
index 5b6f81fc..cc21b628 100644
--- a/sorts/test/merge_sort.test.ts
+++ b/sorts/test/merge_sort.test.ts
@@ -2,14 +2,14 @@ import { mergeSort } from "../merge_sort"
describe("Merge Sort", () => {
it("generating array with variable length and comparing with sorted array", () => {
- let arrLenArr = [10, 200, 40000]
+ const arrLenArr = [10, 200, 40000]
arrLenArr.forEach((arrLen: number) => {
- let inBuiltSortArr = Array(arrLen)
+ const inBuiltSortArr = Array(arrLen)
for (let i = 0; i < arrLen; i++) {
inBuiltSortArr[i] = Math.random() * 10000
}
- let mergeSortArray = inBuiltSortArr.slice()
+ const mergeSortArray = inBuiltSortArr.slice()
inBuiltSortArr.sort((a, b) => a - b)
expect(mergeSort(mergeSortArray)).toStrictEqual(inBuiltSortArr)
From b3a3bd7efa940f9436841aac36f35eb12b0a42fc Mon Sep 17 00:00:00 2001
From: Piotr Idzik <65706193+vil02@users.noreply.github.com>
Date: Sat, 2 Mar 2024 08:55:40 +0100
Subject: [PATCH 13/26] fix: handle the case when target is last in
`jumpSearch` (#231)
---
search/jump_search.ts | 6 +++---
search/test/jump_search.test.ts | 9 +++++++++
2 files changed, 12 insertions(+), 3 deletions(-)
diff --git a/search/jump_search.ts b/search/jump_search.ts
index 45b44e02..e79061d8 100644
--- a/search/jump_search.ts
+++ b/search/jump_search.ts
@@ -25,13 +25,13 @@ export const jumpSearch = (array: number[], target: number): number => {
let currentIdx: number = 0,
stepSize: number = Math.floor(Math.sqrt(array.length)),
nextIdx: number = stepSize;
-
+
while (array[nextIdx - 1] < target) {
currentIdx = nextIdx;
nextIdx += stepSize;
- if (nextIdx >= array.length) {
- nextIdx = array.length - 1;
+ if (nextIdx > array.length) {
+ nextIdx = array.length;
break;
}
}
diff --git a/search/test/jump_search.test.ts b/search/test/jump_search.test.ts
index 59737bdf..3687ccec 100644
--- a/search/test/jump_search.test.ts
+++ b/search/test/jump_search.test.ts
@@ -5,6 +5,15 @@ describe("Jump search", () => {
[[], 1, -1],
[[1, 2, 3, 4, 5], 4, 3],
[[1, 3, 5, 8, 9], 4, -1],
+ [[1, 3, 5, 8], 8, 3],
+ [[1, 3, 5, 8], 9, -1],
+ [[1, 3, 5, 8], 7, -1],
+ [[1, 3, 5, 8, 10], 10, 4],
+ [[1, 3, 5, 8, 10], 11, -1],
+ [[1, 3, 5, 8, 10], 9, -1],
+ [[5], 5, 0],
+ [[5], 100, -1],
+ [[], 100, -1],
])(
"of %o , searching for %o, expected %i",
(array: any[], target: any, index: number) => {
From 26ac72d61cbcf2b2c079afe2ae1b84c8056a5da5 Mon Sep 17 00:00:00 2001
From: Piotr Idzik <65706193+vil02@users.noreply.github.com>
Date: Mon, 4 Mar 2024 23:06:10 +0100
Subject: [PATCH 14/26] style: simplify `binaryLCM` (#233)
---
maths/lowest_common_multiple.ts | 8 --------
maths/test/lowest_common_multiple.test.ts | 17 ++++++++++-------
2 files changed, 10 insertions(+), 15 deletions(-)
diff --git a/maths/lowest_common_multiple.ts b/maths/lowest_common_multiple.ts
index ec852425..95d266d3 100644
--- a/maths/lowest_common_multiple.ts
+++ b/maths/lowest_common_multiple.ts
@@ -38,14 +38,6 @@ export const naiveLCM = (nums: number[]): number => {
//Note that due to utilizing GCF, which requires natural numbers, this method only accepts natural numbers.
export const binaryLCM = (a: number, b: number): number => {
- if (a < 0 || b < 0) {
- throw new Error("numbers must be positive to determine lowest common multiple");
- }
-
- if (!Number.isInteger(a) || !Number.isInteger(b)) {
- throw new Error("this method, which utilizes GCF, requires natural numbers.");
- }
-
return a * b / greatestCommonFactor([a, b]);
}
diff --git a/maths/test/lowest_common_multiple.test.ts b/maths/test/lowest_common_multiple.test.ts
index 55ea9a24..388dba28 100644
--- a/maths/test/lowest_common_multiple.test.ts
+++ b/maths/test/lowest_common_multiple.test.ts
@@ -29,10 +29,15 @@ describe("binaryLCM", () => {
},
);
- test("only whole numbers should be accepted", () => {
- expect(() => binaryLCM(-2, -3)).toThrowError(
- "numbers must be positive to determine lowest common multiple",
- );
+ test("only natural numbers should be accepted", () => {
+ expect(() => binaryLCM(-2, -3)).toThrowError();
+ expect(() => binaryLCM(2, -3)).toThrowError();
+ expect(() => binaryLCM(-2, 3)).toThrowError();
+ });
+
+ test("should throw when any of the inputs is not an int", () => {
+ expect(() => binaryLCM(1, 2.5)).toThrowError();
+ expect(() => binaryLCM(1.5, 2)).toThrowError();
});
});
@@ -45,9 +50,7 @@ describe("lowestCommonMultiple", () => {
);
test("only positive numbers should be accepted", () => {
- expect(() => lowestCommonMultiple([-2, -3])).toThrowError(
- "numbers must be positive to determine lowest common multiple",
- );
+ expect(() => lowestCommonMultiple([-2, -3])).toThrowError();
});
test("at least one number must be passed in", () => {
From c5b12db2f8008400e699bad44e2679f99bf00332 Mon Sep 17 00:00:00 2001
From: Shankha Suvra Dam <71999854+SpiderMath@users.noreply.github.com>
Date: Tue, 5 Mar 2024 11:19:38 +0530
Subject: [PATCH 15/26] feat: Added Double Factorial Iterative Implementation
(#187)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* Update DIRECTORY.md
* 🚀feat: added double factorial (iterative)
* Update DIRECTORY.md
* removed redundant if check, fix formatting
* Update DIRECTORY.md
---------
Co-authored-by: autoprettier
Co-authored-by: Lars Müller <34514239+appgurueu@users.noreply.github.com>
---
DIRECTORY.md | 2 ++
maths/double_factorial_iterative.ts | 29 +++++++++++++++++++
maths/test/double_factorial_iterative.test.ts | 7 +++++
3 files changed, 38 insertions(+)
create mode 100644 maths/double_factorial_iterative.ts
create mode 100644 maths/test/double_factorial_iterative.test.ts
diff --git a/DIRECTORY.md b/DIRECTORY.md
index 3e6e6418..185bae95 100644
--- a/DIRECTORY.md
+++ b/DIRECTORY.md
@@ -108,6 +108,7 @@
* [Calculate Median](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/maths/calculate_median.ts)
* [Degrees To Radians](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/maths/degrees_to_radians.ts)
* [Digit Sum](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/maths/digit_sum.ts)
+ * [Double Factorial Iterative](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/maths/double_factorial_iterative.ts)
* [Euler Totient](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/maths/euler_totient.ts)
* [Factorial](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/maths/factorial.ts)
* [Factors](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/maths/factors.ts)
@@ -128,6 +129,7 @@
* [Number Of Digits](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/maths/number_of_digits.ts)
* [Pascals Triangle](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/maths/pascals_triangle.ts)
* [Perfect Cube](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/maths/perfect_cube.ts)
+ * [Perfect Number](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/maths/perfect_number.ts)
* [Perfect Square](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/maths/perfect_square.ts)
* [Prime Factorization](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/maths/prime_factorization.ts)
* [Primes](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/maths/primes.ts)
diff --git a/maths/double_factorial_iterative.ts b/maths/double_factorial_iterative.ts
new file mode 100644
index 00000000..6044eca0
--- /dev/null
+++ b/maths/double_factorial_iterative.ts
@@ -0,0 +1,29 @@
+/**
+ * @function DoubleFactorialIterative
+ * @description Calculate the double factorial of a number (iterative implementation)
+ * @summary In mathematics, double factorial of a number n is denoted by n!!.
+ * It is not to be confused with (n!)!, which is the factorial function iterated twice.
+ * The double factorial is the product of all positive integers upto n that have the same parity (odd or even)
+ * as n.
+ * Therefore,
+ * 9!! = 9 . 7 . 5 . 3 . 1
+ * 10!! = 10 . 8 . 6 . 4 . 2
+ *
+ * Please note that for factorials of even numbers, the series ends at 2.
+ * @see [Wikipedia](https://en.wikipedia.org/wiki/Double_factorial)
+ * @see [Mathworld](https://mathworld.wolfram.com/DoubleFactorial.html)
+ * @see [GeeksForGeeks](https://www.geeksforgeeks.org/double-factorial/)
+ * @example DoubleFactorialIterative(4) = 8
+ * @example DoubleFactorialIterative(5) = 15
+ */
+const DoubleFactorialIterative = (n: number) => {
+ if(n < 0) throw new RangeError("The number needs to be non-negative")
+ let doubleFactorial = 1
+
+ for(let i = n; i > 0; i -= 2)
+ doubleFactorial *= i
+
+ return doubleFactorial
+}
+
+export { DoubleFactorialIterative }
diff --git a/maths/test/double_factorial_iterative.test.ts b/maths/test/double_factorial_iterative.test.ts
new file mode 100644
index 00000000..3c221785
--- /dev/null
+++ b/maths/test/double_factorial_iterative.test.ts
@@ -0,0 +1,7 @@
+import { DoubleFactorialIterative } from "../double_factorial_iterative";
+
+describe("Double Factorial", () => {
+ test.each([[4, 8], [5, 15], [10, 3840]])("%i!! = %i", (n, expected) => {
+ expect(DoubleFactorialIterative(n)).toBe(expected)
+ })
+})
\ No newline at end of file
From c2d7aa6895b6655d5c0a5aead130803645a1d2eb Mon Sep 17 00:00:00 2001
From: Piotr Idzik <65706193+vil02@users.noreply.github.com>
Date: Mon, 18 Mar 2024 18:33:33 +0100
Subject: [PATCH 16/26] Add and run prettier (#234)
* chore: add `prettier`
* style: run `prettier`
* chore: check formatting in CI
---
.github/workflows/ci.yml | 1 +
.gitpod.yml | 2 -
.prettierignore | 2 +
.prettierrc | 15 +
babel.config.js | 11 +-
backtracking/all_combinations_of_size_k.ts | 20 +-
backtracking/generateparentheses.ts | 26 +-
.../test/all_combinations_of_size_k.test.ts | 33 +-
backtracking/test/generateparentheses.test.ts | 140 +-
bit_manipulation/add_binary.ts | 37 +-
bit_manipulation/is_power_of_2.ts | 2 +-
bit_manipulation/is_power_of_4.ts | 3 +-
bit_manipulation/log_two.ts | 14 +-
bit_manipulation/test/add_binary.test.ts | 52 +-
bit_manipulation/test/is_power_of_2.test.ts | 25 +-
bit_manipulation/test/is_power_of_4.test.ts | 4 +-
bit_manipulation/test/log_two.test.ts | 15 +-
ciphers/test/xor_cipher.test.ts | 10 +-
data_structures/disjoint_set/disjoint_set.ts | 31 +-
.../disjoint_set/test/disjoint_set.test.ts | 32 +-
data_structures/heap/heap.ts | 158 +-
data_structures/heap/test/heap.test.ts | 200 +-
data_structures/list/doubly_linked_list.ts | 478 +-
data_structures/list/linked_list.ts | 22 +-
data_structures/list/singly_linked_list.ts | 149 +-
.../list/test/doubly_linked_list.test.ts | 36 +-
data_structures/list/test/linked_list.ts | 122 +-
.../list/test/singly_linked_list.test.ts | 6 +-
data_structures/map/hash_map.ts | 374 +-
data_structures/map/map.ts | 20 +-
data_structures/map/test/hash_map.test.ts | 218 +-
data_structures/queue/array_queue.ts | 96 +-
data_structures/queue/circular_queue.ts | 168 +-
data_structures/queue/linked_queue.ts | 150 +-
data_structures/queue/queue.ts | 12 +-
data_structures/queue/stack_queue.ts | 134 +-
.../queue/test/array_queue.test.ts | 4 +-
.../queue/test/circular_queue.test.ts | 96 +-
.../queue/test/linked_queue.test.ts | 4 +-
data_structures/queue/test/queue.ts | 100 +-
.../queue/test/stack_queue.test.ts | 6 +-
data_structures/set/hash_map_set.ts | 28 +-
data_structures/set/map_set.ts | 114 +-
data_structures/set/set.ts | 12 +-
data_structures/stack/linked_list_stack.ts | 126 +-
data_structures/stack/stack.ts | 22 +-
.../stack/test/linked_list_stack.test.ts | 50 +-
data_structures/stack/test/stack.test.ts | 82 +-
data_structures/tree/binary_search_tree.ts | 106 +-
.../tree/test/binary_search_tree.test.ts | 68 +-
data_structures/tries/test/tries.test.ts | 52 +-
data_structures/tries/tries.ts | 24 +-
dynamic_programming/coin_change.ts | 55 +-
dynamic_programming/knapsack.ts | 25 +-
dynamic_programming/lcs.ts | 70 +-
dynamic_programming/test/coin_change.test.ts | 59 +-
dynamic_programming/test/knapsack.test.ts | 20 +-
dynamic_programming/test/lcs.test.ts | 36 +-
graph/bellman_ford.ts | 16 +-
graph/bipartite_graph.ts | 26 +-
graph/dijkstra.ts | 35 +-
graph/floyd_warshall.ts | 19 +-
graph/johnson.ts | 31 +-
graph/kosajaru.ts | 59 +-
graph/kruskal.ts | 35 +-
graph/prim.ts | 62 +-
graph/tarjan.ts | 53 +-
graph/test/bellman_ford.test.ts | 150 +-
graph/test/bipartite_graph.test.ts | 72 +-
graph/test/dijkstra.test.ts | 102 +-
graph/test/floyd_warshall.test.ts | 68 +-
graph/test/johnson.test.ts | 170 +-
graph/test/kosajaru.test.ts | 164 +-
graph/test/kruskal.test.ts | 99 +-
graph/test/prim.test.ts | 89 +-
graph/test/tarjan.test.ts | 176 +-
jest.config.ts | 10 +-
maths/absolute_value.ts | 4 +-
maths/aliquot_sum.ts | 4 +-
maths/armstrong_number.ts | 4 +-
maths/binomial_coefficient.ts | 20 +-
maths/calculate_mean.ts | 8 +-
maths/calculate_median.ts | 24 +-
maths/degrees_to_radians.ts | 20 +-
maths/digit_sum.ts | 12 +-
maths/double_factorial_iterative.ts | 17 +-
maths/euler_totient.ts | 18 +-
maths/factorial.ts | 6 +-
maths/factors.ts | 26 +-
maths/fibonacci.ts | 43 +-
maths/find_min.ts | 26 +-
maths/gaussian_elimination.ts | 28 +-
maths/greatest_common_factor.ts | 14 +-
maths/hamming_distance.ts | 3 +-
maths/is_divisible.ts | 10 +-
maths/is_even.ts | 14 +-
maths/is_leap_year.ts | 6 +-
maths/is_odd.ts | 14 +-
maths/is_palindrome.ts | 20 +-
maths/is_square_free.ts | 21 +-
maths/juggler_sequence.ts | 8 +-
maths/lowest_common_multiple.ts | 26 +-
maths/matrix_multiplication.ts | 33 +-
maths/number_of_digits.ts | 6 +-
maths/pascals_triangle.ts | 22 +-
maths/perfect_cube.ts | 4 +-
maths/perfect_number.ts | 28 +-
maths/perfect_square.ts | 4 +-
maths/prime_factorization.ts | 30 +-
maths/primes.ts | 46 +-
maths/pronic_number.ts | 10 +-
maths/radians_to_degrees.ts | 20 +-
maths/series/hexagonal_numbers.ts | 5 +-
maths/series/test/hexagonal_numbers.test.ts | 14 +-
maths/sieve_of_eratosthenes.ts | 17 +-
maths/signum.ts | 2 +-
maths/square_root.ts | 16 +-
maths/test/absolute_value.test.ts | 46 +-
maths/test/aliquot_sum.test.ts | 14 +-
maths/test/armstrong_number.test.ts | 12 +-
maths/test/binomial_coefficient.test.ts | 58 +-
maths/test/calculate_mean.test.ts | 50 +-
maths/test/calculate_median.test.ts | 38 +-
maths/test/degrees_to_radians.test.ts | 14 +-
maths/test/digit_sum.test.ts | 32 +-
maths/test/double_factorial_iterative.test.ts | 16 +-
maths/test/euler_totient.test.ts | 37 +-
maths/test/factorial.test.ts | 36 +-
maths/test/factors.test.ts | 43 +-
maths/test/fibonacci.test.ts | 16 +-
maths/test/find_min.test.ts | 28 +-
maths/test/gaussian_elimination.test.ts | 48 +-
maths/test/greatest_common_factor.test.ts | 63 +-
maths/test/hamming_distance.test.ts | 9 +-
maths/test/is_divisible.test.ts | 70 +-
maths/test/is_even.test.ts | 29 +-
maths/test/is_leap_year.test.ts | 90 +-
maths/test/is_odd.test.ts | 29 +-
maths/test/is_palindrome.test.ts | 25 +-
maths/test/is_square_free.test.ts | 34 +-
maths/test/juggler_sequence.test.ts | 10 +-
maths/test/lowest_common_multiple.test.ts | 119 +-
maths/test/matrix_multiplication.test.ts | 30 +-
maths/test/number_of_digits.test.ts | 31 +-
maths/test/pascals_triangle.test.ts | 12 +-
maths/test/perfect_cube.test.ts | 10 +-
maths/test/perfect_numbers.test.ts | 10 +-
maths/test/perfect_square.test.ts | 16 +-
maths/test/prime_factorization.test.ts | 57 +-
maths/test/primes.test.ts | 63 +-
maths/test/pronic_number.test.ts | 8 +-
maths/test/radians_to_degrees.test.ts | 14 +-
maths/test/sieve_of_eratosthenes.test.ts | 30 +-
maths/test/signum.test.ts | 9 +-
maths/test/square_root.test.ts | 24 +-
maths/test/ugly_numbers.test.ts | 10 +-
maths/test/zellers_congruence.test.ts | 54 +-
maths/ugly_numbers.ts | 16 +-
maths/zellers_congruence.ts | 26 +-
other/is_sorted_array.ts | 14 +-
other/parse_nested_brackets.ts | 58 +-
other/shuffle_array.ts | 12 +-
other/test/is_sorted_array.test.ts | 18 +-
other/test/parse_nested_brackets.test.ts | 36 +-
other/test/shuffle_array.test.ts | 44 +-
package-lock.json | 12904 ++++++++--------
package.json | 42 +-
search/binary_search.ts | 84 +-
search/interpolation_search.ts | 40 +-
search/jump_search.ts | 93 +-
search/linear_search.ts | 12 +-
search/sentinel_search.ts | 44 +-
search/test/binary_search.test.ts | 67 +-
search/test/interpolation_search.test.ts | 21 +-
search/test/jump_search.test.ts | 46 +-
search/test/linear_search.test.ts | 12 +-
search/test/sentinel_search.test.ts | 18 +-
sorts/bogo_sort.ts | 12 +-
sorts/bubble_sort.ts | 39 +-
sorts/counting_sort.ts | 28 +-
sorts/cycle_sort.ts | 131 +-
sorts/gnome_sort.ts | 14 +-
sorts/heap_sort.ts | 61 +-
sorts/insertion_sort.ts | 14 +-
sorts/quick_select.ts | 52 +-
sorts/quick_sort.ts | 39 +-
sorts/selection_sort.ts | 10 +-
sorts/shell_sort.ts | 26 +-
sorts/swap_sort.ts | 37 +-
sorts/test/bogo_sort.test.ts | 26 +-
sorts/test/bubble_sort.test.ts | 30 +-
sorts/test/counting_sort.test.ts | 20 +-
sorts/test/cycle_sort.test.ts | 36 +-
sorts/test/gnome_sort.test.ts | 12 +-
sorts/test/heap_sort.test.ts | 34 +-
sorts/test/insertion_sort.test.ts | 26 +-
sorts/test/merge_sort.test.ts | 6 +-
sorts/test/quick_select.test.ts | 48 +-
sorts/test/quick_sort.test.ts | 34 +-
sorts/test/selection_sort.test.ts | 20 +-
sorts/test/shell_sort.test.ts | 30 +-
sorts/test/swap_sort.test.ts | 25 +-
sorts/test/tree_sort.test.ts | 50 +-
sorts/tree_sort.ts | 10 +-
tsconfig.json | 19 +-
205 files changed, 11151 insertions(+), 10755 deletions(-)
create mode 100644 .prettierignore
create mode 100644 .prettierrc
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index a84c9fa0..cff9701c 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -16,3 +16,4 @@ jobs:
node-version: "18.x"
- run: npm ci
- run: npm test
+ - run: npm run check-style
diff --git a/.gitpod.yml b/.gitpod.yml
index 46209a0a..5ba99cbb 100644
--- a/.gitpod.yml
+++ b/.gitpod.yml
@@ -1,5 +1,3 @@
tasks:
- init: |
npm install && npm test
-
-
diff --git a/.prettierignore b/.prettierignore
new file mode 100644
index 00000000..1305111f
--- /dev/null
+++ b/.prettierignore
@@ -0,0 +1,2 @@
+.github
+*.md
diff --git a/.prettierrc b/.prettierrc
new file mode 100644
index 00000000..a85cb7eb
--- /dev/null
+++ b/.prettierrc
@@ -0,0 +1,15 @@
+{
+ "arrowParens": "always",
+ "bracketSpacing": true,
+ "endOfLine": "lf",
+ "insertPragma": false,
+ "printWidth": 80,
+ "proseWrap": "preserve",
+ "quoteProps": "as-needed",
+ "requirePragma": false,
+ "semi": false,
+ "singleQuote": true,
+ "tabWidth": 2,
+ "trailingComma": "none",
+ "useTabs": false
+}
diff --git a/babel.config.js b/babel.config.js
index 924d02bb..7b976f52 100644
--- a/babel.config.js
+++ b/babel.config.js
@@ -1,7 +1,6 @@
module.exports = {
- presets: [
- ['@babel/preset-env', { targets: { node: 'current' } }],
- '@babel/preset-typescript'
- ]
-};
-
+ presets: [
+ ['@babel/preset-env', { targets: { node: 'current' } }],
+ '@babel/preset-typescript'
+ ]
+}
diff --git a/backtracking/all_combinations_of_size_k.ts b/backtracking/all_combinations_of_size_k.ts
index 23ee3760..67e18bf6 100644
--- a/backtracking/all_combinations_of_size_k.ts
+++ b/backtracking/all_combinations_of_size_k.ts
@@ -10,8 +10,8 @@
* and repeat the same process for the next number.
*/
export function generateCombinations(n: number, k: number): number[][] {
- const combinationsAcc: number[][] = [];
- const currentCombination: number[] = [];
+ const combinationsAcc: number[][] = []
+ const currentCombination: number[] = []
function generateAllCombos(
n: number,
@@ -20,19 +20,19 @@ export function generateCombinations(n: number, k: number): number[][] {
): number[][] {
if (k === 0) {
if (currentCombination.length > 0) {
- combinationsAcc.push(currentCombination.slice());
+ combinationsAcc.push(currentCombination.slice())
}
- return combinationsAcc;
+ return combinationsAcc
}
- const endCursor = n - k + 2;
+ const endCursor = n - k + 2
for (let i = startCursor; i < endCursor; i++) {
- currentCombination.push(i);
- generateAllCombos(n, k - 1, i + 1);
- currentCombination.pop();
+ currentCombination.push(i)
+ generateAllCombos(n, k - 1, i + 1)
+ currentCombination.pop()
}
- return combinationsAcc;
+ return combinationsAcc
}
- return generateAllCombos(n, k, 1);
+ return generateAllCombos(n, k, 1)
}
diff --git a/backtracking/generateparentheses.ts b/backtracking/generateparentheses.ts
index e2c93662..a998ac34 100644
--- a/backtracking/generateparentheses.ts
+++ b/backtracking/generateparentheses.ts
@@ -6,26 +6,30 @@
*/
const generateParentheses = (n: number): string[] => {
- const result: string[] = [];
+ const result: string[] = []
- const solve = (chars: string, openParentheses: number, closedParentheses: number) => {
+ const solve = (
+ chars: string,
+ openParentheses: number,
+ closedParentheses: number
+ ) => {
if (openParentheses === n && closedParentheses === n) {
- result.push(chars);
- return;
+ result.push(chars)
+ return
}
if (openParentheses <= n) {
- solve(chars + "(", openParentheses + 1, closedParentheses);
+ solve(chars + '(', openParentheses + 1, closedParentheses)
}
if (closedParentheses < openParentheses) {
- solve(chars + ")", openParentheses, closedParentheses + 1);
+ solve(chars + ')', openParentheses, closedParentheses + 1)
}
- };
+ }
- solve("", 0, 0);
+ solve('', 0, 0)
- return result;
-};
+ return result
+}
-export { generateParentheses };
+export { generateParentheses }
diff --git a/backtracking/test/all_combinations_of_size_k.test.ts b/backtracking/test/all_combinations_of_size_k.test.ts
index 09639406..96e2526c 100644
--- a/backtracking/test/all_combinations_of_size_k.test.ts
+++ b/backtracking/test/all_combinations_of_size_k.test.ts
@@ -1,4 +1,4 @@
-import { generateCombinations } from "../all_combinations_of_size_k";
+import { generateCombinations } from '../all_combinations_of_size_k'
const cases = [
[
@@ -7,20 +7,31 @@ const cases = [
[
[1, 2],
[1, 3],
+ [2, 3]
+ ]
+ ],
+ [
+ 4,
+ 2,
+ [
+ [1, 2],
+ [1, 3],
+ [1, 4],
[2, 3],
- ],
+ [2, 4],
+ [3, 4]
+ ]
],
- [4, 2, [[1, 2], [1, 3], [1, 4], [2, 3], [2, 4], [3, 4]]],
[0, 0, []],
- [2, 3, []],
-] as const;
+ [2, 3, []]
+] as const
-describe("AllCombinationsOfSizeK", () => {
+describe('AllCombinationsOfSizeK', () => {
it.each(cases)(
- "create all combinations given n=%p and k=%p",
+ 'create all combinations given n=%p and k=%p',
(n, k, expectedCombos) => {
- const combinations = generateCombinations(n, k);
- expect(combinations).toEqual(expectedCombos);
+ const combinations = generateCombinations(n, k)
+ expect(combinations).toEqual(expectedCombos)
}
- );
-});
+ )
+})
diff --git a/backtracking/test/generateparentheses.test.ts b/backtracking/test/generateparentheses.test.ts
index c3752d34..42751fd2 100644
--- a/backtracking/test/generateparentheses.test.ts
+++ b/backtracking/test/generateparentheses.test.ts
@@ -1,83 +1,83 @@
-import { generateParentheses } from "../generateparentheses";
+import { generateParentheses } from '../generateparentheses'
const cases: [number, string[]][] = [
- [0, [""]],
- [1, ["()"]],
- [2, ["(())", "()()"]],
- [3, ["((()))", "(()())", "(())()", "()(())", "()()()"]],
+ [0, ['']],
+ [1, ['()']],
+ [2, ['(())', '()()']],
+ [3, ['((()))', '(()())', '(())()', '()(())', '()()()']],
[
4,
[
- "(((())))",
- "((()()))",
- "((())())",
- "((()))()",
- "(()(()))",
- "(()()())",
- "(()())()",
- "(())(())",
- "(())()()",
- "()((()))",
- "()(()())",
- "()(())()",
- "()()(())",
- "()()()()",
- ],
+ '(((())))',
+ '((()()))',
+ '((())())',
+ '((()))()',
+ '(()(()))',
+ '(()()())',
+ '(()())()',
+ '(())(())',
+ '(())()()',
+ '()((()))',
+ '()(()())',
+ '()(())()',
+ '()()(())',
+ '()()()()'
+ ]
],
[
5,
[
- "((((()))))",
- "(((()())))",
- "(((())()))",
- "(((()))())",
- "(((())))()",
- "((()(())))",
- "((()()()))",
- "((()())())",
- "((()()))()",
- "((())(()))",
- "((())()())",
- "((())())()",
- "((()))(())",
- "((()))()()",
- "(()((())))",
- "(()(()()))",
- "(()(())())",
- "(()(()))()",
- "(()()(()))",
- "(()()()())",
- "(()()())()",
- "(()())(())",
- "(()())()()",
- "(())((()))",
- "(())(()())",
- "(())(())()",
- "(())()(())",
- "(())()()()",
- "()(((())))",
- "()((()()))",
- "()((())())",
- "()((()))()",
- "()(()(()))",
- "()(()()())",
- "()(()())()",
- "()(())(())",
- "()(())()()",
- "()()((()))",
- "()()(()())",
- "()()(())()",
- "()()()(())",
- "()()()()()",
- ],
- ],
-];
+ '((((()))))',
+ '(((()())))',
+ '(((())()))',
+ '(((()))())',
+ '(((())))()',
+ '((()(())))',
+ '((()()()))',
+ '((()())())',
+ '((()()))()',
+ '((())(()))',
+ '((())()())',
+ '((())())()',
+ '((()))(())',
+ '((()))()()',
+ '(()((())))',
+ '(()(()()))',
+ '(()(())())',
+ '(()(()))()',
+ '(()()(()))',
+ '(()()()())',
+ '(()()())()',
+ '(()())(())',
+ '(()())()()',
+ '(())((()))',
+ '(())(()())',
+ '(())(())()',
+ '(())()(())',
+ '(())()()()',
+ '()(((())))',
+ '()((()()))',
+ '()((())())',
+ '()((()))()',
+ '()(()(()))',
+ '()(()()())',
+ '()(()())()',
+ '()(())(())',
+ '()(())()()',
+ '()()((()))',
+ '()()(()())',
+ '()()(())()',
+ '()()()(())',
+ '()()()()()'
+ ]
+ ]
+]
-describe("Generate Parentheses", () => {
+describe('Generate Parentheses', () => {
test.each(cases)(
- "generate all valid parentheses of input %n",
+ 'generate all valid parentheses of input %n',
(n: number, expected: string[]) => {
- expect(generateParentheses(n)).toStrictEqual(expected);
+ expect(generateParentheses(n)).toStrictEqual(expected)
}
- );
-});
+ )
+})
diff --git a/bit_manipulation/add_binary.ts b/bit_manipulation/add_binary.ts
index 38ca43af..7e6ecd03 100644
--- a/bit_manipulation/add_binary.ts
+++ b/bit_manipulation/add_binary.ts
@@ -5,23 +5,28 @@
* @param secondBinaryNo - The second binary string.
* @returns The binary sum of the input strings.
*/
-export function addBinary(firstBinaryNo: string, secondBinaryNo: string): string {
- let lengthOfFirstNumber: number = firstBinaryNo.length - 1;
- let lengthOfSecondNumber: number = secondBinaryNo.length - 1;
- const solution: string[] = [];
- let carry: number = 0;
+export function addBinary(
+ firstBinaryNo: string,
+ secondBinaryNo: string
+): string {
+ let lengthOfFirstNumber: number = firstBinaryNo.length - 1
+ let lengthOfSecondNumber: number = secondBinaryNo.length - 1
+ const solution: string[] = []
+ let carry: number = 0
- while ( lengthOfFirstNumber >= 0 || lengthOfSecondNumber >= 0) {
- let sum: number = carry;
- if (lengthOfFirstNumber >= 0) sum += parseInt(firstBinaryNo.charAt(lengthOfFirstNumber));
- if (lengthOfSecondNumber >= 0) sum += parseInt(secondBinaryNo.charAt(lengthOfSecondNumber));
- solution.push((sum % 2).toString());
- carry = Math.floor(sum / 2);
- lengthOfFirstNumber--;
- lengthOfSecondNumber--;
- }
+ while (lengthOfFirstNumber >= 0 || lengthOfSecondNumber >= 0) {
+ let sum: number = carry
+ if (lengthOfFirstNumber >= 0)
+ sum += parseInt(firstBinaryNo.charAt(lengthOfFirstNumber))
+ if (lengthOfSecondNumber >= 0)
+ sum += parseInt(secondBinaryNo.charAt(lengthOfSecondNumber))
+ solution.push((sum % 2).toString())
+ carry = Math.floor(sum / 2)
+ lengthOfFirstNumber--
+ lengthOfSecondNumber--
+ }
- if (carry !== 0) solution.push(carry.toString());
+ if (carry !== 0) solution.push(carry.toString())
- return solution.reverse().join('');
+ return solution.reverse().join('')
}
diff --git a/bit_manipulation/is_power_of_2.ts b/bit_manipulation/is_power_of_2.ts
index 487c1a8c..2edcea31 100644
--- a/bit_manipulation/is_power_of_2.ts
+++ b/bit_manipulation/is_power_of_2.ts
@@ -22,4 +22,4 @@
* @returns {boolean}
*/
-export const isPowerOfTwo = (n: number): boolean => n > 0 && (n & (n - 1)) === 0
\ No newline at end of file
+export const isPowerOfTwo = (n: number): boolean => n > 0 && (n & (n - 1)) === 0
diff --git a/bit_manipulation/is_power_of_4.ts b/bit_manipulation/is_power_of_4.ts
index e7a57bc5..1e5e2d5a 100644
--- a/bit_manipulation/is_power_of_4.ts
+++ b/bit_manipulation/is_power_of_4.ts
@@ -12,4 +12,5 @@
* const result = isPowerOfFour(16); // Returns true (16 is 4^2)
* const result2 = isPowerOfFour(5); // Returns false (5 is not a power of four)
*/
-export const isPowerOfFour = (n: number): boolean => ((n > 0) && ((n & n - 1) === 0) && (n % 3 === 1))
+export const isPowerOfFour = (n: number): boolean =>
+ n > 0 && (n & (n - 1)) === 0 && n % 3 === 1
diff --git a/bit_manipulation/log_two.ts b/bit_manipulation/log_two.ts
index 6fb40f2d..7246c8ce 100644
--- a/bit_manipulation/log_two.ts
+++ b/bit_manipulation/log_two.ts
@@ -6,10 +6,10 @@
* @returns {number} Log2 approximation equal to floor(log2(n))
*/
export const logTwo = (n: number): number => {
- let result = 0
- while (n >> 1) {
- n >>= 1
- result++
- }
- return result
-}
\ No newline at end of file
+ let result = 0
+ while (n >> 1) {
+ n >>= 1
+ result++
+ }
+ return result
+}
diff --git a/bit_manipulation/test/add_binary.test.ts b/bit_manipulation/test/add_binary.test.ts
index e8ce1776..e3fe52fc 100644
--- a/bit_manipulation/test/add_binary.test.ts
+++ b/bit_manipulation/test/add_binary.test.ts
@@ -1,33 +1,33 @@
-import { addBinary } from "../add_binary";
+import { addBinary } from '../add_binary'
describe('Add Binary Number', () => {
- it('should add two binary numbers with no carry', () => {
- const result = addBinary('1101', '1011');
- expect(result).toBe('11000');
- });
+ it('should add two binary numbers with no carry', () => {
+ const result = addBinary('1101', '1011')
+ expect(result).toBe('11000')
+ })
- it('should add two binary numbers with carry', () => {
- const result = addBinary('1111', '1111');
- expect(result).toBe('11110');
- });
+ it('should add two binary numbers with carry', () => {
+ const result = addBinary('1111', '1111')
+ expect(result).toBe('11110')
+ })
- it('should add two different-length binary numbers', () => {
- const result = addBinary('1101', '111');
- expect(result).toBe('10100');
- });
+ it('should add two different-length binary numbers', () => {
+ const result = addBinary('1101', '111')
+ expect(result).toBe('10100')
+ })
- it('should add two empty binary numbers', () => {
- const result = addBinary('', '');
- expect(result).toBe('');
- });
+ it('should add two empty binary numbers', () => {
+ const result = addBinary('', '')
+ expect(result).toBe('')
+ })
- it('should add one empty binary number to a non-empty number', () => {
- const result = addBinary('1010', '');
- expect(result).toBe('1010');
- });
+ it('should add one empty binary number to a non-empty number', () => {
+ const result = addBinary('1010', '')
+ expect(result).toBe('1010')
+ })
- it('should add one non-empty binary number to an empty number', () => {
- const result = addBinary('', '1101');
- expect(result).toBe('1101');
- });
-});
\ No newline at end of file
+ it('should add one non-empty binary number to an empty number', () => {
+ const result = addBinary('', '1101')
+ expect(result).toBe('1101')
+ })
+})
diff --git a/bit_manipulation/test/is_power_of_2.test.ts b/bit_manipulation/test/is_power_of_2.test.ts
index 1276e6d1..8993947b 100644
--- a/bit_manipulation/test/is_power_of_2.test.ts
+++ b/bit_manipulation/test/is_power_of_2.test.ts
@@ -1,14 +1,13 @@
-import { isPowerOfTwo } from "../is_power_of_2"
+import { isPowerOfTwo } from '../is_power_of_2'
-
-describe('IsPowerOfTwo' , () => {
- it.each([
- [0, false],
- [1, true],
- [4, true],
- [1024, true],
- [1025, false],
- ])('Check if %i is a power of 2 or not', (number, expected) => {
- expect(isPowerOfTwo(number)).toBe(expected);
- });
-})
\ No newline at end of file
+describe('IsPowerOfTwo', () => {
+ it.each([
+ [0, false],
+ [1, true],
+ [4, true],
+ [1024, true],
+ [1025, false]
+ ])('Check if %i is a power of 2 or not', (number, expected) => {
+ expect(isPowerOfTwo(number)).toBe(expected)
+ })
+})
diff --git a/bit_manipulation/test/is_power_of_4.test.ts b/bit_manipulation/test/is_power_of_4.test.ts
index a9b31c47..1851f708 100644
--- a/bit_manipulation/test/is_power_of_4.test.ts
+++ b/bit_manipulation/test/is_power_of_4.test.ts
@@ -1,4 +1,4 @@
-import { isPowerOfFour } from "../is_power_of_4"
+import { isPowerOfFour } from '../is_power_of_4'
describe('IsPowerOfFour', () => {
it.each([
@@ -11,4 +11,4 @@ describe('IsPowerOfFour', () => {
])('should return the number %i is power of four or not', (n, expected) => {
expect(isPowerOfFour(n)).toBe(expected)
})
-})
\ No newline at end of file
+})
diff --git a/bit_manipulation/test/log_two.test.ts b/bit_manipulation/test/log_two.test.ts
index ff168ad3..923341f4 100644
--- a/bit_manipulation/test/log_two.test.ts
+++ b/bit_manipulation/test/log_two.test.ts
@@ -1,10 +1,7 @@
-import { logTwo } from "../log_two"
+import { logTwo } from '../log_two'
-describe('LogTwoTests' , () => {
- test.each([...Array(100).keys()].map(i => [i + 1]))(
- 'log2(%i)',
- (input) => {
- expect(logTwo(input)).toBe(Math.floor(Math.log2(input)));
- }
- );
-})
\ No newline at end of file
+describe('LogTwoTests', () => {
+ test.each([...Array(100).keys()].map((i) => [i + 1]))('log2(%i)', (input) => {
+ expect(logTwo(input)).toBe(Math.floor(Math.log2(input)))
+ })
+})
diff --git a/ciphers/test/xor_cipher.test.ts b/ciphers/test/xor_cipher.test.ts
index b8def4a6..0607d6a3 100644
--- a/ciphers/test/xor_cipher.test.ts
+++ b/ciphers/test/xor_cipher.test.ts
@@ -1,8 +1,8 @@
-import { XORCipher } from '../xor_cipher';
+import { XORCipher } from '../xor_cipher'
describe('Testing XORCipher function', () => {
it('passing a string & number as an argument', () => {
- expect(XORCipher('test', 32)).toBe('TEST');
- expect(XORCipher('TEST', 32)).toBe('test');
- });
-});
+ expect(XORCipher('test', 32)).toBe('TEST')
+ expect(XORCipher('TEST', 32)).toBe('test')
+ })
+})
diff --git a/data_structures/disjoint_set/disjoint_set.ts b/data_structures/disjoint_set/disjoint_set.ts
index f627e8ec..1d8ce49f 100644
--- a/data_structures/disjoint_set/disjoint_set.ts
+++ b/data_structures/disjoint_set/disjoint_set.ts
@@ -6,9 +6,9 @@
* The find operation uses path compression.
* This allows the time complexity of the find operation be O(alpha(n)).
* alpha(n) being the inverse Ackermann function.
- *
+ *
* The join operation uses union by size: The smaller set is joined to the bigger one.
- *
+ *
* You can perform the following operations on the disjoint set:
* - find: Determine which subset a particular element is in - O(alpha(n))
* - join: Join two subsets into a single subset - O(1)
@@ -16,15 +16,15 @@
*/
export class DisjointSet {
/** Direct parent for an element */
- private head: number[];
+ private head: number[]
/** Size of the subtree above an element */
- private size: number[];
+ private size: number[]
constructor(n: number) {
// Initially each set has its own id element
- this.head = Array.from({ length: n }, (_, index) => index);
- this.size = Array(n).fill(1);
+ this.head = Array.from({ length: n }, (_, index) => index)
+ this.size = Array(n).fill(1)
}
/**
@@ -33,39 +33,38 @@ export class DisjointSet {
find(index: number): number {
if (this.head[index] != index) {
// Use path compression (set an edge between the element and its head)
- this.head[index] = this.find(this.head[index]);
+ this.head[index] = this.find(this.head[index])
}
- return this.head[index];
+ return this.head[index]
}
-
/**
* Join two sets
*/
join(first: number, second: number): void {
// Get the root of each set to join
- let firstHead = this.find(first);
- let secondHead = this.find(second);
+ let firstHead = this.find(first)
+ let secondHead = this.find(second)
// If they're the same (same set)
- if (firstHead === secondHead) return;
+ if (firstHead === secondHead) return
// Keep the bigger set in firstHead
if (this.size[firstHead] < this.size[secondHead]) {
- [firstHead, secondHead] = [secondHead, firstHead];
+ ;[firstHead, secondHead] = [secondHead, firstHead]
}
// Join the smallest set with the bigger one
- this.head[secondHead] = firstHead;
+ this.head[secondHead] = firstHead
// Update size of the bigger set after join
- this.size[firstHead] += this.size[secondHead];
+ this.size[firstHead] += this.size[secondHead]
}
/**
* Check whether two elements are in the same set
*/
isSame(first: number, second: number): boolean {
- return this.find(first) === this.find(second);
+ return this.find(first) === this.find(second)
}
}
diff --git a/data_structures/disjoint_set/test/disjoint_set.test.ts b/data_structures/disjoint_set/test/disjoint_set.test.ts
index 3409426a..7e300e13 100644
--- a/data_structures/disjoint_set/test/disjoint_set.test.ts
+++ b/data_structures/disjoint_set/test/disjoint_set.test.ts
@@ -1,24 +1,24 @@
-import { DisjointSet } from "../disjoint_set"
+import { DisjointSet } from '../disjoint_set'
-describe("DisjointSet", () => {
- let ds: DisjointSet;
+describe('DisjointSet', () => {
+ let ds: DisjointSet
beforeEach(() => {
// Ensure create a new DisjoinSet instance on every test
- ds = new DisjointSet(10);
- });
+ ds = new DisjointSet(10)
+ })
- it("should show proper head element after join", () => {
- expect(ds.find(0)).toEqual(0);
+ it('should show proper head element after join', () => {
+ expect(ds.find(0)).toEqual(0)
- ds.join(1, 4);
- ds.join(2, 3);
- expect(ds.isSame(1, 4)).toEqual(true);
- expect(ds.isSame(2, 3)).toEqual(true);
- expect(ds.isSame(1, 3)).toEqual(false);
+ ds.join(1, 4)
+ ds.join(2, 3)
+ expect(ds.isSame(1, 4)).toEqual(true)
+ expect(ds.isSame(2, 3)).toEqual(true)
+ expect(ds.isSame(1, 3)).toEqual(false)
- ds.join(4, 3);
- expect(ds.isSame(1, 3)).toEqual(true);
- expect(ds.isSame(2, 9)).toEqual(false);
- });
+ ds.join(4, 3)
+ expect(ds.isSame(1, 3)).toEqual(true)
+ expect(ds.isSame(2, 9)).toEqual(false)
+ })
})
diff --git a/data_structures/heap/heap.ts b/data_structures/heap/heap.ts
index b5ab0ebc..100ce1b3 100644
--- a/data_structures/heap/heap.ts
+++ b/data_structures/heap/heap.ts
@@ -12,13 +12,13 @@
*/
export abstract class Heap {
- protected heap: T[];
+ protected heap: T[]
// A comparison function. Returns true if a should be the parent of b.
- protected compare: (a: T, b: T) => boolean;
+ protected compare: (a: T, b: T) => boolean
constructor(compare: (a: T, b: T) => boolean) {
- this.heap = [];
- this.compare = compare;
+ this.heap = []
+ this.compare = compare
}
/**
@@ -27,174 +27,188 @@ export abstract class Heap {
* In a minHeap the value at parentIndex should be smaller than the value at childIndex
*
*/
- private isRightlyPlaced( childIndex: number, parentIndex: number) {
- return this.compare(this.heap[parentIndex], this.heap[childIndex]);
+ private isRightlyPlaced(childIndex: number, parentIndex: number) {
+ return this.compare(this.heap[parentIndex], this.heap[childIndex])
}
/**
* In a maxHeap the index with the larger value is returned
* In a minHeap the index with the smaller value is returned
*/
- private getChildIndexToSwap(leftChildIndex: number, rightChildIndex: number): number {
+ private getChildIndexToSwap(
+ leftChildIndex: number,
+ rightChildIndex: number
+ ): number {
if (rightChildIndex >= this.size()) {
- return leftChildIndex;
+ return leftChildIndex
}
return this.compare(this.heap[leftChildIndex], this.heap[rightChildIndex])
? leftChildIndex
- : rightChildIndex;
+ : rightChildIndex
}
public insert(value: T): void {
- this.heap.push(value);
- this.bubbleUp();
+ this.heap.push(value)
+ this.bubbleUp()
}
public extract(): T {
- const maxElement = this.heap[0];
- this.heap[0] = this.heap[this.size() - 1];
- this.heap.pop();
- this.sinkDown();
- return maxElement;
+ const maxElement = this.heap[0]
+ this.heap[0] = this.heap[this.size() - 1]
+ this.heap.pop()
+ this.sinkDown()
+ return maxElement
}
public size(): number {
- return this.heap.length;
+ return this.heap.length
}
public isEmpty(): boolean {
- return this.size() === 0;
+ return this.size() === 0
}
protected swap(a: number, b: number) {
- [this.heap[a], this.heap[b]] = [
- this.heap[b],
- this.heap[a],
- ];
+ ;[this.heap[a], this.heap[b]] = [this.heap[b], this.heap[a]]
}
protected bubbleUp(index = this.size() - 1): void {
- let parentIndex;
+ let parentIndex
while (index > 0) {
- parentIndex = Math.floor((index - 1) / 2);
- if (this.isRightlyPlaced(index, parentIndex)) break;
- this.swap(parentIndex, index);
- index = parentIndex;
+ parentIndex = Math.floor((index - 1) / 2)
+ if (this.isRightlyPlaced(index, parentIndex)) break
+ this.swap(parentIndex, index)
+ index = parentIndex
}
}
private sinkDown(): void {
- let index = 0;
- let leftChildIndex = this.getLeftChildIndex(index);
- let rightChildIndex = this.getRightChildIndex(index);
- let childIndexToSwap;
+ let index = 0
+ let leftChildIndex = this.getLeftChildIndex(index)
+ let rightChildIndex = this.getRightChildIndex(index)
+ let childIndexToSwap
while (this.heap[leftChildIndex] || this.heap[rightChildIndex]) {
childIndexToSwap = this.getChildIndexToSwap(
leftChildIndex,
rightChildIndex
- );
- if (this.isRightlyPlaced(childIndexToSwap, index)) break;
- this.swap(childIndexToSwap, index);
- index = childIndexToSwap;
- leftChildIndex = this.getLeftChildIndex(index);
- rightChildIndex = this.getRightChildIndex(index);
+ )
+ if (this.isRightlyPlaced(childIndexToSwap, index)) break
+ this.swap(childIndexToSwap, index)
+ index = childIndexToSwap
+ leftChildIndex = this.getLeftChildIndex(index)
+ rightChildIndex = this.getRightChildIndex(index)
}
}
private getLeftChildIndex(index: number): number {
- return index * 2 + 1;
+ return index * 2 + 1
}
private getRightChildIndex(index: number): number {
- return index * 2 + 2;
+ return index * 2 + 2
}
public check(): void {
- return this._check();
+ return this._check()
}
private _check(index: number = 0): void {
- if (!this.heap[index]) return;
- const leftChildIndex = this.getLeftChildIndex(index);
- const rightChildIndex = this.getRightChildIndex(index);
+ if (!this.heap[index]) return
+ const leftChildIndex = this.getLeftChildIndex(index)
+ const rightChildIndex = this.getRightChildIndex(index)
if (
this.heap[leftChildIndex] &&
!this.isRightlyPlaced(leftChildIndex, index)
)
- throw new Error("Heap does not adhere to heap invariant");
+ throw new Error('Heap does not adhere to heap invariant')
if (
this.heap[rightChildIndex] &&
!this.isRightlyPlaced(rightChildIndex, index)
)
- throw new Error("Heap does not adhere to heap invariant");
+ throw new Error('Heap does not adhere to heap invariant')
- this._check(leftChildIndex);
- this._check(rightChildIndex);
+ this._check(leftChildIndex)
+ this._check(rightChildIndex)
}
}
export class MinHeap extends Heap {
- constructor(compare = (a: T, b: T) => { return a < b }) {
- super(compare);
+ constructor(
+ compare = (a: T, b: T) => {
+ return a < b
+ }
+ ) {
+ super(compare)
}
}
export class MaxHeap extends Heap {
- constructor(compare = (a: T, b: T) => { return a > b }) {
- super(compare);
+ constructor(
+ compare = (a: T, b: T) => {
+ return a > b
+ }
+ ) {
+ super(compare)
}
}
// Priority queue that supports increasePriority() in O(log(n)). The limitation is that there can only be a single element for each key, and the max number or keys must be specified at heap construction. Most of the functions are wrappers around MinHeap functions and update the keys array.
export class PriorityQueue extends MinHeap {
// Maps from the n'th node to its index within the heap.
- private keys: number[];
+ private keys: number[]
// Maps from element to its index with keys.
- private keys_index: (a: T) => number;
+ private keys_index: (a: T) => number
- constructor(keys_index: (a: T) => number, num_keys: number, compare = (a: T, b: T) => { return a < b }) {
- super(compare);
- this.keys = Array(num_keys).fill(-1);
- this.keys_index = keys_index;
+ constructor(
+ keys_index: (a: T) => number,
+ num_keys: number,
+ compare = (a: T, b: T) => {
+ return a < b
+ }
+ ) {
+ super(compare)
+ this.keys = Array(num_keys).fill(-1)
+ this.keys_index = keys_index
}
protected swap(a: number, b: number) {
- const akey = this.keys_index(this.heap[a]);
- const bkey = this.keys_index(this.heap[b]);
- [this.keys[akey], this.keys[bkey]] = [this.keys[bkey], this.keys[akey]];
- super.swap(a, b);
+ const akey = this.keys_index(this.heap[a])
+ const bkey = this.keys_index(this.heap[b])
+ ;[this.keys[akey], this.keys[bkey]] = [this.keys[bkey], this.keys[akey]]
+ super.swap(a, b)
}
public insert(value: T) {
- this.keys[this.keys_index(value)] = this.size();
- super.insert(value);
+ this.keys[this.keys_index(value)] = this.size()
+ super.insert(value)
}
public extract(): T {
// Unmark the the highest priority element and set key to zero for the last element in the heap.
- this.keys[this.keys_index(this.heap[0])] = -1;
+ this.keys[this.keys_index(this.heap[0])] = -1
if (this.size() > 1) {
- this.keys[this.keys_index(this.heap[this.size() - 1])] = 0;
+ this.keys[this.keys_index(this.heap[this.size() - 1])] = 0
}
- return super.extract();
+ return super.extract()
}
public increasePriority(idx: number, value: T) {
if (this.keys[idx] == -1) {
// If the key does not exist, insert the value.
- this.insert(value);
- return;
+ this.insert(value)
+ return
}
- const key = this.keys[idx];
+ const key = this.keys[idx]
if (this.compare(this.heap[key], value)) {
// Do not do anything if the value in the heap already has a higher priority.
- return;
+ return
}
// Increase the priority and bubble it up the heap.
- this.heap[key] = value;
- this.bubbleUp(key);
+ this.heap[key] = value
+ this.bubbleUp(key)
}
}
diff --git a/data_structures/heap/test/heap.test.ts b/data_structures/heap/test/heap.test.ts
index 3b90fc9b..9b513335 100644
--- a/data_structures/heap/test/heap.test.ts
+++ b/data_structures/heap/test/heap.test.ts
@@ -1,133 +1,139 @@
-import { MaxHeap, MinHeap, PriorityQueue } from "../heap";
+import { MaxHeap, MinHeap, PriorityQueue } from '../heap'
-describe("MaxHeap", () => {
- let heap: MaxHeap;
+describe('MaxHeap', () => {
+ let heap: MaxHeap
const elements: number[] = [
- 12, 4, 43, 42, 9, 7, 39, 16, 55, 1, 51, 34, 81, 18,
- ];
+ 12, 4, 43, 42, 9, 7, 39, 16, 55, 1, 51, 34, 81, 18
+ ]
beforeEach(() => {
- heap = new MaxHeap();
+ heap = new MaxHeap()
for (const element of elements) {
- heap.insert(element);
+ heap.insert(element)
}
- });
+ })
- it("should initialize a heap from input array", () => {
- expect(heap.isEmpty()).toEqual(false);
- heap.check();
- });
+ it('should initialize a heap from input array', () => {
+ expect(heap.isEmpty()).toEqual(false)
+ heap.check()
+ })
- it("should remove and return the max element in the heap", () => {
- const maxValue = heap.extract();
+ it('should remove and return the max element in the heap', () => {
+ const maxValue = heap.extract()
- expect(maxValue).toEqual(81);
- heap.check();
- });
+ expect(maxValue).toEqual(81)
+ heap.check()
+ })
- it("should insert a new element and bubble Up the element to it correct index in the heap", () => {
- heap.insert(61);
- heap.check();
- });
+ it('should insert a new element and bubble Up the element to it correct index in the heap', () => {
+ heap.insert(61)
+ heap.check()
+ })
const extract_all = (heap: MaxHeap) => {
- [...elements].sort((a, b) => b - a).forEach((element: number) => {
- expect(heap.extract()).toEqual(element);
- });
- heap.check();
- expect(heap.size()).toEqual(0);
+ ;[...elements]
+ .sort((a, b) => b - a)
+ .forEach((element: number) => {
+ expect(heap.extract()).toEqual(element)
+ })
+ heap.check()
+ expect(heap.size()).toEqual(0)
}
- it("should remove and return the max elements in order", () => {
- extract_all(heap);
- });
+ it('should remove and return the max elements in order', () => {
+ extract_all(heap)
+ })
- it("should insert all, then remove and return the max elements in order", () => {
- heap = new MaxHeap();
+ it('should insert all, then remove and return the max elements in order', () => {
+ heap = new MaxHeap()
elements.forEach((element: number) => {
- heap.insert(element);
- });
- heap.check();
- expect(heap.size()).toEqual(elements.length);
- extract_all(heap);
- });
-});
-
-describe("MinHeap", () => {
- let heap: MinHeap;
+ heap.insert(element)
+ })
+ heap.check()
+ expect(heap.size()).toEqual(elements.length)
+ extract_all(heap)
+ })
+})
+
+describe('MinHeap', () => {
+ let heap: MinHeap
const elements: number[] = [
- 12, 4, 43, 42, 9, 7, 39, 16, 55, 1, 51, 34, 81, 18,
- ];
+ 12, 4, 43, 42, 9, 7, 39, 16, 55, 1, 51, 34, 81, 18
+ ]
beforeEach(() => {
- heap = new MinHeap();
+ heap = new MinHeap()
for (const element of elements) {
- heap.insert(element);
+ heap.insert(element)
}
- });
+ })
- it("should initialize a heap from input array", () => {
- expect(heap.isEmpty()).toEqual(false);
- heap.check();
- });
+ it('should initialize a heap from input array', () => {
+ expect(heap.isEmpty()).toEqual(false)
+ heap.check()
+ })
- it("should remove and return the min element in the heap", () => {
- const minValue = heap.extract();
+ it('should remove and return the min element in the heap', () => {
+ const minValue = heap.extract()
- expect(minValue).toEqual(1);
- heap.check();
- });
+ expect(minValue).toEqual(1)
+ heap.check()
+ })
- it("should insert a new element and bubble Up the element to it correct index in the heap", () => {
- heap.insert(24);
- heap.check();
- });
+ it('should insert a new element and bubble Up the element to it correct index in the heap', () => {
+ heap.insert(24)
+ heap.check()
+ })
const extract_all = (heap: MinHeap, elements: number[]) => {
- [...elements].sort((a, b) => a - b).forEach((element: number) => {
- expect(heap.extract()).toEqual(element);
- });
- heap.check();
- expect(heap.size()).toEqual(0);
+ ;[...elements]
+ .sort((a, b) => a - b)
+ .forEach((element: number) => {
+ expect(heap.extract()).toEqual(element)
+ })
+ heap.check()
+ expect(heap.size()).toEqual(0)
}
- it("should remove and return the min elements in order", () => {
- extract_all(heap, elements);
- });
+ it('should remove and return the min elements in order', () => {
+ extract_all(heap, elements)
+ })
- it("should insert all, then remove and return the min elements in order", () => {
- heap = new MinHeap();
+ it('should insert all, then remove and return the min elements in order', () => {
+ heap = new MinHeap()
elements.forEach((element: number) => {
- heap.insert(element);
- });
- heap.check();
- expect(heap.size()).toEqual(elements.length);
- extract_all(heap, elements);
- });
-
- it("should increase priority", () => {
- const heap = new PriorityQueue((a: number) => { return a; }, elements.length);
+ heap.insert(element)
+ })
+ heap.check()
+ expect(heap.size()).toEqual(elements.length)
+ extract_all(heap, elements)
+ })
+
+ it('should increase priority', () => {
+ const heap = new PriorityQueue((a: number) => {
+ return a
+ }, elements.length)
elements.forEach((element: number) => {
- heap.insert(element);
- });
- heap.check();
- expect(heap.size()).toEqual(elements.length);
-
- heap.increasePriority(55, 14);
- heap.increasePriority(18, 16);
- heap.increasePriority(81, 72);
- heap.increasePriority(9, 0);
- heap.increasePriority(43, 33);
+ heap.insert(element)
+ })
+ heap.check()
+ expect(heap.size()).toEqual(elements.length)
+
+ heap.increasePriority(55, 14)
+ heap.increasePriority(18, 16)
+ heap.increasePriority(81, 72)
+ heap.increasePriority(9, 0)
+ heap.increasePriority(43, 33)
// decreasing priority should do nothing
- heap.increasePriority(72, 100);
- heap.increasePriority(12, 24);
- heap.increasePriority(39, 40);
+ heap.increasePriority(72, 100)
+ heap.increasePriority(12, 24)
+ heap.increasePriority(39, 40)
- heap.check();
+ heap.check()
// Elements after increasing priority
const newElements: number[] = [
- 12, 4, 33, 42, 0, 7, 39, 16, 14, 1, 51, 34, 72, 16,
- ];
- extract_all(heap, newElements);
- });
-});
+ 12, 4, 33, 42, 0, 7, 39, 16, 14, 1, 51, 34, 72, 16
+ ]
+ extract_all(heap, newElements)
+ })
+})
diff --git a/data_structures/list/doubly_linked_list.ts b/data_structures/list/doubly_linked_list.ts
index 7ed7447f..7cb90f4e 100644
--- a/data_structures/list/doubly_linked_list.ts
+++ b/data_structures/list/doubly_linked_list.ts
@@ -1,4 +1,4 @@
-import { LinkedList } from "./linked_list";
+import { LinkedList } from './linked_list'
/**
* This is an implementation of a Doubly Linked List.
@@ -13,270 +13,270 @@ import { LinkedList } from "./linked_list";
* @property length The length of the list.
*/
export class DoublyLinkedList implements LinkedList {
- private head?: DoublyLinkedListNode = undefined;
- private tail?: DoublyLinkedListNode = undefined;
- private length: number = 0;
-
- /**
- * Checks if the list is empty.
- *
- * @returns {boolean} Whether the list is empty or not.
- */
- isEmpty(): boolean {
- return !this.head;
+ private head?: DoublyLinkedListNode = undefined
+ private tail?: DoublyLinkedListNode = undefined
+ private length: number = 0
+
+ /**
+ * Checks if the list is empty.
+ *
+ * @returns {boolean} Whether the list is empty or not.
+ */
+ isEmpty(): boolean {
+ return !this.head
+ }
+
+ /**
+ * Gets a value of a node at a specific index.
+ * Time complexity: O(n)
+ *
+ * @param index The index of the node.
+ * @returns The value of a node at the specified index.
+ */
+ get(index: number): T | null {
+ if (index < 0 || index >= this.length) {
+ return null
}
- /**
- * Gets a value of a node at a specific index.
- * Time complexity: O(n)
- *
- * @param index The index of the node.
- * @returns The value of a node at the specified index.
- */
- get(index: number): T | null {
- if (index < 0 || index >= this.length) {
- return null;
- }
-
- let currentNode: DoublyLinkedListNode | undefined = this.head;
- for (let i: number = 0; i < index; i++) {
- currentNode = currentNode?.next;
- }
-
- return currentNode?.value ?? null;
+ let currentNode: DoublyLinkedListNode | undefined = this.head
+ for (let i: number = 0; i < index; i++) {
+ currentNode = currentNode?.next
}
- /**
- * Inserts a node at the head of the list.
- * Time complexity: O(1)
- *
- * @param value The value of the node being inserted.
- */
- push(value: T): void {
- const newNode = new DoublyLinkedListNode(value);
-
- if (!this.head) {
- this.head = newNode;
- this.tail = newNode;
- } else {
- this.head.prev = newNode;
- newNode.next = this.head;
- this.head = newNode;
- }
-
- this.length++;
+ return currentNode?.value ?? null
+ }
+
+ /**
+ * Inserts a node at the head of the list.
+ * Time complexity: O(1)
+ *
+ * @param value The value of the node being inserted.
+ */
+ push(value: T): void {
+ const newNode = new DoublyLinkedListNode(value)
+
+ if (!this.head) {
+ this.head = newNode
+ this.tail = newNode
+ } else {
+ this.head.prev = newNode
+ newNode.next = this.head
+ this.head = newNode
}
- /**
- * Removes a node from the head of the list.
- * Time complexity: O(1)
- *
- * @returns The value of the node that was removed.
- * @throws Index out of bounds if the list is empty.
- */
- pop(): T {
- if (!this.head) {
- throw new Error("Index out of bounds");
- }
-
- const removedNode = this.head;
-
- if (this.head === this.tail) {
- this.tail = undefined;
- } else {
- this.head.next!.prev = undefined;
- }
-
- this.head = this.head.next;
- this.length--;
-
- return removedNode.value;
+ this.length++
+ }
+
+ /**
+ * Removes a node from the head of the list.
+ * Time complexity: O(1)
+ *
+ * @returns The value of the node that was removed.
+ * @throws Index out of bounds if the list is empty.
+ */
+ pop(): T {
+ if (!this.head) {
+ throw new Error('Index out of bounds')
}
- /**
- * Inserts a node at the tail of the list.
- * Time complexity: O(1)
- *
- * @param value The value of the node being inserted.
- */
- append(value: T): void {
- const newNode = new DoublyLinkedListNode(value);
-
- if (!this.head) {
- this.head = newNode;
- } else {
- this.tail!.next = newNode;
- newNode.prev = this.tail;
- }
-
- this.tail = newNode;
- this.length++;
- }
+ const removedNode = this.head
- /**
- * Removes a node from the tail of the list.
- * Time complexity: O(1)
- *
- * @returns The value of the node that was removed.
- * @throws Index out of bounds if the list is empty.
- */
- removeTail(): T {
- if (!this.head) {
- throw new Error("Index out of bounds");
- }
-
- const removedNode = this.tail;
-
- if (this.head === this.tail) {
- this.head = undefined;
- } else {
- this.tail!.prev!.next = undefined;
- }
-
- this.tail = this.tail!.prev;
- this.length--;
-
- return removedNode!.value;
+ if (this.head === this.tail) {
+ this.tail = undefined
+ } else {
+ this.head.next!.prev = undefined
}
- /**
- * Inserts a node at a specific index.
- * Time complexity: O(n)
- *
- * @param index The index where the node will be inserted.
- * @param value The value of the node being inserted.
- * @throws Index out of bounds if the index is not valid.
- */
- insertAt(index: number, value: T): void {
- if (index < 0 || index > this.length) {
- throw new Error("Index out of bounds");
- }
-
- if (index === 0) {
- this.push(value);
- return;
- }
-
- if (index === this.length) {
- this.append(value);
- return;
- }
-
- const newNode = new DoublyLinkedListNode(value);
- let prevNode: DoublyLinkedListNode | undefined = this.head;
- for (let i: number = 0; i < index - 1; i++) {
- prevNode = prevNode?.next;
- }
- const nextNode = prevNode?.next;
-
- prevNode!.next = newNode;
- newNode.prev = prevNode;
- newNode.next = nextNode;
- nextNode!.prev = newNode;
-
- this.length++;
+ this.head = this.head.next
+ this.length--
+
+ return removedNode.value
+ }
+
+ /**
+ * Inserts a node at the tail of the list.
+ * Time complexity: O(1)
+ *
+ * @param value The value of the node being inserted.
+ */
+ append(value: T): void {
+ const newNode = new DoublyLinkedListNode(value)
+
+ if (!this.head) {
+ this.head = newNode
+ } else {
+ this.tail!.next = newNode
+ newNode.prev = this.tail
}
- /**
- * Removes a node at a specific index.
- * Time complexity: O(n)
- *
- * @param index The index of the node to be removed.
- * @returns The value of the node that was removed.
- * @throws Index out of bounds if the index is not valid.
- */
- removeAt(index: number): T {
- if (index < 0 || index >= this.length) {
- throw new Error("Index out of bounds");
- }
-
- if (index === 0) {
- return this.pop();
- }
-
- if (index === this.length - 1) {
- return this.removeTail();
- }
-
- let removedNode: DoublyLinkedListNode | undefined = this.head;
- for (let i: number = 0; i < index; i++) {
- removedNode = removedNode?.next;
- }
- removedNode!.prev!.next = removedNode!.next;
- removedNode!.next!.prev = removedNode!.prev;
-
- this.length--;
-
- return removedNode!.value;
+ this.tail = newNode
+ this.length++
+ }
+
+ /**
+ * Removes a node from the tail of the list.
+ * Time complexity: O(1)
+ *
+ * @returns The value of the node that was removed.
+ * @throws Index out of bounds if the list is empty.
+ */
+ removeTail(): T {
+ if (!this.head) {
+ throw new Error('Index out of bounds')
}
- /**
- * Reverses the list.
- * Time complexity: O(n)
- *
- * @returns The reversed list or null if the list is empty.
- */
- reverse(): DoublyLinkedList | null {
- if (!this.head) {
- return null;
- }
+ const removedNode = this.tail
- let currentNode: DoublyLinkedListNode | undefined = this.head;
- let nextNode: DoublyLinkedListNode | undefined = undefined;
- let prevNode: DoublyLinkedListNode | undefined = undefined;
+ if (this.head === this.tail) {
+ this.head = undefined
+ } else {
+ this.tail!.prev!.next = undefined
+ }
- while (currentNode) {
- nextNode = currentNode.next;
- prevNode = currentNode.prev;
+ this.tail = this.tail!.prev
+ this.length--
+
+ return removedNode!.value
+ }
+
+ /**
+ * Inserts a node at a specific index.
+ * Time complexity: O(n)
+ *
+ * @param index The index where the node will be inserted.
+ * @param value The value of the node being inserted.
+ * @throws Index out of bounds if the index is not valid.
+ */
+ insertAt(index: number, value: T): void {
+ if (index < 0 || index > this.length) {
+ throw new Error('Index out of bounds')
+ }
- currentNode.next = prevNode;
- currentNode.prev = nextNode;
+ if (index === 0) {
+ this.push(value)
+ return
+ }
- prevNode = currentNode;
- currentNode = nextNode;
- }
+ if (index === this.length) {
+ this.append(value)
+ return
+ }
- this.tail = this.head;
- this.head = prevNode;
+ const newNode = new DoublyLinkedListNode(value)
+ let prevNode: DoublyLinkedListNode | undefined = this.head
+ for (let i: number = 0; i < index - 1; i++) {
+ prevNode = prevNode?.next
+ }
+ const nextNode = prevNode?.next
+
+ prevNode!.next = newNode
+ newNode.prev = prevNode
+ newNode.next = nextNode
+ nextNode!.prev = newNode
+
+ this.length++
+ }
+
+ /**
+ * Removes a node at a specific index.
+ * Time complexity: O(n)
+ *
+ * @param index The index of the node to be removed.
+ * @returns The value of the node that was removed.
+ * @throws Index out of bounds if the index is not valid.
+ */
+ removeAt(index: number): T {
+ if (index < 0 || index >= this.length) {
+ throw new Error('Index out of bounds')
+ }
- return this;
+ if (index === 0) {
+ return this.pop()
}
- /**
- * Clears the list.
- */
- clear(): void {
- this.head = undefined;
- this.tail = undefined;
- this.length = 0;
+ if (index === this.length - 1) {
+ return this.removeTail()
}
- /**
- * Converts the list to an array.
- *
- * @returns The array representation of the list.
- */
- toArray(): T[] {
- const array: T[] = [];
+ let removedNode: DoublyLinkedListNode | undefined = this.head
+ for (let i: number = 0; i < index; i++) {
+ removedNode = removedNode?.next
+ }
+ removedNode!.prev!.next = removedNode!.next
+ removedNode!.next!.prev = removedNode!.prev
+
+ this.length--
+
+ return removedNode!.value
+ }
+
+ /**
+ * Reverses the list.
+ * Time complexity: O(n)
+ *
+ * @returns The reversed list or null if the list is empty.
+ */
+ reverse(): DoublyLinkedList | null {
+ if (!this.head) {
+ return null
+ }
- let currentNode: DoublyLinkedListNode | undefined = this.head;
+ let currentNode: DoublyLinkedListNode | undefined = this.head
+ let nextNode: DoublyLinkedListNode | undefined = undefined
+ let prevNode: DoublyLinkedListNode | undefined = undefined
- while (currentNode) {
- array.push(currentNode.value);
- currentNode = currentNode.next;
- }
+ while (currentNode) {
+ nextNode = currentNode.next
+ prevNode = currentNode.prev
- return array;
+ currentNode.next = prevNode
+ currentNode.prev = nextNode
+
+ prevNode = currentNode
+ currentNode = nextNode
}
- /**
- * Gets the length of the list.
- *
- * @returns The length of the list.
- */
- getLength(): number {
- return this.length;
+ this.tail = this.head
+ this.head = prevNode
+
+ return this
+ }
+
+ /**
+ * Clears the list.
+ */
+ clear(): void {
+ this.head = undefined
+ this.tail = undefined
+ this.length = 0
+ }
+
+ /**
+ * Converts the list to an array.
+ *
+ * @returns The array representation of the list.
+ */
+ toArray(): T[] {
+ const array: T[] = []
+
+ let currentNode: DoublyLinkedListNode | undefined = this.head
+
+ while (currentNode) {
+ array.push(currentNode.value)
+ currentNode = currentNode.next
}
+
+ return array
+ }
+
+ /**
+ * Gets the length of the list.
+ *
+ * @returns The length of the list.
+ */
+ getLength(): number {
+ return this.length
+ }
}
/**
@@ -288,9 +288,9 @@ export class DoublyLinkedList implements LinkedList {
* @property prev The previous node before this node.
*/
class DoublyLinkedListNode {
- constructor(
- public value: T,
- public next?: DoublyLinkedListNode,
- public prev?: DoublyLinkedListNode
- ) {}
+ constructor(
+ public value: T,
+ public next?: DoublyLinkedListNode,
+ public prev?: DoublyLinkedListNode
+ ) {}
}
diff --git a/data_structures/list/linked_list.ts b/data_structures/list/linked_list.ts
index 596af23b..8c6eee94 100644
--- a/data_structures/list/linked_list.ts
+++ b/data_structures/list/linked_list.ts
@@ -2,15 +2,15 @@
* An interface for linked lists, which shares the common methods.
*/
export interface LinkedList {
- isEmpty(): boolean;
- get(index: number): T | null | undefined;
- push(data: T): void;
- pop(): T | undefined;
- append(data: T): void;
- removeTail(): T | undefined;
- insertAt(index: number, data: T): void;
- removeAt(index: number): T | undefined;
- clear(): void;
- toArray(): (T | undefined)[];
- getLength(): number;
+ isEmpty(): boolean
+ get(index: number): T | null | undefined
+ push(data: T): void
+ pop(): T | undefined
+ append(data: T): void
+ removeTail(): T | undefined
+ insertAt(index: number, data: T): void
+ removeAt(index: number): T | undefined
+ clear(): void
+ toArray(): (T | undefined)[]
+ getLength(): number
}
diff --git a/data_structures/list/singly_linked_list.ts b/data_structures/list/singly_linked_list.ts
index 56172a8c..0a3ef7b2 100644
--- a/data_structures/list/singly_linked_list.ts
+++ b/data_structures/list/singly_linked_list.ts
@@ -1,4 +1,4 @@
-import { LinkedList } from "./linked_list";
+import { LinkedList } from './linked_list'
/**
* Represents a node in a linked list.
@@ -8,7 +8,10 @@ import { LinkedList } from "./linked_list";
* @property next A reference to the next node in the list. Can reference to null, if there is no next element.
*/
class ListNode {
- constructor(public data: T, public next?: ListNode) {}
+ constructor(
+ public data: T,
+ public next?: ListNode
+ ) {}
}
/**
@@ -23,17 +26,17 @@ class ListNode {
* @property length The length of the list.
*/
export class SinglyLinkedList implements LinkedList {
- private head?: ListNode;
- private tail?: ListNode;
- private length: number;
+ private head?: ListNode
+ private tail?: ListNode
+ private length: number
/**
* Creates a new, empty linked list.
*/
constructor() {
- this.head = undefined;
- this.tail = undefined;
- this.length = 0;
+ this.head = undefined
+ this.tail = undefined
+ this.length = 0
}
/**
@@ -42,7 +45,7 @@ export class SinglyLinkedList implements LinkedList {
* @returns Whether the list is empty or not.
*/
isEmpty(): boolean {
- return !this.head;
+ return !this.head
}
/**
@@ -54,23 +57,23 @@ export class SinglyLinkedList implements LinkedList {
*/
get(index: number): T | null {
if (index < 0 || index >= this.length) {
- return null;
+ return null
}
if (this.isEmpty()) {
- return null;
+ return null
}
- let currentNode: ListNode = this.head!;
+ let currentNode: ListNode = this.head!
for (let i: number = 0; i < index; i++) {
if (!currentNode.next) {
- return null;
+ return null
}
- currentNode = currentNode.next;
+ currentNode = currentNode.next
}
- return currentNode.data;
+ return currentNode.data
}
/**
@@ -80,17 +83,17 @@ export class SinglyLinkedList implements LinkedList {
* @param data The data to be inserted.
*/
push(data: T): void {
- const node: ListNode = new ListNode(data);
+ const node: ListNode = new ListNode(data)
if (this.isEmpty()) {
- this.head = node;
- this.tail = node;
+ this.head = node
+ this.tail = node
} else {
- node.next = this.head;
- this.head = node;
+ node.next = this.head
+ this.head = node
}
- this.length++;
+ this.length++
}
/**
@@ -102,14 +105,14 @@ export class SinglyLinkedList implements LinkedList {
*/
pop(): T {
if (this.isEmpty()) {
- throw new Error('Index out of bounds');
+ throw new Error('Index out of bounds')
}
- const node: ListNode = this.head!;
- this.head = this.head!.next;
- this.length--;
+ const node: ListNode = this.head!
+ this.head = this.head!.next
+ this.length--
- return node.data;
+ return node.data
}
/**
@@ -119,16 +122,16 @@ export class SinglyLinkedList implements LinkedList {
* @param data The data of the node being inserted.
*/
append(data: T): void {
- const node: ListNode = new ListNode(data);
+ const node: ListNode = new ListNode(data)
if (this.isEmpty()) {
- this.head = node;
+ this.head = node
} else {
- this.tail!.next = node;
+ this.tail!.next = node
}
- this.tail = node;
- this.length++;
+ this.tail = node
+ this.length++
}
/**
@@ -140,27 +143,27 @@ export class SinglyLinkedList implements LinkedList {
*/
removeTail(): T {
if (!this.head) {
- throw new Error('Index out of bounds');
+ throw new Error('Index out of bounds')
}
- const currentTail = this.tail;
+ const currentTail = this.tail
if (this.head === this.tail) {
- this.head = undefined;
- this.tail = undefined;
- this.length--;
+ this.head = undefined
+ this.tail = undefined
+ this.length--
- return currentTail!.data;
+ return currentTail!.data
}
- let currentNode: ListNode = this.head;
+ let currentNode: ListNode = this.head
while (currentNode.next !== currentTail) {
- currentNode = currentNode.next!;
+ currentNode = currentNode.next!
}
- this.tail = currentNode;
- this.length--;
+ this.tail = currentNode
+ this.length--
- return currentTail!.data;
+ return currentTail!.data
}
/**
@@ -173,32 +176,32 @@ export class SinglyLinkedList implements LinkedList {
*/
insertAt(index: number, data: T): void {
if (index < 0 || index > this.length) {
- throw new Error('Index out of bounds');
+ throw new Error('Index out of bounds')
}
if (index === 0) {
- this.push(data);
+ this.push(data)
- return;
+ return
}
if (index === this.length) {
- this.append(data);
+ this.append(data)
- return;
+ return
}
- const newNode = new ListNode(data);
- let currentNode: ListNode | undefined = this.head;
+ const newNode = new ListNode(data)
+ let currentNode: ListNode | undefined = this.head
for (let i: number = 0; i < index - 1; i++) {
- currentNode = currentNode?.next;
+ currentNode = currentNode?.next
}
- const nextNode = currentNode?.next;
- currentNode!.next = newNode;
- newNode.next = nextNode;
+ const nextNode = currentNode?.next
+ currentNode!.next = newNode
+ newNode.next = nextNode
- this.length++;
+ this.length++
}
/**
@@ -211,40 +214,40 @@ export class SinglyLinkedList implements LinkedList {
*/
removeAt(index: number): T {
if (index < 0 || index >= this.length) {
- throw new Error('Index out of bounds');
+ throw new Error('Index out of bounds')
}
if (index === 0) {
- return this.pop();
+ return this.pop()
}
if (index === this.length - 1) {
- return this.removeTail();
+ return this.removeTail()
}
- let previousNode: ListNode | undefined;
- let currentNode: ListNode | undefined = this.head;
+ let previousNode: ListNode | undefined
+ let currentNode: ListNode | undefined = this.head
for (let i: number = 0; i < index; i++) {
if (i === index - 1) {
- previousNode = currentNode;
+ previousNode = currentNode
}
- currentNode = currentNode?.next;
+ currentNode = currentNode?.next
}
- previousNode!.next = currentNode?.next;
- this.length--;
+ previousNode!.next = currentNode?.next
+ this.length--
- return currentNode!.data;
+ return currentNode!.data
}
/**
* Clears the list.
*/
clear(): void {
- this.head = undefined;
- this.tail = undefined;
- this.length = 0;
+ this.head = undefined
+ this.tail = undefined
+ this.length = 0
}
/**
@@ -253,15 +256,15 @@ export class SinglyLinkedList implements LinkedList {
* @returns The array representation of the list.
*/
toArray(): T[] {
- const array: T[] = [];
- let currentNode: ListNode | undefined = this.head;
+ const array: T[] = []
+ let currentNode: ListNode | undefined = this.head
while (currentNode) {
- array.push(currentNode.data);
- currentNode = currentNode.next;
+ array.push(currentNode.data)
+ currentNode = currentNode.next
}
- return array;
+ return array
}
/**
@@ -270,6 +273,6 @@ export class SinglyLinkedList implements LinkedList {
* @returns The length of the list.
*/
getLength(): number {
- return this.length;
+ return this.length
}
}
diff --git a/data_structures/list/test/doubly_linked_list.test.ts b/data_structures/list/test/doubly_linked_list.test.ts
index 2e41d3af..f0c611cd 100644
--- a/data_structures/list/test/doubly_linked_list.test.ts
+++ b/data_structures/list/test/doubly_linked_list.test.ts
@@ -1,24 +1,24 @@
-import { DoublyLinkedList } from "../doubly_linked_list";
-import { testLinkedList } from "./linked_list";
+import { DoublyLinkedList } from '../doubly_linked_list'
+import { testLinkedList } from './linked_list'
-describe("DoublyLinkedList", () => {
- testLinkedList(DoublyLinkedList);
+describe('DoublyLinkedList', () => {
+ testLinkedList(DoublyLinkedList)
- it("should reverse the list", () => {
- const list: DoublyLinkedList = new DoublyLinkedList();
+ it('should reverse the list', () => {
+ const list: DoublyLinkedList = new DoublyLinkedList()
- list.append(1);
- list.append(2);
- list.append(3);
- list.reverse();
+ list.append(1)
+ list.append(2)
+ list.append(3)
+ list.reverse()
- expect(list.get(0)).toBe(3);
- expect(list.get(1)).toBe(2);
- });
+ expect(list.get(0)).toBe(3)
+ expect(list.get(1)).toBe(2)
+ })
- it("should return null for reverse when list is empty", () => {
- const list: DoublyLinkedList = new DoublyLinkedList();
+ it('should return null for reverse when list is empty', () => {
+ const list: DoublyLinkedList = new DoublyLinkedList()
- expect(list.reverse()).toBeNull();
- });
-});
+ expect(list.reverse()).toBeNull()
+ })
+})
diff --git a/data_structures/list/test/linked_list.ts b/data_structures/list/test/linked_list.ts
index 5717ab15..6d76c930 100644
--- a/data_structures/list/test/linked_list.ts
+++ b/data_structures/list/test/linked_list.ts
@@ -1,109 +1,109 @@
-import { LinkedList } from "../linked_list";
+import { LinkedList } from '../linked_list'
-type LinkedListConstructor = new () => LinkedList;
+type LinkedListConstructor = new () => LinkedList
export function testLinkedList(LinkedList: LinkedListConstructor) {
describe('with filled list (push)', () => {
- let list: LinkedList = new LinkedList;
+ let list: LinkedList = new LinkedList()
beforeEach(() => {
- list = new LinkedList();
- list.push(1);
- list.push(2);
- list.push(3);
- });
+ list = new LinkedList()
+ list.push(1)
+ list.push(2)
+ list.push(3)
+ })
it('should return false for isEmpty when list is not empty', () => {
- expect(list.isEmpty()).toBeFalsy();
- });
+ expect(list.isEmpty()).toBeFalsy()
+ })
it('should return correct node for get', () => {
- expect(list.get(1)).toBe(2);
- });
+ expect(list.get(1)).toBe(2)
+ })
it('should push nodes to the list and return correct head and tail', () => {
- expect(list.get(0)).toBe(3);
- expect(list.get(2)).toBe(1);
- });
+ expect(list.get(0)).toBe(3)
+ expect(list.get(2)).toBe(1)
+ })
it('should pop nodes from the list and return correct head and tail', () => {
- expect(list.pop()).toBe(3);
- expect(list.get(0)).toBe(2);
- expect(list.get(1)).toBe(1);
- });
- });
+ expect(list.pop()).toBe(3)
+ expect(list.get(0)).toBe(2)
+ expect(list.get(1)).toBe(1)
+ })
+ })
describe('with filled list (append)', () => {
- let list: LinkedList = new LinkedList();
+ let list: LinkedList = new LinkedList()
beforeEach(() => {
- list = new LinkedList();
- list.append(1);
- list.append(2);
- list.append(3);
- });
+ list = new LinkedList()
+ list.append(1)
+ list.append(2)
+ list.append(3)
+ })
it('should append nodes to the list and return correct head and tail', () => {
- expect(list.get(0)).toBe(1);
- expect(list.get(2)).toBe(3);
- });
+ expect(list.get(0)).toBe(1)
+ expect(list.get(2)).toBe(3)
+ })
it('should remove tail from the list and return correct head and tail', () => {
- expect(list.removeTail()).toBe(3);
- expect(list.get(0)).toBe(1);
- expect(list.get(1)).toBe(2);
- });
+ expect(list.removeTail()).toBe(3)
+ expect(list.get(0)).toBe(1)
+ expect(list.get(1)).toBe(2)
+ })
it('should insert nodes at the correct index', () => {
- list.insertAt(1, 4);
+ list.insertAt(1, 4)
- expect(list.get(1)).toBe(4);
- });
+ expect(list.get(1)).toBe(4)
+ })
it('should remove nodes at the correct index', () => {
- expect(list.removeAt(1)).toBe(2);
- });
+ expect(list.removeAt(1)).toBe(2)
+ })
it('should return null for removeAt when index is out of bounds', () => {
- expect(() => list.removeAt(3)).toThrowError('Index out of bounds');
- });
+ expect(() => list.removeAt(3)).toThrowError('Index out of bounds')
+ })
it('should clear the list', () => {
- list.clear();
+ list.clear()
- expect(list.isEmpty()).toBeTruthy();
- });
+ expect(list.isEmpty()).toBeTruthy()
+ })
it('should convert the list to an array', () => {
- expect(list.toArray()).toEqual([1, 2, 3]);
- });
+ expect(list.toArray()).toEqual([1, 2, 3])
+ })
it('should return correct length', () => {
- expect(list.getLength()).toBe(3);
- });
- });
+ expect(list.getLength()).toBe(3)
+ })
+ })
describe('with empty list', () => {
- let list: LinkedList;
+ let list: LinkedList
beforeEach(() => {
- list = new LinkedList();
- });
+ list = new LinkedList()
+ })
it('should return true for isEmpty when list is empty', () => {
- expect(list.isEmpty()).toBeTruthy();
- });
+ expect(list.isEmpty()).toBeTruthy()
+ })
it('should return null for get when index is out of bounds', () => {
- expect(list.get(1)).toBeNull();
- });
+ expect(list.get(1)).toBeNull()
+ })
it('should throw error for pop when list is empty', () => {
- expect(() => list.pop()).toThrowError('Index out of bounds');
- });
+ expect(() => list.pop()).toThrowError('Index out of bounds')
+ })
it('should return null for removeTail when list is empty', () => {
- expect(() => list.removeTail()).toThrowError('Index out of bounds');
- });
- });
-}
\ No newline at end of file
+ expect(() => list.removeTail()).toThrowError('Index out of bounds')
+ })
+ })
+}
diff --git a/data_structures/list/test/singly_linked_list.test.ts b/data_structures/list/test/singly_linked_list.test.ts
index 0754c5e6..80ef33d5 100644
--- a/data_structures/list/test/singly_linked_list.test.ts
+++ b/data_structures/list/test/singly_linked_list.test.ts
@@ -1,4 +1,4 @@
-import { SinglyLinkedList } from "../singly_linked_list";
-import { testLinkedList } from "./linked_list";
+import { SinglyLinkedList } from '../singly_linked_list'
+import { testLinkedList } from './linked_list'
-describe("Singly linked list", () => testLinkedList(SinglyLinkedList));
\ No newline at end of file
+describe('Singly linked list', () => testLinkedList(SinglyLinkedList))
diff --git a/data_structures/map/hash_map.ts b/data_structures/map/hash_map.ts
index 900848a5..ed121110 100644
--- a/data_structures/map/hash_map.ts
+++ b/data_structures/map/hash_map.ts
@@ -1,4 +1,4 @@
-import { Map } from "./map";
+import { Map } from './map'
/**
* Represents a hash map.
@@ -14,210 +14,210 @@ import { Map } from "./map";
* @param loadFactor The load factor to determine when to resize the hash map.
*/
export class HashMap implements Map {
- private size!: number;
- private buckets!: MapEntry[][];
- private readonly loadFactor = 0.75;
-
- constructor() {
- this.clear();
+ private size!: number
+ private buckets!: MapEntry[][]
+ private readonly loadFactor = 0.75
+
+ constructor() {
+ this.clear()
+ }
+
+ /**
+ * Gets the size.
+ *
+ * @returns The size.
+ */
+ getSize(): number {
+ return this.size
+ }
+
+ /**
+ * Sets a key-value pair.
+ *
+ * @param key The key.
+ * @param value The value.
+ */
+ set(key: K, value: V): void {
+ const loadFactor = this.size / this.buckets.length
+ if (loadFactor > this.loadFactor) {
+ this.resize()
}
- /**
- * Gets the size.
- *
- * @returns The size.
- */
- getSize(): number {
- return this.size;
- }
+ const index = this.hash(key)
+ const bucket = this.buckets[index]
- /**
- * Sets a key-value pair.
- *
- * @param key The key.
- * @param value The value.
- */
- set(key: K, value: V): void {
- const loadFactor = this.size / this.buckets.length;
- if (loadFactor > this.loadFactor) {
- this.resize();
- }
-
- const index = this.hash(key);
- const bucket = this.buckets[index];
-
- if (bucket.length === 0) {
- bucket.push(new MapEntry(key, value));
- this.size++;
- return;
- }
-
- for (const entry of bucket) {
- if (entry.key === key) {
- entry.value = value;
- return;
- }
- }
-
- bucket.push(new MapEntry(key, value));
- this.size++;
+ if (bucket.length === 0) {
+ bucket.push(new MapEntry(key, value))
+ this.size++
+ return
}
- /**
- * Gets a value.
- *
- * @param key The key to get the value for.
- * @returns The value or null if the key does not exist.
- */
- get(key: K): V | null {
- const index = this.hash(key);
- const bucket = this.buckets[index];
-
- for (const entry of bucket) {
- if (entry.key === key) {
- return entry.value;
- }
- }
-
- return null;
+ for (const entry of bucket) {
+ if (entry.key === key) {
+ entry.value = value
+ return
+ }
}
- /**
- * Deletes a key-value pair.
- *
- * @param key The key whose key-value pair to delete.
- */
- delete(key: K): void {
- const index = this.hash(key);
- const bucket = this.buckets[index];
-
- for (const entry of bucket) {
- if (entry.key === key) {
- bucket.splice(bucket.indexOf(entry), 1);
- this.size--;
- return;
- }
- }
+ bucket.push(new MapEntry(key, value))
+ this.size++
+ }
+
+ /**
+ * Gets a value.
+ *
+ * @param key The key to get the value for.
+ * @returns The value or null if the key does not exist.
+ */
+ get(key: K): V | null {
+ const index = this.hash(key)
+ const bucket = this.buckets[index]
+
+ for (const entry of bucket) {
+ if (entry.key === key) {
+ return entry.value
+ }
}
- /**
- * Checks if a key exists.
- *
- * @param key The key.
- * @returns Whether the key exists.
- */
- has(key: K): boolean {
- const index = this.hash(key);
- const bucket = this.buckets[index];
-
- for (const entry of bucket) {
- if (entry.key === key) {
- return true;
- }
- }
-
- return false;
+ return null
+ }
+
+ /**
+ * Deletes a key-value pair.
+ *
+ * @param key The key whose key-value pair to delete.
+ */
+ delete(key: K): void {
+ const index = this.hash(key)
+ const bucket = this.buckets[index]
+
+ for (const entry of bucket) {
+ if (entry.key === key) {
+ bucket.splice(bucket.indexOf(entry), 1)
+ this.size--
+ return
+ }
}
-
- /**
- * Clears the hash map.
- */
- clear(): void {
- this.size = 0;
- this.initializeBuckets(16);
+ }
+
+ /**
+ * Checks if a key exists.
+ *
+ * @param key The key.
+ * @returns Whether the key exists.
+ */
+ has(key: K): boolean {
+ const index = this.hash(key)
+ const bucket = this.buckets[index]
+
+ for (const entry of bucket) {
+ if (entry.key === key) {
+ return true
+ }
}
- /**
- * Gets all keys.
- *
- * @returns The keys.
- */
- keys(): K[] {
- const keys: K[] = [];
- for (const bucket of this.buckets) {
- for (const entry of bucket) {
- keys.push(entry.key);
- }
- }
-
- return keys;
+ return false
+ }
+
+ /**
+ * Clears the hash map.
+ */
+ clear(): void {
+ this.size = 0
+ this.initializeBuckets(16)
+ }
+
+ /**
+ * Gets all keys.
+ *
+ * @returns The keys.
+ */
+ keys(): K[] {
+ const keys: K[] = []
+ for (const bucket of this.buckets) {
+ for (const entry of bucket) {
+ keys.push(entry.key)
+ }
}
- /**
- * Gets all values.
- *
- * @returns The values.
- */
- values(): V[] {
- const values: V[] = [];
- for (const bucket of this.buckets) {
- for (const entry of bucket) {
- values.push(entry.value);
- }
- }
-
- return values;
+ return keys
+ }
+
+ /**
+ * Gets all values.
+ *
+ * @returns The values.
+ */
+ values(): V[] {
+ const values: V[] = []
+ for (const bucket of this.buckets) {
+ for (const entry of bucket) {
+ values.push(entry.value)
+ }
}
- /**
- * Gets all entries.
- *
- * @returns The entries.
- */
- entries(): MapEntry[] {
- const entries: MapEntry[] = [];
- for (const bucket of this.buckets) {
- for (const entry of bucket) {
- entries.push(entry);
- }
- }
-
- return entries;
+ return values
+ }
+
+ /**
+ * Gets all entries.
+ *
+ * @returns The entries.
+ */
+ entries(): MapEntry[] {
+ const entries: MapEntry[] = []
+ for (const bucket of this.buckets) {
+ for (const entry of bucket) {
+ entries.push(entry)
+ }
}
- /**
- * Initializes the buckets.
- *
- * @param amount The amount of buckets to initialize.
- */
- private initializeBuckets(amount: number): void {
- this.buckets = [];
- for (let i = 0; i < amount; i++) {
- this.buckets.push([]);
- }
+ return entries
+ }
+
+ /**
+ * Initializes the buckets.
+ *
+ * @param amount The amount of buckets to initialize.
+ */
+ private initializeBuckets(amount: number): void {
+ this.buckets = []
+ for (let i = 0; i < amount; i++) {
+ this.buckets.push([])
}
-
- /**
- * Hashes a key to an index.
- * This implementation uses the djb2 algorithm, which might not be the best.
- * Feel free to change it to something else.
- *
- * @param key The key.
- * @return The index.
- */
- protected hash(key: K): number {
- let hash = 0;
-
- for (let i = 0; i < String(key).length; i++) {
- hash = (hash << 5) - hash + String(key).charCodeAt(i);
- }
-
- return hash % this.buckets.length;
+ }
+
+ /**
+ * Hashes a key to an index.
+ * This implementation uses the djb2 algorithm, which might not be the best.
+ * Feel free to change it to something else.
+ *
+ * @param key The key.
+ * @return The index.
+ */
+ protected hash(key: K): number {
+ let hash = 0
+
+ for (let i = 0; i < String(key).length; i++) {
+ hash = (hash << 5) - hash + String(key).charCodeAt(i)
}
- /**
- * Resizes the hash map by doubling the amount of buckets.
- */
- private resize(): void {
- const entries = this.entries();
+ return hash % this.buckets.length
+ }
+
+ /**
+ * Resizes the hash map by doubling the amount of buckets.
+ */
+ private resize(): void {
+ const entries = this.entries()
- this.initializeBuckets(this.buckets.length * 2);
- this.size = 0;
+ this.initializeBuckets(this.buckets.length * 2)
+ this.size = 0
- for (const entry of entries) {
- this.set(entry.key, entry.value);
- }
+ for (const entry of entries) {
+ this.set(entry.key, entry.value)
}
+ }
}
/**
@@ -229,11 +229,11 @@ export class HashMap implements Map {
* @param value The value.
*/
export class MapEntry {
- key: K;
- value: V;
+ key: K
+ value: V
- constructor(key: K, value: V) {
- this.key = key;
- this.value = value;
- }
+ constructor(key: K, value: V) {
+ this.key = key
+ this.value = value
+ }
}
diff --git a/data_structures/map/map.ts b/data_structures/map/map.ts
index ff2a9fc3..4c3bab55 100644
--- a/data_structures/map/map.ts
+++ b/data_structures/map/map.ts
@@ -1,16 +1,16 @@
-import { MapEntry } from "./hash_map";
+import { MapEntry } from './hash_map'
/**
* This interface is a representation of the Map data structure.
*/
export interface Map {
- getSize(): number;
- set(key: K, value: V): void;
- get(key: K): V | null;
- delete(key: K): void;
- has(key: K): boolean;
- clear(): void;
- keys(): K[];
- values(): V[];
- entries(): MapEntry[];
+ getSize(): number
+ set(key: K, value: V): void
+ get(key: K): V | null
+ delete(key: K): void
+ has(key: K): boolean
+ clear(): void
+ keys(): K[]
+ values(): V[]
+ entries(): MapEntry[]
}
diff --git a/data_structures/map/test/hash_map.test.ts b/data_structures/map/test/hash_map.test.ts
index 16640e97..c2927a28 100644
--- a/data_structures/map/test/hash_map.test.ts
+++ b/data_structures/map/test/hash_map.test.ts
@@ -1,109 +1,109 @@
-import { HashMap } from "../../map/hash_map";
-
-describe("Hash Map", () => {
- let hashMap: HashMap;
- beforeEach(() => {
- hashMap = new HashMap();
- });
-
- it("should set a value", () => {
- hashMap.set("a", 1);
-
- expect(hashMap.values()).toEqual([1]);
- });
-
- it("should override a value", () => {
- hashMap.set("a", 1);
- hashMap.set("a", 2);
-
- expect(hashMap.values()).toEqual([2]);
- });
-
- it("should get a value", () => {
- hashMap.set("a", 1);
-
- expect(hashMap.get("a")).toBe(1);
- });
-
- it("should get null if key does not exist", () => {
- expect(hashMap.get("a")).toBeNull();
- });
-
- it("should delete a value", () => {
- hashMap.set("a", 1);
- hashMap.delete("a");
-
- expect(hashMap.get("a")).toBeNull();
- });
-
- it("should do nothing on delete if key does not exist", () => {
- hashMap.delete("a");
-
- expect(hashMap.get("a")).toBeNull();
- });
-
- it("should return true if key exists", () => {
- hashMap.set("a", 1);
-
- expect(hashMap.has("a")).toBe(true);
- });
-
- it("should return false if key does not exist", () => {
- expect(hashMap.has("a")).toBe(false);
- });
-
- it("should clear the hash table", () => {
- hashMap.set("a", 1);
- hashMap.set("b", 2);
- hashMap.set("c", 3);
- hashMap.clear();
-
- expect(hashMap.getSize()).toBe(0);
- });
-
- it("should return all keys", () => {
- hashMap.set("a", 1);
- hashMap.set("b", 2);
- hashMap.set("c", 3);
-
- expect(hashMap.keys()).toEqual(["a", "b", "c"]);
- });
-
- it("should return all values", () => {
- hashMap.set("a", 1);
- hashMap.set("b", 2);
- hashMap.set("c", 3);
-
- expect(hashMap.values()).toEqual([1, 2, 3]);
- });
-
- it("should return all key-value pairs", () => {
- hashMap.set("a", 1);
- hashMap.set("b", 2);
- hashMap.set("c", 3);
-
- expect(hashMap.entries()).toEqual([
- { key: "a", value: 1 },
- { key: "b", value: 2 },
- { key: "c", value: 3 },
- ]);
- });
-
- it("should keep entries when trigger resize", () => {
- hashMap.set('a', 1);
- hashMap.set('b', 2);
- hashMap.set('c', 3);
- hashMap.set('d', 4);
- hashMap.set('e', 5);
- hashMap.set('f', 6);
- hashMap.set('g', 7);
- hashMap.set('h', 8);
- hashMap.set('i', 9);
- hashMap.set('j', 10);
- hashMap.set('k', 11);
- hashMap.set('l', 12);
- hashMap.set('m', 13);
- hashMap.set('n', 14);
- expect(hashMap.getSize()).toBe(14);
- })
-});
+import { HashMap } from '../../map/hash_map'
+
+describe('Hash Map', () => {
+ let hashMap: HashMap
+ beforeEach(() => {
+ hashMap = new HashMap()
+ })
+
+ it('should set a value', () => {
+ hashMap.set('a', 1)
+
+ expect(hashMap.values()).toEqual([1])
+ })
+
+ it('should override a value', () => {
+ hashMap.set('a', 1)
+ hashMap.set('a', 2)
+
+ expect(hashMap.values()).toEqual([2])
+ })
+
+ it('should get a value', () => {
+ hashMap.set('a', 1)
+
+ expect(hashMap.get('a')).toBe(1)
+ })
+
+ it('should get null if key does not exist', () => {
+ expect(hashMap.get('a')).toBeNull()
+ })
+
+ it('should delete a value', () => {
+ hashMap.set('a', 1)
+ hashMap.delete('a')
+
+ expect(hashMap.get('a')).toBeNull()
+ })
+
+ it('should do nothing on delete if key does not exist', () => {
+ hashMap.delete('a')
+
+ expect(hashMap.get('a')).toBeNull()
+ })
+
+ it('should return true if key exists', () => {
+ hashMap.set('a', 1)
+
+ expect(hashMap.has('a')).toBe(true)
+ })
+
+ it('should return false if key does not exist', () => {
+ expect(hashMap.has('a')).toBe(false)
+ })
+
+ it('should clear the hash table', () => {
+ hashMap.set('a', 1)
+ hashMap.set('b', 2)
+ hashMap.set('c', 3)
+ hashMap.clear()
+
+ expect(hashMap.getSize()).toBe(0)
+ })
+
+ it('should return all keys', () => {
+ hashMap.set('a', 1)
+ hashMap.set('b', 2)
+ hashMap.set('c', 3)
+
+ expect(hashMap.keys()).toEqual(['a', 'b', 'c'])
+ })
+
+ it('should return all values', () => {
+ hashMap.set('a', 1)
+ hashMap.set('b', 2)
+ hashMap.set('c', 3)
+
+ expect(hashMap.values()).toEqual([1, 2, 3])
+ })
+
+ it('should return all key-value pairs', () => {
+ hashMap.set('a', 1)
+ hashMap.set('b', 2)
+ hashMap.set('c', 3)
+
+ expect(hashMap.entries()).toEqual([
+ { key: 'a', value: 1 },
+ { key: 'b', value: 2 },
+ { key: 'c', value: 3 }
+ ])
+ })
+
+ it('should keep entries when trigger resize', () => {
+ hashMap.set('a', 1)
+ hashMap.set('b', 2)
+ hashMap.set('c', 3)
+ hashMap.set('d', 4)
+ hashMap.set('e', 5)
+ hashMap.set('f', 6)
+ hashMap.set('g', 7)
+ hashMap.set('h', 8)
+ hashMap.set('i', 9)
+ hashMap.set('j', 10)
+ hashMap.set('k', 11)
+ hashMap.set('l', 12)
+ hashMap.set('m', 13)
+ hashMap.set('n', 14)
+ expect(hashMap.getSize()).toBe(14)
+ })
+})
diff --git a/data_structures/queue/array_queue.ts b/data_structures/queue/array_queue.ts
index 19027768..0f53c270 100644
--- a/data_structures/queue/array_queue.ts
+++ b/data_structures/queue/array_queue.ts
@@ -5,60 +5,60 @@
* The time complexity of the operations is O(n).
*/
import { Queue } from './queue'
-export class ArrayQueue implements Queue{
- private queue: T[] = [];
+export class ArrayQueue implements Queue {
+ private queue: T[] = []
- /**
- * Returns the number of items in the queue.
- *
- * @returns {number} The number of items in the queue.
- */
- length(): number {
- return this.queue.length;
- }
+ /**
+ * Returns the number of items in the queue.
+ *
+ * @returns {number} The number of items in the queue.
+ */
+ length(): number {
+ return this.queue.length
+ }
- /**
- * Checks if the queue is empty.
- *
- * @returns {boolean} Whether the queue is empty or not.
- */
- isEmpty(): boolean {
- return this.queue.length === 0;
- }
+ /**
+ * Checks if the queue is empty.
+ *
+ * @returns {boolean} Whether the queue is empty or not.
+ */
+ isEmpty(): boolean {
+ return this.queue.length === 0
+ }
- /**
- * Adds an item to the queue.
- *
- * @param item The item being added to the queue.
- */
- enqueue(item: T): void {
- this.queue.push(item);
- }
+ /**
+ * Adds an item to the queue.
+ *
+ * @param item The item being added to the queue.
+ */
+ enqueue(item: T): void {
+ this.queue.push(item)
+ }
- /**
- * Removes an item from the queue and returns it.
- *
- * @throws Queue Underflow if the queue is empty.
- * @returns The item that was removed from the queue.
- */
- dequeue(): T {
- if (this.isEmpty()) {
- throw new Error("Queue Underflow");
- }
-
- return this.queue.shift() as T;
+ /**
+ * Removes an item from the queue and returns it.
+ *
+ * @throws Queue Underflow if the queue is empty.
+ * @returns The item that was removed from the queue.
+ */
+ dequeue(): T {
+ if (this.isEmpty()) {
+ throw new Error('Queue Underflow')
}
- /**
- * Returns the item at the front of the queue.
- *
- * @returns The item at the front of the queue or null if the queue is empty.
- */
- peek(): T | null {
- if (this.isEmpty()) {
- return null;
- }
+ return this.queue.shift() as T
+ }
- return this.queue[0];
+ /**
+ * Returns the item at the front of the queue.
+ *
+ * @returns The item at the front of the queue or null if the queue is empty.
+ */
+ peek(): T | null {
+ if (this.isEmpty()) {
+ return null
}
+
+ return this.queue[0]
+ }
}
diff --git a/data_structures/queue/circular_queue.ts b/data_structures/queue/circular_queue.ts
index ce42e059..8d278163 100644
--- a/data_structures/queue/circular_queue.ts
+++ b/data_structures/queue/circular_queue.ts
@@ -8,102 +8,102 @@
* @param {number} size The size of the queue.
*/
export class CircularQueue {
- private queue: T[];
- private frontIndex: number;
- private rearIndex: number;
- private size: number;
+ private queue: T[]
+ private frontIndex: number
+ private rearIndex: number
+ private size: number
- constructor(size: number) {
- this.queue = new Array(size);
- this.frontIndex = -1;
- this.rearIndex = -1;
- this.size = size;
- }
+ constructor(size: number) {
+ this.queue = new Array(size)
+ this.frontIndex = -1
+ this.rearIndex = -1
+ this.size = size
+ }
- /**
- * Adds an item to the queue.
- *
- * @param item The item being added to the queue.
- */
- enqueue(item: T): void {
- if (
- (this.frontIndex == 0 && this.rearIndex == this.size - 1) ||
- this.rearIndex == (this.frontIndex - 1) % (this.size - 1)
- ) {
- throw new Error("Queue is full");
- } else if (this.frontIndex == -1) {
- this.frontIndex = 0;
- this.rearIndex = 0;
- this.queue[this.rearIndex] = item;
- } else if (this.rearIndex == this.size - 1 && this.frontIndex != 0) {
- this.rearIndex = 0;
- this.queue[this.rearIndex] = item;
- } else {
- this.rearIndex++;
- this.queue[this.rearIndex] = item;
- }
+ /**
+ * Adds an item to the queue.
+ *
+ * @param item The item being added to the queue.
+ */
+ enqueue(item: T): void {
+ if (
+ (this.frontIndex == 0 && this.rearIndex == this.size - 1) ||
+ this.rearIndex == (this.frontIndex - 1) % (this.size - 1)
+ ) {
+ throw new Error('Queue is full')
+ } else if (this.frontIndex == -1) {
+ this.frontIndex = 0
+ this.rearIndex = 0
+ this.queue[this.rearIndex] = item
+ } else if (this.rearIndex == this.size - 1 && this.frontIndex != 0) {
+ this.rearIndex = 0
+ this.queue[this.rearIndex] = item
+ } else {
+ this.rearIndex++
+ this.queue[this.rearIndex] = item
}
+ }
- /**
- * Removes an item from the queue and returns it.
- *
- * @throws Queue Underflow if the queue is empty.
- * @returns The item that was removed from the queue.
- */
- dequeue(): T | undefined {
- if (this.frontIndex == -1) {
- throw new Error("Queue is empty");
- }
-
- const item = this.queue[this.frontIndex];
- if (this.frontIndex == this.rearIndex) {
- this.frontIndex = -1;
- this.rearIndex = -1;
- } else if (this.frontIndex == this.size - 1) {
- this.frontIndex = 0;
- } else {
- this.frontIndex++;
- }
+ /**
+ * Removes an item from the queue and returns it.
+ *
+ * @throws Queue Underflow if the queue is empty.
+ * @returns The item that was removed from the queue.
+ */
+ dequeue(): T | undefined {
+ if (this.frontIndex == -1) {
+ throw new Error('Queue is empty')
+ }
- return item;
+ const item = this.queue[this.frontIndex]
+ if (this.frontIndex == this.rearIndex) {
+ this.frontIndex = -1
+ this.rearIndex = -1
+ } else if (this.frontIndex == this.size - 1) {
+ this.frontIndex = 0
+ } else {
+ this.frontIndex++
}
- /**
- * Returns the item at the front of the queue.
- *
- * @returns The item at the front of the queue or null if the queue is empty.
- */
- peek(): T | null | undefined {
- if (this.frontIndex == -1) {
- return null;
- }
+ return item
+ }
- return this.queue[this.frontIndex];
+ /**
+ * Returns the item at the front of the queue.
+ *
+ * @returns The item at the front of the queue or null if the queue is empty.
+ */
+ peek(): T | null | undefined {
+ if (this.frontIndex == -1) {
+ return null
}
- /**
- * Checks if the queue is empty.
- *
- * @returns {boolean} Whether the queue is empty or not.
- */
- isEmpty(): boolean {
- return this.frontIndex == -1;
- }
+ return this.queue[this.frontIndex]
+ }
- /**
- * Returns the number of items in the queue.
- *
- * @returns {number} The number of items in the queue.
- */
- length(): number {
- if (this.frontIndex == -1) {
- return 0;
- }
+ /**
+ * Checks if the queue is empty.
+ *
+ * @returns {boolean} Whether the queue is empty or not.
+ */
+ isEmpty(): boolean {
+ return this.frontIndex == -1
+ }
- if (this.rearIndex >= this.frontIndex) {
- return this.rearIndex - this.frontIndex + 1;
- }
+ /**
+ * Returns the number of items in the queue.
+ *
+ * @returns {number} The number of items in the queue.
+ */
+ length(): number {
+ if (this.frontIndex == -1) {
+ return 0
+ }
- return this.size - (this.frontIndex - this.rearIndex - 1);
+ if (this.rearIndex >= this.frontIndex) {
+ return this.rearIndex - this.frontIndex + 1
}
+
+ return this.size - (this.frontIndex - this.rearIndex - 1)
+ }
}
diff --git a/data_structures/queue/linked_queue.ts b/data_structures/queue/linked_queue.ts
index bc90bd52..280447cc 100644
--- a/data_structures/queue/linked_queue.ts
+++ b/data_structures/queue/linked_queue.ts
@@ -1,8 +1,8 @@
-import { Queue } from "./queue";
+import { Queue } from './queue'
type Node = {
- value: T,
- next?: Node,
+ value: T
+ next?: Node
}
/**
@@ -12,84 +12,76 @@ type Node = {
* The first element that was added to the queue will be the first one to be removed.
*/
export class LinkedQueue implements Queue {
-
- public size: number;
- public head?: Node;
- private tail?: Node;
-
- constructor() {
- this.head = this.tail = undefined;
- this.size = 0;
- }
-
- /**
- * Adds an item to the queue.
- *
- * @param item The item being added to the queue.
- */
- enqueue(item: T): void {
- const node = { value: item } as Node; // Creates a new node
- this.size++ // Increase the length of the Queue
-
-
- if (!this.tail) {
- this.tail = this.head = node;
- return;
- }
- this.tail.next = node; // Updates the next tail to the node created
- this.tail = node; // The tail of the Queue then becomes the node created!!
-
- }
-
-
- /**
- * Removes an item from the queue and returns it.
- *
- * @throws Queue Underflow if the queue is empty.
- * @returns The item that was removed from the queue.
- */
- dequeue(): T | undefined {
-
- if (!this.head) {
- throw new Error("Queue Underflow");
- }
-
- this.size--;
- const head = this.head; // We store the head in order not to lose track of it
- this.head = this.head.next; // Update the the head to the next node
- return head.value; // Return the value of the head
+ public size: number
+ public head?: Node
+ private tail?: Node
+
+ constructor() {
+ this.head = this.tail = undefined
+ this.size = 0
+ }
+
+ /**
+ * Adds an item to the queue.
+ *
+ * @param item The item being added to the queue.
+ */
+ enqueue(item: T): void {
+ const node = { value: item } as Node // Creates a new node
+ this.size++ // Increase the length of the Queue
+
+ if (!this.tail) {
+ this.tail = this.head = node
+ return
}
-
-
- /**
- * Returns the item at the front of the queue.
- *
- * @returns The item at the front of the queue or null if the queue is empty.
- */
- peek(): T | undefined | null {
-
- if (this.isEmpty()) {
- return null;
- }
- return this.head?.value;
- }
-
- /**
- * Checks if the queue is empty.
- *
- * @returns {boolean} Whether the queue is empty or not.
- */
- isEmpty(): boolean {
- return this.size === 0
+ this.tail.next = node // Updates the next tail to the node created
+ this.tail = node // The tail of the Queue then becomes the node created!!
+ }
+
+ /**
+ * Removes an item from the queue and returns it.
+ *
+ * @throws Queue Underflow if the queue is empty.
+ * @returns The item that was removed from the queue.
+ */
+ dequeue(): T | undefined {
+ if (!this.head) {
+ throw new Error('Queue Underflow')
}
- /**
- * Returns the number of items in the queue.
- *
- * @returns {number} The number of items in the queue.
- */
- length(): number {
- return this.size;
+ this.size--
+ const head = this.head // We store the head in order not to lose track of it
+ this.head = this.head.next // Update the the head to the next node
+ return head.value // Return the value of the head
+ }
+
+ /**
+ * Returns the item at the front of the queue.
+ *
+ * @returns The item at the front of the queue or null if the queue is empty.
+ */
+ peek(): T | undefined | null {
+ if (this.isEmpty()) {
+ return null
}
+ return this.head?.value
+ }
+
+ /**
+ * Checks if the queue is empty.
+ *
+ * @returns {boolean} Whether the queue is empty or not.
+ */
+ isEmpty(): boolean {
+ return this.size === 0
+ }
+
+ /**
+ * Returns the number of items in the queue.
+ *
+ * @returns {number} The number of items in the queue.
+ */
+ length(): number {
+ return this.size
+ }
}
-
diff --git a/data_structures/queue/queue.ts b/data_structures/queue/queue.ts
index 81b3c61f..08763dc1 100644
--- a/data_structures/queue/queue.ts
+++ b/data_structures/queue/queue.ts
@@ -1,7 +1,7 @@
export interface Queue {
- enqueue(item: T): void
- dequeue(): T | undefined
- peek(): T | undefined | null
- isEmpty(): boolean
- length(): number
-}
\ No newline at end of file
+ enqueue(item: T): void
+ dequeue(): T | undefined
+ peek(): T | undefined | null
+ isEmpty(): boolean
+ length(): number
+}
diff --git a/data_structures/queue/stack_queue.ts b/data_structures/queue/stack_queue.ts
index e6f129d0..d20f1028 100644
--- a/data_structures/queue/stack_queue.ts
+++ b/data_structures/queue/stack_queue.ts
@@ -7,85 +7,85 @@
* The other stack acts as a dequeue stack which helps in dequeuing the elements
*/
-import { Stack } from "../stack/stack";
-import { Queue } from "./queue";
+import { Stack } from '../stack/stack'
+import { Queue } from './queue'
export class StackQueue implements Queue {
- private enqueueStack: Stack = new Stack();
- private dequeueStack: Stack = new Stack();
+ private enqueueStack: Stack = new Stack()
+ private dequeueStack: Stack = new Stack()
- /**
- * Returns the length of the Queue
- *
- * @returns {number} the length of the Queue
- */
- length(): number {
- return this.enqueueStack.length() + this.dequeueStack.length();
- }
+ /**
+ * Returns the length of the Queue
+ *
+ * @returns {number} the length of the Queue
+ */
+ length(): number {
+ return this.enqueueStack.length() + this.dequeueStack.length()
+ }
- /**
- * Checks if the queue is empty.
- *
- * @returns {boolean} Whether the queue is empty or not.
- */
- isEmpty(): boolean {
- return this.enqueueStack.isEmpty() && this.dequeueStack.isEmpty();
- }
+ /**
+ * Checks if the queue is empty.
+ *
+ * @returns {boolean} Whether the queue is empty or not.
+ */
+ isEmpty(): boolean {
+ return this.enqueueStack.isEmpty() && this.dequeueStack.isEmpty()
+ }
- /**
- * Adds an item to the queue.
- * We always add a new item to the enqueueStack.
- * @param item The item being added to the queue.
- */
- enqueue(item: T): void {
- this.enqueueStack.push(item);
- }
+ /**
+ * Adds an item to the queue.
+ * We always add a new item to the enqueueStack.
+ * @param item The item being added to the queue.
+ */
+ enqueue(item: T): void {
+ this.enqueueStack.push(item)
+ }
- /**
- * Shifts the elements from the enqueueStack to the dequeueStack
- * In the worst case, all the elements from the enqueue stack needs to shifted, which needs O(n) time.
- * However, after the shift, elements can de dequeued at O(1).
- * This helps in dequeuing the elements in amortized O(1) time.
- */
- private shift(): void {
- while (!this.enqueueStack.isEmpty()) {
- const enqueueStackTop = this.enqueueStack.pop();
- this.dequeueStack.push(enqueueStackTop);
- }
+ /**
+ * Shifts the elements from the enqueueStack to the dequeueStack
+ * In the worst case, all the elements from the enqueue stack needs to shifted, which needs O(n) time.
+ * However, after the shift, elements can de dequeued at O(1).
+ * This helps in dequeuing the elements in amortized O(1) time.
+ */
+ private shift(): void {
+ while (!this.enqueueStack.isEmpty()) {
+ const enqueueStackTop = this.enqueueStack.pop()
+ this.dequeueStack.push(enqueueStackTop)
}
+ }
- /**
- * Removes an item from the queue and returns it.
- *
- * @throws Queue Underflow if the queue is empty.
- * @returns The item that was removed from the queue.
- */
- dequeue(): T {
- if (this.isEmpty()) {
- throw new Error("Queue Underflow");
- }
-
- if (this.dequeueStack.isEmpty()) {
- this.shift();
- }
+ /**
+ * Removes an item from the queue and returns it.
+ *
+ * @throws Queue Underflow if the queue is empty.
+ * @returns The item that was removed from the queue.
+ */
+ dequeue(): T {
+ if (this.isEmpty()) {
+ throw new Error('Queue Underflow')
+ }
- return this.dequeueStack.pop();
+ if (this.dequeueStack.isEmpty()) {
+ this.shift()
}
- /**
- * Returns the item at the front of the queue.
- *
- * @returns The item at the front of the queue or null if the queue is empty.
- */
- peek(): T | null {
- if (this.isEmpty()) {
- return null;
- }
+ return this.dequeueStack.pop()
+ }
- if (this.dequeueStack.isEmpty()) {
- this.shift();
- }
+ /**
+ * Returns the item at the front of the queue.
+ *
+ * @returns The item at the front of the queue or null if the queue is empty.
+ */
+ peek(): T | null {
+ if (this.isEmpty()) {
+ return null
+ }
- return this.dequeueStack.top();
+ if (this.dequeueStack.isEmpty()) {
+ this.shift()
}
+
+ return this.dequeueStack.top()
+ }
}
diff --git a/data_structures/queue/test/array_queue.test.ts b/data_structures/queue/test/array_queue.test.ts
index 9bc6f48f..f080b545 100644
--- a/data_structures/queue/test/array_queue.test.ts
+++ b/data_structures/queue/test/array_queue.test.ts
@@ -1,4 +1,4 @@
-import { ArrayQueue } from "../array_queue";
+import { ArrayQueue } from '../array_queue'
import { testQueue } from './queue'
-describe("Array Queue", () => testQueue(ArrayQueue));
+describe('Array Queue', () => testQueue(ArrayQueue))
diff --git a/data_structures/queue/test/circular_queue.test.ts b/data_structures/queue/test/circular_queue.test.ts
index 042e5d81..059216fe 100644
--- a/data_structures/queue/test/circular_queue.test.ts
+++ b/data_structures/queue/test/circular_queue.test.ts
@@ -1,65 +1,65 @@
-import { CircularQueue } from "../circular_queue";
+import { CircularQueue } from '../circular_queue'
-describe("Circular Queue", () => {
- let queue: CircularQueue;
+describe('Circular Queue', () => {
+ let queue: CircularQueue
- beforeEach(() => {
- queue = new CircularQueue(5);
- });
+ beforeEach(() => {
+ queue = new CircularQueue(5)
+ })
- it("should enqueue an element", () => {
- queue.enqueue(1);
+ it('should enqueue an element', () => {
+ queue.enqueue(1)
- expect(queue.peek()).toBe(1);
- });
+ expect(queue.peek()).toBe(1)
+ })
- it("should throw an error on enqueue when queue is full", () => {
- queue.enqueue(1);
- queue.enqueue(2);
- queue.enqueue(3);
- queue.enqueue(4);
- queue.enqueue(5);
+ it('should throw an error on enqueue when queue is full', () => {
+ queue.enqueue(1)
+ queue.enqueue(2)
+ queue.enqueue(3)
+ queue.enqueue(4)
+ queue.enqueue(5)
- expect(() => queue.enqueue(6)).toThrowError("Queue is full");
- });
+ expect(() => queue.enqueue(6)).toThrowError('Queue is full')
+ })
- it("should dequeue an element", () => {
- queue.enqueue(1);
- queue.enqueue(2);
+ it('should dequeue an element', () => {
+ queue.enqueue(1)
+ queue.enqueue(2)
- expect(queue.dequeue()).toBe(1);
- });
+ expect(queue.dequeue()).toBe(1)
+ })
- it("should throw an error on dequeue when queue is empty", () => {
- expect(() => queue.dequeue()).toThrowError("Queue is empty");
- });
+ it('should throw an error on dequeue when queue is empty', () => {
+ expect(() => queue.dequeue()).toThrowError('Queue is empty')
+ })
- it("should peek an element", () => {
- queue.enqueue(1);
- queue.enqueue(2);
+ it('should peek an element', () => {
+ queue.enqueue(1)
+ queue.enqueue(2)
- expect(queue.peek()).toBe(1);
- });
+ expect(queue.peek()).toBe(1)
+ })
- it("should return null on peek when queue is empty", () => {
- expect(queue.peek()).toBeNull();
- });
+ it('should return null on peek when queue is empty', () => {
+ expect(queue.peek()).toBeNull()
+ })
- it("should return true on isEmpty when queue is empty", () => {
- expect(queue.isEmpty()).toBeTruthy();
- });
+ it('should return true on isEmpty when queue is empty', () => {
+ expect(queue.isEmpty()).toBeTruthy()
+ })
- it("should return false on isEmpty when queue is not empty", () => {
- queue.enqueue(1);
+ it('should return false on isEmpty when queue is not empty', () => {
+ queue.enqueue(1)
- expect(queue.isEmpty()).toBeFalsy();
- });
+ expect(queue.isEmpty()).toBeFalsy()
+ })
- it("should return the correct length", () => {
- queue.enqueue(1);
- queue.enqueue(2);
- queue.enqueue(3);
+ it('should return the correct length', () => {
+ queue.enqueue(1)
+ queue.enqueue(2)
+ queue.enqueue(3)
- expect(queue.length()).toBe(3);
- });
-});
+ expect(queue.length()).toBe(3)
+ })
+})
diff --git a/data_structures/queue/test/linked_queue.test.ts b/data_structures/queue/test/linked_queue.test.ts
index 408c1aa7..79b94169 100644
--- a/data_structures/queue/test/linked_queue.test.ts
+++ b/data_structures/queue/test/linked_queue.test.ts
@@ -1,4 +1,4 @@
import { testQueue } from './queue'
-import { LinkedQueue } from '../linked_queue';
+import { LinkedQueue } from '../linked_queue'
-describe("Linked Queue", () => testQueue(LinkedQueue));
+describe('Linked Queue', () => testQueue(LinkedQueue))
diff --git a/data_structures/queue/test/queue.ts b/data_structures/queue/test/queue.ts
index 5fb57564..26535712 100644
--- a/data_structures/queue/test/queue.ts
+++ b/data_structures/queue/test/queue.ts
@@ -1,54 +1,54 @@
-import { Queue } from '../queue';
+import { Queue } from '../queue'
type QueueConstructor = new () => Queue
export function testQueue(Queue: QueueConstructor) {
- it("enqueue should add a new element to the queue", () => {
- const queue = new Queue();
- queue.enqueue(1);
- expect(queue.length()).toBe(1);
- });
-
- it("isEmpty should return true on empty queue", () => {
- const queue = new Queue();
- expect(queue.isEmpty()).toBeTruthy();
- });
-
- it("isEmpty should return false on not empty queue", () => {
- const queue = new Queue();
- queue.enqueue(1);
- expect(queue.isEmpty()).toBeFalsy();
- });
-
- it("front should return the first value", () => {
- const queue = new Queue();
- queue.enqueue(1);
- expect(queue.peek()).toBe(1);
- });
-
- it("front should return null when the queue is empty", () => {
- const queue = new Queue();
- expect(queue.peek()).toBe(null);
- });
-
- it("length should return the number of elements in the queue", () => {
- const queue = new Queue();
- queue.enqueue(1);
- queue.enqueue(1);
- queue.enqueue(1);
- expect(queue.length()).toBe(3);
- });
-
- it("dequeue should remove the first element", () => {
- const queue = new Queue();
- queue.enqueue(1);
- queue.enqueue(2);
- queue.enqueue(3);
- queue.dequeue();
- expect(queue.length()).toBe(2);
- });
-
- it("dequeue should throw error on empty queue", () => {
- const queue = new Queue();
- expect(() => queue.dequeue()).toThrow("Queue Underflow");
- });
+ it('enqueue should add a new element to the queue', () => {
+ const queue = new Queue()
+ queue.enqueue(1)
+ expect(queue.length()).toBe(1)
+ })
+
+ it('isEmpty should return true on empty queue', () => {
+ const queue = new Queue()
+ expect(queue.isEmpty()).toBeTruthy()
+ })
+
+ it('isEmpty should return false on not empty queue', () => {
+ const queue = new Queue()
+ queue.enqueue(1)
+ expect(queue.isEmpty()).toBeFalsy()
+ })
+
+ it('front should return the first value', () => {
+ const queue = new Queue()
+ queue.enqueue(1)
+ expect(queue.peek()).toBe(1)
+ })
+
+ it('front should return null when the queue is empty', () => {
+ const queue = new Queue()
+ expect(queue.peek()).toBe(null)
+ })
+
+ it('length should return the number of elements in the queue', () => {
+ const queue = new Queue()
+ queue.enqueue(1)
+ queue.enqueue(1)
+ queue.enqueue(1)
+ expect(queue.length()).toBe(3)
+ })
+
+ it('dequeue should remove the first element', () => {
+ const queue = new Queue()
+ queue.enqueue(1)
+ queue.enqueue(2)
+ queue.enqueue(3)
+ queue.dequeue()
+ expect(queue.length()).toBe(2)
+ })
+
+ it('dequeue should throw error on empty queue', () => {
+ const queue = new Queue()
+ expect(() => queue.dequeue()).toThrow('Queue Underflow')
+ })
}
diff --git a/data_structures/queue/test/stack_queue.test.ts b/data_structures/queue/test/stack_queue.test.ts
index ab8240bf..538e0503 100644
--- a/data_structures/queue/test/stack_queue.test.ts
+++ b/data_structures/queue/test/stack_queue.test.ts
@@ -1,4 +1,4 @@
-import { testQueue } from './queue';
-import { StackQueue } from '../stack_queue';
+import { testQueue } from './queue'
+import { StackQueue } from '../stack_queue'
-describe("Stack Based Queue", () => testQueue(StackQueue));
\ No newline at end of file
+describe('Stack Based Queue', () => testQueue(StackQueue))
diff --git a/data_structures/set/hash_map_set.ts b/data_structures/set/hash_map_set.ts
index ade41cbb..ddb86543 100644
--- a/data_structures/set/hash_map_set.ts
+++ b/data_structures/set/hash_map_set.ts
@@ -1,6 +1,6 @@
-import { Map } from "../map/map";
-import { HashMap } from "../map/hash_map";
-import { MapSet } from "./map_set";
+import { Map } from '../map/map'
+import { HashMap } from '../map/hash_map'
+import { MapSet } from './map_set'
/**
* This class is a representation of the Set data structure based on a hash map.
@@ -9,16 +9,16 @@ import { MapSet } from "./map_set";
* @extends MapSet
*/
export class HashMapSet extends MapSet {
- constructor() {
- super();
- }
+ constructor() {
+ super()
+ }
- /**
- * Initializes the map used to store the set.
- *
- * @returns {Map} The map used to store the set.
- */
- protected initMap(): Map {
- return new HashMap();
- }
+ /**
+ * Initializes the map used to store the set.
+ *
+ * @returns {Map} The map used to store the set.
+ */
+ protected initMap(): Map {
+ return new HashMap()
+ }
}
diff --git a/data_structures/set/map_set.ts b/data_structures/set/map_set.ts
index 11e8c2f2..ce4f8ebc 100644
--- a/data_structures/set/map_set.ts
+++ b/data_structures/set/map_set.ts
@@ -1,5 +1,5 @@
-import { Map } from "./map";
-import { Set } from "./set";
+import { Map } from './map'
+import { Set } from './set'
/**
* This class is a representation of the Set data structure based on a hash map.
@@ -9,67 +9,67 @@ import { Set } from "./set";
* @property {Map} map The map used to store the set.
*/
export abstract class MapSet implements Set {
- private map: Map;
+ private map: Map
- constructor() {
- this.map = this.initMap();
- }
+ constructor() {
+ this.map = this.initMap()
+ }
- /**
- * Initializes the map used to store the set.
- */
- protected abstract initMap(): Map;
+ /**
+ * Initializes the map used to store the set.
+ */
+ protected abstract initMap(): Map
- /**
- * Adds a new element to the set.
- *
- * @param value The value to add to the set.
- */
- add(value: K): void {
- this.map.set(value, null);
- }
+ /**
+ * Adds a new element to the set.
+ *
+ * @param value The value to add to the set.
+ */
+ add(value: K): void {
+ this.map.set(value, null)
+ }
- /**
- * Removes an element from the set.
- *
- * @param value The value to remove from the set.
- */
- delete(value: K): void {
- this.map.delete(value);
- }
+ /**
+ * Removes an element from the set.
+ *
+ * @param value The value to remove from the set.
+ */
+ delete(value: K): void {
+ this.map.delete(value)
+ }
- /**
- * Checks if the set contains a given value.
- *
- * @param value The value to check for.
- * @returns Whether the set contains the value.
- */
- has(value: K): boolean {
- return this.map.has(value);
- }
+ /**
+ * Checks if the set contains a given value.
+ *
+ * @param value The value to check for.
+ * @returns Whether the set contains the value.
+ */
+ has(value: K): boolean {
+ return this.map.has(value)
+ }
- /**
- * Removes all elements from the set.
- */
- clear(): void {
- this.map.clear();
- }
+ /**
+ * Removes all elements from the set.
+ */
+ clear(): void {
+ this.map.clear()
+ }
- /**
- * Returns an array of all the values in the set.
- *
- * @returns An array of all the values in the set.
- */
- values(): K[] {
- return this.map.keys();
- }
+ /**
+ * Returns an array of all the values in the set.
+ *
+ * @returns An array of all the values in the set.
+ */
+ values(): K[] {
+ return this.map.keys()
+ }
- /**
- * Returns the number of elements in the set.
- *
- * @returns The number of elements in the set.
- */
- getSize(): number {
- return this.map.getSize();
- }
+ /**
+ * Returns the number of elements in the set.
+ *
+ * @returns The number of elements in the set.
+ */
+ getSize(): number {
+ return this.map.getSize()
+ }
}
diff --git a/data_structures/set/set.ts b/data_structures/set/set.ts
index 3d814d41..2b3c1d83 100644
--- a/data_structures/set/set.ts
+++ b/data_structures/set/set.ts
@@ -2,10 +2,10 @@
* This interface is a representation of the Set data structure.
*/
export interface Set {
- getSize(): number;
- add(value: K): void;
- delete(value: K): void;
- has(value: K): boolean;
- clear(): void;
- values(): K[];
+ getSize(): number
+ add(value: K): void
+ delete(value: K): void
+ has(value: K): boolean
+ clear(): void
+ values(): K[]
}
diff --git a/data_structures/stack/linked_list_stack.ts b/data_structures/stack/linked_list_stack.ts
index 11b1dbd9..8c07b4ce 100644
--- a/data_structures/stack/linked_list_stack.ts
+++ b/data_structures/stack/linked_list_stack.ts
@@ -1,4 +1,4 @@
-import { SinglyLinkedList } from "../list/singly_linked_list";
+import { SinglyLinkedList } from '../list/singly_linked_list'
/**
* This is an implementation of a stack, based on a linked list.
@@ -7,76 +7,76 @@ import { SinglyLinkedList } from "../list/singly_linked_list";
* to determine which element is next in the list.
*/
export class LinkedListStack {
- private list: SinglyLinkedList;
- private limit: number;
+ private list: SinglyLinkedList
+ private limit: number
- /**
- * Creates a new stack object.
- */
- constructor(limit: number = Number.MAX_VALUE) {
- this.list = new SinglyLinkedList();
- this.limit = limit;
- }
-
- /**
- * Gets the top element of the stack.
- * Time complexity: constant (O(1))
- *
- * @returns The top element of the stack.
- */
- top(): T | null {
- if (this.list.isEmpty()) {
- return null;
- }
+ /**
+ * Creates a new stack object.
+ */
+ constructor(limit: number = Number.MAX_VALUE) {
+ this.list = new SinglyLinkedList()
+ this.limit = limit
+ }
- return this.list.get(0)!;
+ /**
+ * Gets the top element of the stack.
+ * Time complexity: constant (O(1))
+ *
+ * @returns The top element of the stack.
+ */
+ top(): T | null {
+ if (this.list.isEmpty()) {
+ return null
}
- /**
- * Inserts a new element on the top of the stack.
- * Time complexity: constant (O(1))
- *
- * @param data The data of the element to insert.
- * @throws Stack overflow, if the new element does not fit in the limit.
- */
- push(data: T): void {
- if (this.list.getLength() + 1 > this.limit) {
- throw new Error('Stack overflow')
- }
+ return this.list.get(0)!
+ }
- this.list.push(data);
+ /**
+ * Inserts a new element on the top of the stack.
+ * Time complexity: constant (O(1))
+ *
+ * @param data The data of the element to insert.
+ * @throws Stack overflow, if the new element does not fit in the limit.
+ */
+ push(data: T): void {
+ if (this.list.getLength() + 1 > this.limit) {
+ throw new Error('Stack overflow')
}
- /**
- * Removes the top element from the stack.
- * Time complexity: constant (O(1))
- *
- * @returns The previous top element.
- * @throws Stack underflow, if the stack has no elements to pop.
- */
- pop(): T {
- if (this.list.isEmpty()) {
- throw new Error('Stack underflow')
- }
+ this.list.push(data)
+ }
- return this.list.pop();
+ /**
+ * Removes the top element from the stack.
+ * Time complexity: constant (O(1))
+ *
+ * @returns The previous top element.
+ * @throws Stack underflow, if the stack has no elements to pop.
+ */
+ pop(): T {
+ if (this.list.isEmpty()) {
+ throw new Error('Stack underflow')
}
- /**
- * Gets the amount of elements in the stack.
- *
- * @returns The amount of elements in the stack.
- */
- length(): number {
- return this.list.getLength();
- }
+ return this.list.pop()
+ }
- /**
- * Gets whether the stack is empty or not.
- *
- * @returns Whether the stack is empty or not.
- */
- isEmpty(): boolean {
- return this.list.isEmpty();
- }
-}
\ No newline at end of file
+ /**
+ * Gets the amount of elements in the stack.
+ *
+ * @returns The amount of elements in the stack.
+ */
+ length(): number {
+ return this.list.getLength()
+ }
+
+ /**
+ * Gets whether the stack is empty or not.
+ *
+ * @returns Whether the stack is empty or not.
+ */
+ isEmpty(): boolean {
+ return this.list.isEmpty()
+ }
+}
diff --git a/data_structures/stack/stack.ts b/data_structures/stack/stack.ts
index 60affe13..3a660bca 100644
--- a/data_structures/stack/stack.ts
+++ b/data_structures/stack/stack.ts
@@ -5,15 +5,15 @@
* This is a class-based implementation of a Stack.
*/
export class Stack {
- private stack: T[] = [];
- private limit: number;
+ private stack: T[] = []
+ private limit: number
/**
* constructor of the stack, can set a limit, if not provided there is no limit to the stack.
* @param {number} [limit=Number.MAX_VALUE] the limit of the stack
*/
constructor(limit: number = Number.MAX_VALUE) {
- this.limit = limit;
+ this.limit = limit
}
/**
@@ -23,10 +23,10 @@ export class Stack {
*/
push(value: T) {
if (this.length() + 1 > this.limit) {
- throw new Error('Stack Overflow');
+ throw new Error('Stack Overflow')
}
- this.stack.push(value);
+ this.stack.push(value)
}
/**
@@ -37,10 +37,10 @@ export class Stack {
*/
pop(): T {
if (this.length() !== 0) {
- return this.stack.pop() as T;
+ return this.stack.pop() as T
}
- throw new Error('Stack Underflow');
+ throw new Error('Stack Underflow')
}
/**
@@ -49,7 +49,7 @@ export class Stack {
* @return {number} the number of elements in the stack
*/
length(): number {
- return this.stack.length;
+ return this.stack.length
}
/**
@@ -58,7 +58,7 @@ export class Stack {
* @return {boolean} returns true if the stack is empty, otherwise false
*/
isEmpty(): boolean {
- return this.length() === 0;
+ return this.length() === 0
}
/**
@@ -68,9 +68,9 @@ export class Stack {
*/
top(): T | null {
if (this.length() !== 0) {
- return this.stack[this.length() - 1];
+ return this.stack[this.length() - 1]
}
- return null;
+ return null
}
}
diff --git a/data_structures/stack/test/linked_list_stack.test.ts b/data_structures/stack/test/linked_list_stack.test.ts
index 54f47c48..0595c063 100644
--- a/data_structures/stack/test/linked_list_stack.test.ts
+++ b/data_structures/stack/test/linked_list_stack.test.ts
@@ -1,32 +1,32 @@
-import { LinkedListStack } from "../linked_list_stack";
+import { LinkedListStack } from '../linked_list_stack'
-describe("Linked List Stack", () => {
- const stack: LinkedListStack = new LinkedListStack(4);
+describe('Linked List Stack', () => {
+ const stack: LinkedListStack = new LinkedListStack