From 8767d0b1306d52d4aa0334c4718b6599ac8ffb40 Mon Sep 17 00:00:00 2001
From: Exortions <exortionsmc@gmail.com>
Date: Sat, 7 May 2022 18:36:04 -0700
Subject: [PATCH 1/8] add yt video association algorithm

---
 Search/YoutubeVideoAssociation.js           | 54 +++++++++++++++++++++
 Search/test/YoutubeVideoAssociation.test.js | 25 ++++++++++
 2 files changed, 79 insertions(+)
 create mode 100644 Search/YoutubeVideoAssociation.js
 create mode 100644 Search/test/YoutubeVideoAssociation.test.js

diff --git a/Search/YoutubeVideoAssociation.js b/Search/YoutubeVideoAssociation.js
new file mode 100644
index 0000000000..a729b64d72
--- /dev/null
+++ b/Search/YoutubeVideoAssociation.js
@@ -0,0 +1,54 @@
+class AssociationAlgorithm {
+  constructor (requiredPercentageForAsssociation = 10) {
+    this.REQUIRED_PERCENTAGE_FOR_ASSOCIATION = requiredPercentageForAsssociation
+
+    this.associations = {}
+    this.searches = {}
+  }
+
+  #associate (id, query) {
+    if (!this.associations[id]) { this.associations[id] = [] }
+
+    this.associations[id].push(query)
+  }
+
+  #search (id, query) {
+    if (!this.searches[id]) { this.searches[id] = [] }
+
+    let search = Number(this.searches[id][query])
+
+    if (!search) search = 0
+
+    this.searches[id][query] = search + 1
+  }
+
+  // Main function to run the algorithm
+  search (data) {
+    const { id, views } = data.video
+    const { query } = data.search
+
+    if (!this.associations[id]) this.associations[id] = []
+
+    this.#search(id, query)
+
+    const percentageOfViewsFromSearch = (Number(this.searches[id][query]) / Number(views)) * 100
+
+    if (percentageOfViewsFromSearch > this.REQUIRED_PERCENTAGE_FOR_ASSOCIATION) {
+      // Associate the video with the search query
+
+      this.#associate(id, query)
+    } else {
+      // The video does not have a high enough percentage of views from the query to be associated with it
+    }
+  }
+
+  isVideoAssociated (id, query) {
+    return this.associations[id] && this.associations[id].includes(query)
+  }
+
+  getAssociations (id) {
+    return this.associations[id]
+  }
+}
+
+export default AssociationAlgorithm
diff --git a/Search/test/YoutubeVideoAssociation.test.js b/Search/test/YoutubeVideoAssociation.test.js
new file mode 100644
index 0000000000..c81bec76f0
--- /dev/null
+++ b/Search/test/YoutubeVideoAssociation.test.js
@@ -0,0 +1,25 @@
+import AssociationAlgorithm from '../YoutubeVideoAssociation'
+
+describe('Youtube Video Association Algorithm', () => {
+  const search = {
+    video: {
+      id: 'dQw4w9WgXcQ',
+      views: '100'
+    },
+    search: {
+      query: 'Rick Roll'
+    }
+  }
+
+  const algorithm = new AssociationAlgorithm(10)
+
+  test('The video should not be associated after one search', () => {
+    algorithm.search(search)
+
+    expect(algorithm.isVideoAssociated('dQw4w9WgXcQ', 'Rick Roll')).toBe(false)
+  })
+
+  test('The video should be associated after 11 searches', () => {
+    for (let i = 0; i < 10; i++) algorithm.search(search)
+  })
+})

From 78e3cb870de677032459b13c39d9285173a3bc27 Mon Sep 17 00:00:00 2001
From: Exortions <exortionsmc@gmail.com>
Date: Sat, 7 May 2022 22:02:04 -0700
Subject: [PATCH 2/8] Implement FindMaxRecursion in JS

---
 Maths/FindMaxRecursion.js           | 38 +++++++++++++++++++
 Maths/test/FindMaxRecursion.test.js | 58 +++++++++++++++++++++++++++++
 2 files changed, 96 insertions(+)
 create mode 100644 Maths/FindMaxRecursion.js
 create mode 100644 Maths/test/FindMaxRecursion.test.js

diff --git a/Maths/FindMaxRecursion.js b/Maths/FindMaxRecursion.js
new file mode 100644
index 0000000000..a95eb68406
--- /dev/null
+++ b/Maths/FindMaxRecursion.js
@@ -0,0 +1,38 @@
+/**
+ * @function findMaxRecursion
+ * @description This algorithm will find the maximum value of a array of numbers.
+ *
+ * @param {Integer[]} arr Array of numbers
+ * @param {Integer} left Index of the first element
+ * @param {Integer} right Index of the last element
+ *
+ * @return {Integer} Maximum value of the array
+ *
+ * @see [Maximum value](https://en.wikipedia.org/wiki/Maximum_value)
+ *
+ * @example findMaxRecursion([1, 2, 4, 5]) = 5
+ * @example findMaxRecursion([10, 40, 100, 20]) = 100
+ * @example findMaxRecursion([-1, -2, -4, -5]) = -1
+ */
+function findMaxRecursion(arr, left, right) {
+  const len = arr.length
+
+  if (len === 0 || !arr) return undefined
+
+  if (left >= len || left < -len || right >= len || right < -len)
+    throw new Error('Index out of range')
+
+  if (left === right) return arr[left]
+
+  // left + right shifted is the middle index
+  const mid = (left + right) >> 1
+
+  // Find the maximum of left and right
+  const leftMax = findMaxRecursion(arr, left, mid)
+  const rightMax = findMaxRecursion(arr, mid + 1, right)
+
+  // Return the maximum
+  return Math.max(leftMax, rightMax)
+}
+
+export { findMaxRecursion }
diff --git a/Maths/test/FindMaxRecursion.test.js b/Maths/test/FindMaxRecursion.test.js
new file mode 100644
index 0000000000..4772eeb1d3
--- /dev/null
+++ b/Maths/test/FindMaxRecursion.test.js
@@ -0,0 +1,58 @@
+import { findMaxRecursion } from '../FindMaxRecursion'
+
+describe('Test findMaxRecursion function', () => {
+  const positiveAndNegativeArray = [1, 2, 4, 5, -1, -2, -4, -5]
+  const positiveAndNegativeArray1 = [10, 40, 100, 20, -10, -40, -100, -20]
+
+  const positiveArray = [1, 2, 4, 5]
+  const positiveArray1 = [10, 40, 100, 20]
+
+  const negativeArray = [-1, -2, -4, -5]
+  const negativeArray1 = [-10, -40, -100, -20]
+
+  const zeroArray = [0, 0, 0, 0]
+  const emptyArray = []
+
+  it('Testing with positive arrays', () => {
+    expect(findMaxRecursion(positiveArray, 0, positiveArray.length - 1)).toBe(5)
+    expect(findMaxRecursion(positiveArray1, 0, positiveArray1.length - 1)).toBe(
+      100
+    )
+  })
+
+  it('Testing with negative arrays', () => {
+    expect(findMaxRecursion(negativeArray, 0, negativeArray.length - 1)).toBe(
+      -1
+    )
+    expect(findMaxRecursion(negativeArray1, 0, negativeArray1.length - 1)).toBe(
+      -10
+    )
+  })
+
+  it('Testing with positive and negative arrays', () => {
+    expect(
+      findMaxRecursion(
+        positiveAndNegativeArray,
+        0,
+        positiveAndNegativeArray.length - 1
+      )
+    ).toBe(5)
+    expect(
+      findMaxRecursion(
+        positiveAndNegativeArray1,
+        0,
+        positiveAndNegativeArray1.length - 1
+      )
+    ).toBe(100)
+  })
+
+  it('Testing with zero arrays', () => {
+    expect(findMaxRecursion(zeroArray, 0, zeroArray.length - 1)).toBe(0)
+  })
+
+  it('Testing with empty arrays', () => {
+    expect(findMaxRecursion(emptyArray, 0, emptyArray.length - 1)).toBe(
+      undefined
+    )
+  })
+})

From f784ecfd6a9cb159b5f1b6285400491bb903c433 Mon Sep 17 00:00:00 2001
From: Exortions <75327059+Exortions@users.noreply.github.com>
Date: Sat, 7 May 2022 22:09:59 -0700
Subject: [PATCH 3/8] Delete file in other PR

---
 Search/YoutubeVideoAssociation.js | 54 -------------------------------
 1 file changed, 54 deletions(-)
 delete mode 100644 Search/YoutubeVideoAssociation.js

diff --git a/Search/YoutubeVideoAssociation.js b/Search/YoutubeVideoAssociation.js
deleted file mode 100644
index a729b64d72..0000000000
--- a/Search/YoutubeVideoAssociation.js
+++ /dev/null
@@ -1,54 +0,0 @@
-class AssociationAlgorithm {
-  constructor (requiredPercentageForAsssociation = 10) {
-    this.REQUIRED_PERCENTAGE_FOR_ASSOCIATION = requiredPercentageForAsssociation
-
-    this.associations = {}
-    this.searches = {}
-  }
-
-  #associate (id, query) {
-    if (!this.associations[id]) { this.associations[id] = [] }
-
-    this.associations[id].push(query)
-  }
-
-  #search (id, query) {
-    if (!this.searches[id]) { this.searches[id] = [] }
-
-    let search = Number(this.searches[id][query])
-
-    if (!search) search = 0
-
-    this.searches[id][query] = search + 1
-  }
-
-  // Main function to run the algorithm
-  search (data) {
-    const { id, views } = data.video
-    const { query } = data.search
-
-    if (!this.associations[id]) this.associations[id] = []
-
-    this.#search(id, query)
-
-    const percentageOfViewsFromSearch = (Number(this.searches[id][query]) / Number(views)) * 100
-
-    if (percentageOfViewsFromSearch > this.REQUIRED_PERCENTAGE_FOR_ASSOCIATION) {
-      // Associate the video with the search query
-
-      this.#associate(id, query)
-    } else {
-      // The video does not have a high enough percentage of views from the query to be associated with it
-    }
-  }
-
-  isVideoAssociated (id, query) {
-    return this.associations[id] && this.associations[id].includes(query)
-  }
-
-  getAssociations (id) {
-    return this.associations[id]
-  }
-}
-
-export default AssociationAlgorithm

From 59aaa5dbe942e9ed7be37eaedeec4ffa9227475f Mon Sep 17 00:00:00 2001
From: Exortions <exortionsmc@gmail.com>
Date: Sat, 7 May 2022 22:02:04 -0700
Subject: [PATCH 4/8] Fix requested changes

---
 Maths/FindMaxRecursion.js | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/Maths/FindMaxRecursion.js b/Maths/FindMaxRecursion.js
index a95eb68406..b6a397d403 100644
--- a/Maths/FindMaxRecursion.js
+++ b/Maths/FindMaxRecursion.js
@@ -14,17 +14,18 @@
  * @example findMaxRecursion([10, 40, 100, 20]) = 100
  * @example findMaxRecursion([-1, -2, -4, -5]) = -1
  */
-function findMaxRecursion(arr, left, right) {
+function findMaxRecursion (arr, left, right) {
   const len = arr.length
 
   if (len === 0 || !arr) return undefined
 
-  if (left >= len || left < -len || right >= len || right < -len)
+  if (left >= len || left < -len || right >= len || right < -len) {
     throw new Error('Index out of range')
+  }
 
   if (left === right) return arr[left]
 
-  // left + right shifted is the middle index
+  // x >> y == floor(x / pow(2, y))
   const mid = (left + right) >> 1
 
   // Find the maximum of left and right

From 260474d23920041ffe38bdaf489a9e5d25c6d235 Mon Sep 17 00:00:00 2001
From: Exortions <exortionsmc@gmail.com>
Date: Sun, 8 May 2022 11:54:22 -0700
Subject: [PATCH 5/8] Add requested changes

---
 Maths/FindMaxRecursion.js | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/Maths/FindMaxRecursion.js b/Maths/FindMaxRecursion.js
index b6a397d403..96cd514299 100644
--- a/Maths/FindMaxRecursion.js
+++ b/Maths/FindMaxRecursion.js
@@ -17,18 +17,22 @@
 function findMaxRecursion (arr, left, right) {
   const len = arr.length
 
-  if (len === 0 || !arr) return undefined
+  if (len === 0 || !arr) {
+    return undefined
+  }
 
   if (left >= len || left < -len || right >= len || right < -len) {
     throw new Error('Index out of range')
   }
 
-  if (left === right) return arr[left]
+  if (left === right) {
+    return arr[left]
+  }
 
   // x >> y == floor(x / pow(2, y))
   const mid = (left + right) >> 1
 
-  // Find the maximum of left and right
+  // n >> m is equivalent to floor(n / pow(2, m)), floor(n / 2) in this case
   const leftMax = findMaxRecursion(arr, left, mid)
   const rightMax = findMaxRecursion(arr, mid + 1, right)
 

From bd391bd22b0c21553cc492003a939c81c1b75040 Mon Sep 17 00:00:00 2001
From: Exortions <75327059+Exortions@users.noreply.github.com>
Date: Sun, 8 May 2022 12:00:44 -0700
Subject: [PATCH 6/8] Delete YoutubeVideoAssociation.test.js

---
 Search/test/YoutubeVideoAssociation.test.js | 25 ---------------------
 1 file changed, 25 deletions(-)
 delete mode 100644 Search/test/YoutubeVideoAssociation.test.js

diff --git a/Search/test/YoutubeVideoAssociation.test.js b/Search/test/YoutubeVideoAssociation.test.js
deleted file mode 100644
index c81bec76f0..0000000000
--- a/Search/test/YoutubeVideoAssociation.test.js
+++ /dev/null
@@ -1,25 +0,0 @@
-import AssociationAlgorithm from '../YoutubeVideoAssociation'
-
-describe('Youtube Video Association Algorithm', () => {
-  const search = {
-    video: {
-      id: 'dQw4w9WgXcQ',
-      views: '100'
-    },
-    search: {
-      query: 'Rick Roll'
-    }
-  }
-
-  const algorithm = new AssociationAlgorithm(10)
-
-  test('The video should not be associated after one search', () => {
-    algorithm.search(search)
-
-    expect(algorithm.isVideoAssociated('dQw4w9WgXcQ', 'Rick Roll')).toBe(false)
-  })
-
-  test('The video should be associated after 11 searches', () => {
-    for (let i = 0; i < 10; i++) algorithm.search(search)
-  })
-})

From da7fc331e770749083959feb4d06d11210c7e82f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Lars=20M=C3=BCller?=
 <34514239+appgurueu@users.noreply.github.com>
Date: Sun, 8 May 2022 22:27:43 +0200
Subject: [PATCH 7/8] Deduplicate comment

---
 Maths/FindMaxRecursion.js | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/Maths/FindMaxRecursion.js b/Maths/FindMaxRecursion.js
index 96cd514299..65576540ed 100644
--- a/Maths/FindMaxRecursion.js
+++ b/Maths/FindMaxRecursion.js
@@ -29,10 +29,9 @@ function findMaxRecursion (arr, left, right) {
     return arr[left]
   }
 
-  // x >> y == floor(x / pow(2, y))
+  // n >> m is equivalent to floor(n / pow(2, m)), floor(n / 2) in this case, which is the mid index
   const mid = (left + right) >> 1
-
-  // n >> m is equivalent to floor(n / pow(2, m)), floor(n / 2) in this case
+  
   const leftMax = findMaxRecursion(arr, left, mid)
   const rightMax = findMaxRecursion(arr, mid + 1, right)
 

From 0f83eaf05a4ae552f9711ae221b5d12c67c6a8d1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Lars=20M=C3=BCller?=
 <34514239+appgurueu@users.noreply.github.com>
Date: Sun, 8 May 2022 22:30:03 +0200
Subject: [PATCH 8/8] Remove trailing spaces

---
 Maths/FindMaxRecursion.js | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Maths/FindMaxRecursion.js b/Maths/FindMaxRecursion.js
index 65576540ed..db2325f4f5 100644
--- a/Maths/FindMaxRecursion.js
+++ b/Maths/FindMaxRecursion.js
@@ -31,7 +31,7 @@ function findMaxRecursion (arr, left, right) {
 
   // n >> m is equivalent to floor(n / pow(2, m)), floor(n / 2) in this case, which is the mid index
   const mid = (left + right) >> 1
-  
+
   const leftMax = findMaxRecursion(arr, left, mid)
   const rightMax = findMaxRecursion(arr, mid + 1, right)