From a62a46e732798622b520769c9c1131a052721ca2 Mon Sep 17 00:00:00 2001
From: Shankha Suvra Dam <71999854+SpiderMath@users.noreply.github.com>
Date: Sun, 12 Jan 2025 15:57:54 +0530
Subject: [PATCH 1/2] Resolve duplicate entries for sieve of eratosthenes 
 (#1770)

* remove intarr test

* Remove main file oops

* FIXES: #1666 , remove references to SieveOfEratosthenesIntArray

* Finally fix the requirements, passes vitest

* Updated Documentation in README.md

* FIXES: #1666 and conform to alg comment standards

---------

Co-authored-by: SpiderMath <SpiderMath@users.noreply.github.com>
---
 DIRECTORY.md                                  |  1 -
 Maths/SieveOfEratosthenes.js                  | 43 ++++++++++---------
 Maths/SieveOfEratosthenesIntArray.js          | 24 -----------
 Maths/test/SieveOfEratosthenes.test.js        | 37 +++++++++++-----
 .../test/SieveOfEratosthenesIntArray.test.js  | 12 ------
 Project-Euler/Problem035.js                   |  2 +-
 6 files changed, 49 insertions(+), 70 deletions(-)
 delete mode 100644 Maths/SieveOfEratosthenesIntArray.js
 delete mode 100644 Maths/test/SieveOfEratosthenesIntArray.test.js

diff --git a/DIRECTORY.md b/DIRECTORY.md
index 7f6484cae5..5e8e1f401a 100644
--- a/DIRECTORY.md
+++ b/DIRECTORY.md
@@ -254,7 +254,6 @@
   * [RowEchelon](Maths/RowEchelon.js)
   * [ShorsAlgorithm](Maths/ShorsAlgorithm.js)
   * [SieveOfEratosthenes](Maths/SieveOfEratosthenes.js)
-  * [SieveOfEratosthenesIntArray](Maths/SieveOfEratosthenesIntArray.js)
   * [Signum](Maths/Signum.js)
   * [SimpsonIntegration](Maths/SimpsonIntegration.js)
   * [Softmax](Maths/Softmax.js)
diff --git a/Maths/SieveOfEratosthenes.js b/Maths/SieveOfEratosthenes.js
index 01e141f2f0..681d8ba904 100644
--- a/Maths/SieveOfEratosthenes.js
+++ b/Maths/SieveOfEratosthenes.js
@@ -1,25 +1,26 @@
-const sieveOfEratosthenes = (n) => {
-  /*
-   * Calculates prime numbers till a number n
-   * :param n: Number up to which to calculate primes
-   * :return: A boolean list containing only primes
-   */
-  const primes = new Array(n + 1)
-  primes.fill(true) // set all as true initially
-  primes[0] = primes[1] = false // Handling case for 0 and 1
-  const sqrtn = Math.ceil(Math.sqrt(n))
-  for (let i = 2; i <= sqrtn; i++) {
-    if (primes[i]) {
-      for (let j = i * i; j <= n; j += i) {
-        /*
-        Optimization.
-        Let j start from i * i, not 2 * i, because smaller multiples of i have been marked false.
+/**
+ * @function sieveOfEratosthenes
+ * @description Function to get all the prime numbers below a given number using sieve of eratosthenes algorithm
+ * @param {Number} max The limit below which all the primes are required to be
+ * @returns {Number[]} An array of all the prime numbers below max
+ * @see [Sieve of Eratosthenes](https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes)
+ * @example
+ * sieveOfEratosthenes(1) // ====> []
+ * @example
+ * sieveOfEratosthenes(20) // ====> [2, 3, 5, 7, 11, 13, 17, 19]
+ *
+ */
+function sieveOfEratosthenes(max) {
+  const sieve = []
+  const primes = []
 
-        For example, let i = 4.
-        We do not have to check from 8(4 * 2) to 12(4 * 3)
-        because they have been already marked false when i=2 and i=3.
-        */
-        primes[j] = false
+  for (let i = 2; i <= max; ++i) {
+    if (!sieve[i]) {
+      // If i has not been marked then it is prime
+      primes.push(i)
+      for (let j = i << 1; j <= max; j += i) {
+        // Mark all multiples of i as non-prime
+        sieve[j] = true
       }
     }
   }
diff --git a/Maths/SieveOfEratosthenesIntArray.js b/Maths/SieveOfEratosthenesIntArray.js
deleted file mode 100644
index 56336ce7d8..0000000000
--- a/Maths/SieveOfEratosthenesIntArray.js
+++ /dev/null
@@ -1,24 +0,0 @@
-/**
- * Function to get all prime numbers below a given number
- * This function returns an array of prime numbers
- * @see {@link https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes}
- */
-
-function sieveOfEratosthenes(max) {
-  const sieve = []
-  const primes = []
-
-  for (let i = 2; i <= max; ++i) {
-    if (!sieve[i]) {
-      // If i has not been marked then it is prime
-      primes.push(i)
-      for (let j = i << 1; j <= max; j += i) {
-        // Mark all multiples of i as non-prime
-        sieve[j] = true
-      }
-    }
-  }
-  return primes
-}
-
-export { sieveOfEratosthenes }
diff --git a/Maths/test/SieveOfEratosthenes.test.js b/Maths/test/SieveOfEratosthenes.test.js
index 056693d39b..1a10b8bc7f 100644
--- a/Maths/test/SieveOfEratosthenes.test.js
+++ b/Maths/test/SieveOfEratosthenes.test.js
@@ -1,14 +1,29 @@
 import { sieveOfEratosthenes } from '../SieveOfEratosthenes'
-import { PrimeCheck } from '../PrimeCheck'
-
-describe('should return an array of prime booleans', () => {
-  it('should have each element in the array as a prime boolean', () => {
-    const n = 30
-    const primes = sieveOfEratosthenes(n)
-    primes.forEach((primeBool, index) => {
-      if (primeBool) {
-        expect(PrimeCheck(index)).toBeTruthy()
-      }
-    })
+
+describe('sieveOfEratosthenes', () => {
+  test('returns an empty array for max < 2', () => {
+    expect(sieveOfEratosthenes(1)).toEqual([])
+  })
+
+  test('returns [2] for max = 2', () => {
+    expect(sieveOfEratosthenes(2)).toEqual([2])
+  })
+
+  test('returns [2, 3] for max = 3', () => {
+    expect(sieveOfEratosthenes(3)).toEqual([2, 3])
+  })
+
+  test('returns [2, 3, 5, 7] for max = 10', () => {
+    expect(sieveOfEratosthenes(10)).toEqual([2, 3, 5, 7])
+  })
+
+  test('returns [2, 3, 5, 7, 11, 13, 17, 19] for max = 20', () => {
+    expect(sieveOfEratosthenes(20)).toEqual([2, 3, 5, 7, 11, 13, 17, 19])
+  })
+
+  test('returns [2, 3, 5, 7, 11, 13, 17, 19, 23, 29] for max = 30', () => {
+    expect(sieveOfEratosthenes(30)).toEqual([
+      2, 3, 5, 7, 11, 13, 17, 19, 23, 29
+    ])
   })
 })
diff --git a/Maths/test/SieveOfEratosthenesIntArray.test.js b/Maths/test/SieveOfEratosthenesIntArray.test.js
deleted file mode 100644
index e3a3be3002..0000000000
--- a/Maths/test/SieveOfEratosthenesIntArray.test.js
+++ /dev/null
@@ -1,12 +0,0 @@
-import { sieveOfEratosthenes } from '../SieveOfEratosthenesIntArray'
-import { PrimeCheck } from '../PrimeCheck'
-
-describe('should return an array of prime numbers', () => {
-  it('should have each element in the array as a prime numbers', () => {
-    const n = 100
-    const primes = sieveOfEratosthenes(n)
-    primes.forEach((prime) => {
-      expect(PrimeCheck(prime)).toBeTruthy()
-    })
-  })
-})
diff --git a/Project-Euler/Problem035.js b/Project-Euler/Problem035.js
index c877acba5a..0b11cd0357 100644
--- a/Project-Euler/Problem035.js
+++ b/Project-Euler/Problem035.js
@@ -9,7 +9,7 @@
  *
  * @author ddaniel27
  */
-import { sieveOfEratosthenes } from '../Maths/SieveOfEratosthenesIntArray'
+import { sieveOfEratosthenes } from '../Maths/SieveOfEratosthenes'
 
 function problem35(n) {
   if (n < 2) {

From 1d252d7acae4ac46a3fc5d972c068cb95688c2f7 Mon Sep 17 00:00:00 2001
From: Ridge Kimani <101694484+ridge-kimani@users.noreply.github.com>
Date: Wed, 15 Jan 2025 14:11:02 +0300
Subject: [PATCH 2/2] feat: add tests for binary search trees (#1769)

---
 Data-Structures/Tree/BinarySearchTree.js      | 17 +++--
 .../Tree/test/BinarySearchTree.test.js        | 66 +++++++++++++++++++
 2 files changed, 76 insertions(+), 7 deletions(-)
 create mode 100644 Data-Structures/Tree/test/BinarySearchTree.test.js

diff --git a/Data-Structures/Tree/BinarySearchTree.js b/Data-Structures/Tree/BinarySearchTree.js
index abbcc3fb62..8a65c8e650 100644
--- a/Data-Structures/Tree/BinarySearchTree.js
+++ b/Data-Structures/Tree/BinarySearchTree.js
@@ -36,13 +36,13 @@ const Node = (function Node() {
     visit(output = (value) => console.log(value)) {
       // Recursively go left
       if (this.left !== null) {
-        this.left.visit()
+        this.left.visit(output)
       }
       // Print out value
       output(this.value)
       // Recursively go right
       if (this.right !== null) {
-        this.right.visit()
+        this.right.visit(output)
       }
     }
 
@@ -116,20 +116,23 @@ const Tree = (function () {
     }
 
     // Inorder traversal
-    traverse() {
+    traverse(output = (value) => console.log(value)) {
       if (!this.root) {
         // No nodes are there in the tree till now
         return
       }
-      this.root.visit()
+      this.root.visit(output)
     }
 
     // Start by searching the root
     search(val) {
-      const found = this.root.search(val)
-      if (found !== null) {
-        return found.value
+      if (this.root) {
+        const found = this.root.search(val)
+        if (found !== null) {
+          return found.value
+        }
       }
+
       // not found
       return null
     }
diff --git a/Data-Structures/Tree/test/BinarySearchTree.test.js b/Data-Structures/Tree/test/BinarySearchTree.test.js
new file mode 100644
index 0000000000..4c6c353592
--- /dev/null
+++ b/Data-Structures/Tree/test/BinarySearchTree.test.js
@@ -0,0 +1,66 @@
+import { Tree } from '../BinarySearchTree.js'
+
+describe('Binary Search Tree', () => {
+  let tree
+
+  beforeEach(() => {
+    tree = new Tree()
+    tree.addValue(10)
+    tree.addValue(5)
+    tree.addValue(15)
+    tree.addValue(3)
+    tree.addValue(8)
+  })
+
+  test('should add values to the tree', () => {
+    tree.addValue(12)
+
+    expect(tree.search(12)).toBe(12)
+    expect(tree.search(5)).toBe(5)
+    expect(tree.search(15)).toBe(15)
+  })
+
+  test('should perform in-order traversal', () => {
+    const values = []
+    const output = (val) => values.push(val)
+    tree.traverse(output)
+    expect(values).toEqual([3, 5, 8, 10, 15])
+  })
+
+  test('should remove leaf nodes correctly', () => {
+    tree.removeValue(5)
+    expect(tree.search(5)).toBeNull()
+  })
+
+  test('should remove nodes with one child correctly', () => {
+    tree.addValue(12)
+    tree.removeValue(15)
+
+    expect(tree.search(15)).toBeNull()
+    expect(tree.search(12)).toBe(12)
+  })
+
+  test('should remove nodes with two children correctly', () => {
+    tree.addValue(18)
+    tree.removeValue(15)
+
+    expect(tree.search(15)).toBeNull()
+    expect(tree.search(18)).toBe(18)
+  })
+
+  test('should return null for non-existent values', () => {
+    expect(tree.search(20)).toBeNull()
+    expect(tree.search(0)).toBeNull()
+  })
+
+  test('should handle removal of root node correctly', () => {
+    tree.removeValue(10)
+    expect(tree.search(10)).toBeNull()
+  })
+
+  test('should handle empty tree gracefully', () => {
+    const newTree = new Tree()
+    newTree.removeValue(22) // Should not throw
+    expect(newTree.search(22)).toBeNull()
+  })
+})
