From 8767d0b1306d52d4aa0334c4718b6599ac8ffb40 Mon Sep 17 00:00:00 2001 From: Exortions 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 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 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 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)