From ff314a2bed38525af0445fde53e37338b4db3406 Mon Sep 17 00:00:00 2001
From: Omkarnath Parida <pomkarnath98@gmail.com>
Date: Wed, 9 Oct 2024 05:24:11 +0530
Subject: [PATCH 1/6] Add tests for Project Euler Problem 5 + minor refactor
 (#1691)

---
 DIRECTORY.md                          |  3 +++
 Project-Euler/Problem005.js           |  8 +++-----
 Project-Euler/test/Problem005.test.js | 12 ++++++++++++
 3 files changed, 18 insertions(+), 5 deletions(-)
 create mode 100644 Project-Euler/test/Problem005.test.js

diff --git a/DIRECTORY.md b/DIRECTORY.md
index 6c1fa7aeb8..7f6484cae5 100644
--- a/DIRECTORY.md
+++ b/DIRECTORY.md
@@ -35,6 +35,8 @@
   * [ROT13](Ciphers/ROT13.js)
   * [VigenereCipher](Ciphers/VigenereCipher.js)
   * [XORCipher](Ciphers/XORCipher.js)
+* **Compression**
+  * [RLE](Compression/RLE.js)
 * **Conversions**
   * [ArbitraryBase](Conversions/ArbitraryBase.js)
   * [ArrayBufferToBase64](Conversions/ArrayBufferToBase64.js)
@@ -285,6 +287,7 @@
   * [Problem016](Project-Euler/Problem016.js)
   * [Problem017](Project-Euler/Problem017.js)
   * [Problem018](Project-Euler/Problem018.js)
+  * [Problem019](Project-Euler/Problem019.js)
   * [Problem020](Project-Euler/Problem020.js)
   * [Problem021](Project-Euler/Problem021.js)
   * [Problem023](Project-Euler/Problem023.js)
diff --git a/Project-Euler/Problem005.js b/Project-Euler/Problem005.js
index fe8901c94c..92f3df9b68 100644
--- a/Project-Euler/Problem005.js
+++ b/Project-Euler/Problem005.js
@@ -5,11 +5,9 @@ Smallest multiple
 What is the smallest positive number that is evenly divisible by all of the numbers from 1 to 20?
 */
 
-export const findSmallestMultiple = () => {
-  const divisors = [
-    20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2
-  ]
-  let num = 21
+export const findSmallestMultiple = (maxDivisor) => {
+  const divisors = Array.from({ length: maxDivisor }, (_, i) => i + 1)
+  let num = maxDivisor + 1
   let result
 
   while (!result) {
diff --git a/Project-Euler/test/Problem005.test.js b/Project-Euler/test/Problem005.test.js
new file mode 100644
index 0000000000..f3ac1b03d8
--- /dev/null
+++ b/Project-Euler/test/Problem005.test.js
@@ -0,0 +1,12 @@
+import { expect } from 'vitest'
+import { findSmallestMultiple } from '../Problem005.js'
+
+describe.concurrent('Find smallest multiple', () => {
+  test.each([
+    [10, 2520],
+    [15, 360360],
+    [20, 232792560]
+  ])('max divisor -> %i, smallest multiple -> %i', (a, expected) => {
+    expect(findSmallestMultiple(a)).toBe(expected)
+  })
+})

From 55ff0ade85c3b4857f0a6531a5dfda9f21007aff Mon Sep 17 00:00:00 2001
From: Hridyanshu <124202756+HRIDYANSHU054@users.noreply.github.com>
Date: Wed, 16 Oct 2024 23:52:31 +0530
Subject: [PATCH 2/6] docs: fixed misleading comment about the array method
 (forEach instead of reduce) used in AverageMean.js (#1727)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

* docs: fixed misleading comment about the array method (forEach instead of reduce) used in AverageMean.js

* fix: optimized AverageMean.js by removing redundant comments and unnecessary operations.

* Update Maths/AverageMean.js

Co-authored-by: Lars Müller <34514239+appgurueu@users.noreply.github.com>

---------

Co-authored-by: Hridyanshu7 <himank7794@gmail.com>
Co-authored-by: Lars Müller <34514239+appgurueu@users.noreply.github.com>
---
 Maths/AverageMean.js | 6 +-----
 1 file changed, 1 insertion(+), 5 deletions(-)

diff --git a/Maths/AverageMean.js b/Maths/AverageMean.js
index 75f7b1b58e..8ae3b55992 100644
--- a/Maths/AverageMean.js
+++ b/Maths/AverageMean.js
@@ -13,11 +13,7 @@ const mean = (nums) => {
     throw new TypeError('Invalid Input')
   }
 
-  // This loop sums all values in the 'nums' array using forEach loop
-  const sum = nums.reduce((sum, cur) => sum + cur, 0)
-
-  // Divide sum by the length of the 'nums' array.
-  return sum / nums.length
+  return nums.reduce((sum, cur) => sum + cur, 0) / nums.length
 }
 
 export { mean }

From d8588f9de18db16c29cd6c8332cd0de2c2bb2f3b Mon Sep 17 00:00:00 2001
From: Omkarnath Parida <pomkarnath98@gmail.com>
Date: Sat, 16 Nov 2024 21:38:17 +0530
Subject: [PATCH 3/6] Add tests for Project euler problem 14 solution (#1713)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

* 📦 NEW: Added solution for ProjectEuler-007

* 🐛 FIX: Spelling mistake fixes

* 👌 IMPROVE: changed variable name from `inc` to `candidateValue` and thrown error in case of invalid input

* 👌 IMPROVE: Modified the code

* 👌 IMPROVE: Added test case for ProjectEuler Problem001

* 👌 IMPROVE: Added test cases for Project Euler Problem 4

* 👌 IMPROVE: auto prettier fixes

* 📦 NEW: Testcases for Project Euler Problem 14

* Updated Documentation in README.md

* 👌 IMPROVE: code improvements

---------

Co-authored-by: Omkarnath Parida <omkarnath.parida@yocket.in>
Co-authored-by: pomkarnath98 <pomkarnath98@users.noreply.github.com>
---
 Project-Euler/test/Problem014.test.js | 15 +++++++++++++++
 1 file changed, 15 insertions(+)
 create mode 100644 Project-Euler/test/Problem014.test.js

diff --git a/Project-Euler/test/Problem014.test.js b/Project-Euler/test/Problem014.test.js
new file mode 100644
index 0000000000..ff464dd42d
--- /dev/null
+++ b/Project-Euler/test/Problem014.test.js
@@ -0,0 +1,15 @@
+import { expect } from 'vitest'
+import { findLongestCollatzSequence } from '../Problem014.js'
+
+describe('Longest Collatz Sequence', () => {
+  test.each([
+    [2, 1],
+    [13, 9],
+    [1000000, 837799]
+  ])(
+    'if limit is %i, then the Longest Collatz Sequence will be %i',
+    (a, expected) => {
+      expect(findLongestCollatzSequence(a)).toBe(expected)
+    }
+  )
+})

From 85a55daf49533b9fd558e52f13603a904613e4f2 Mon Sep 17 00:00:00 2001
From: Hridyanshu <124202756+HRIDYANSHU054@users.noreply.github.com>
Date: Fri, 20 Dec 2024 21:35:50 +0530
Subject: [PATCH 4/6] test: added for Linear Search Algorithm (#1753)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

* test: added for Linear Search Algorithm

* Update Search/LinearSearch.js

Co-authored-by: Lars Müller <34514239+appgurueu@users.noreply.github.com>

---------

Co-authored-by: Hridyanshu7 <himank7794@gmail.com>
Co-authored-by: Lars Müller <34514239+appgurueu@users.noreply.github.com>
---
 Search/LinearSearch.js           |  2 ++
 Search/test/LinearSearch.test.js | 35 ++++++++++++++++++++++++++++++++
 2 files changed, 37 insertions(+)
 create mode 100644 Search/test/LinearSearch.test.js

diff --git a/Search/LinearSearch.js b/Search/LinearSearch.js
index 637ebc1589..96a9d1fa34 100644
--- a/Search/LinearSearch.js
+++ b/Search/LinearSearch.js
@@ -3,6 +3,8 @@
  * value within a list. It sequentially checks each element of the list
  * for the target value until a match is found or until all the elements
  * have been searched.
+ *
+ * @see https://en.wikipedia.org/wiki/Linear_search
  */
 function SearchArray(searchNum, ar, output = (v) => console.log(v)) {
   const position = Search(ar, searchNum)
diff --git a/Search/test/LinearSearch.test.js b/Search/test/LinearSearch.test.js
new file mode 100644
index 0000000000..d593d9aa1c
--- /dev/null
+++ b/Search/test/LinearSearch.test.js
@@ -0,0 +1,35 @@
+import { Search as linearSearch } from '../LinearSearch'
+
+const tests = [
+  {
+    test: {
+      arr: [1, 2, 300, 401, 450, 504, 800, 821, 855, 900, 1002],
+      target: 900
+    },
+    expectedValue: 9
+  },
+  {
+    test: {
+      arr: [1, 104, 110, 4, 44, 55, 56, 78],
+      target: 104
+    },
+    expectedValue: 1
+  },
+  {
+    test: {
+      arr: [-4, 5, 50, 77, 821, 85, 99, 100],
+      target: 192
+    },
+    expectedValue: -1
+  }
+]
+
+describe('Linear Search', () => {
+  it.each(tests)(
+    'linearSearch($test.arr, $test.target) => $expectedValue',
+    ({ test, expectedValue }) => {
+      const { arr, target } = test
+      expect(linearSearch(arr, target)).toBe(expectedValue)
+    }
+  )
+})

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 5/6] 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 6/6] 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()
+  })
+})
