From 2b2821c27483be636fc7af4adaa03ca408ffc704 Mon Sep 17 00:00:00 2001 From: Shreyas Shrawage Date: Fri, 1 Oct 2021 14:33:51 +0530 Subject: [PATCH 1/3] Added a function to find GCD of multiple numbers --- README.md | 12 +++++- src/algorithms/math/gcd_multiple_numbers.js | 44 +++++++++++++++++++++ src/algorithms/math/index.js | 14 ++++--- 3 files changed, 63 insertions(+), 7 deletions(-) create mode 100644 src/algorithms/math/gcd_multiple_numbers.js diff --git a/README.md b/README.md index ce93985d..a8e4af85 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # algorithms-js [![Build Status](https://travis-ci.org/manrajgrover/algorithms-js.svg?branch=master)](https://travis-ci.org/manrajgrover/algorithms-js) [![Build status](https://ci.appveyor.com/api/projects/status/6l0vybrb4y0c7eh8?svg=true)](https://ci.appveyor.com/project/manrajgrover/algorithms-js) [![npm](https://img.shields.io/npm/v/algorithms-js.svg?maxAge=2592000?style=flat-square)](https://www.npmjs.com/package/algorithms-js) [![npm](https://img.shields.io/npm/dt/algorithms-js.svg?maxAge=2592000?style=flat-square)](https://www.npmjs.com/package/algorithms-js) ![awesome](https://img.shields.io/badge/awesome-yes-green.svg) -> Consumable Data Structures and Algorithms library in JavaScript +> Consumable Data Structures and Algorithms library in JavaScript ## Note @@ -27,9 +27,11 @@ Or use `jsdeliver`: ``` ## Usage + Library contains both algorithms as well as data structures: ### Data Structures + Currently, library supports following data structures: - [Doubly Linked List](https://github.com/manrajgrover/algorithms-js/blob/master/src/data-structures/doubly_linked_list.js) @@ -42,9 +44,11 @@ Currently, library supports following data structures: - [Trie](https://github.com/manrajgrover/algorithms-js/blob/master/src/data-structures/trie.js) ### Algorithms + Currently library supports following algorithms: #### Search + Various Searching algorithms: - [Binary Search](https://github.com/manrajgrover/algorithms-js/blob/master/src/algorithms/search/binary_search.js) @@ -57,6 +61,7 @@ Various Searching algorithms: - [Ternary Search](https://github.com/manrajgrover/algorithms-js/blob/master/src/algorithms/search/ternary_search.js) #### Sort + Various Sorting algorithms: - [Bubble Sort](https://github.com/manrajgrover/algorithms-js/blob/master/src/algorithms/sort/bubble_sort.js) @@ -68,19 +73,23 @@ Various Sorting algorithms: - [Selection Sort](https://github.com/manrajgrover/algorithms-js/blob/master/src/algorithms/sort/selection_sort.js) #### Math + Various Math algorithms: - [Extended Euclidean](https://github.com/manrajgrover/algorithms-js/blob/master/src/algorithms/math/extended_euclidean.js) - [Fast Exponentiation](https://github.com/manrajgrover/algorithms-js/blob/master/src/algorithms/math/fast_exp.js) - [GCD](https://github.com/manrajgrover/algorithms-js/blob/master/src/algorithms/math/gcd.js) +- [GCD of Multiple Numbers](https://github.com/manrajgrover/algorithms-js/blob/master/src/algorithms/math/gcd_multiple_numbers.js) - [LCM](https://github.com/manrajgrover/algorithms-js/blob/master/src/algorithms/math/lcm.js) #### String + Various String algorithms: - [Levenshtein Distance](https://github.com/manrajgrover/algorithms-js/blob/master/src/algorithms/string/levenshtein_distance.js) #### Geometry + Various Geometry algorithms: - [Tangent between circles](https://github.com/manrajgrover/algorithms-js/blob/master/src/algorithms/geometry/tangent_between_circles.js) @@ -128,6 +137,7 @@ $ npm run build-dev ``` ## Get in touch + Say hi on [twitter](https://twitter.com/manrajsgrover) ## License diff --git a/src/algorithms/math/gcd_multiple_numbers.js b/src/algorithms/math/gcd_multiple_numbers.js new file mode 100644 index 00000000..1d4b6836 --- /dev/null +++ b/src/algorithms/math/gcd_multiple_numbers.js @@ -0,0 +1,44 @@ +/** + * Calculates GCD of multiple numbers + * @param {Number, Number... Number} + * @return {Number} HCF or GCD of provided numbers + * + * References: https://www.geeksforgeeks.org/python-program-for-gcd-of-more-than-two-or-array-numbers/ + */ +function gcd_multiple_numbers() { + if (arguments.length < 2) { + console.error( + `Function gcd_multiple_numbers requires atleast 2 arguments, but only ${arguments.length} provided.` + ); + return; + } + const GCD = (a, b) => { + a = Math.abs(a); + b = Math.abs(b); + + if (a === 0 || b === 0) { + return 0; + } + + if (a === b) { + return a; + } + + if (a > b) { + return GCD(a - b, b); + } + + return GCD(a, b - a); + }; + + num1 = arguments[0]; + num2 = arguments[1]; + let gcd = GCD(num1, num2); + for (let i = 2; i < arguments.length; i++) { + gcd = GCD(gcd, arguments[i]); + } + + return gcd; +} + +module.exports = gcd_multiple_numbers; diff --git a/src/algorithms/math/index.js b/src/algorithms/math/index.js index 41b2e488..93f400c1 100644 --- a/src/algorithms/math/index.js +++ b/src/algorithms/math/index.js @@ -1,13 +1,15 @@ -const extendedEuclidean = require('./extended_euclidean'); -const gcd = require('./gcd'); -const fastexp = require('./fast_exp'); -const lcm = require('./lcm'); -const modularInverse = require('./modular_inverse'); +const extendedEuclidean = require("./extended_euclidean"); +const gcd = require("./gcd"); +const gcd_multiple_numbers = require("./gcd_multiple_numbers"); +const fastexp = require("./fast_exp"); +const lcm = require("./lcm"); +const modularInverse = require("./modular_inverse"); module.exports = { extendedEuclidean, gcd, + gcd_multiple_numbers, fastexp, lcm, - modularInverse + modularInverse, }; From ec90712f768ae018b8329a786743751bfd4cdd75 Mon Sep 17 00:00:00 2001 From: Shreyas Shrawage Date: Fri, 1 Oct 2021 14:47:01 +0530 Subject: [PATCH 2/3] Added testing script for gdc of multiple numbers --- package-lock.json | 56 ++++++++++++++----- .../algorithms/math/testGcdMultipleNumbers.js | 31 ++++++++++ 2 files changed, 72 insertions(+), 15 deletions(-) create mode 100644 test/algorithms/math/testGcdMultipleNumbers.js diff --git a/package-lock.json b/package-lock.json index af75e273..b64d1db0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -483,6 +483,7 @@ "resolved": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz", "integrity": "sha1-DNkKVhCT810KmSVsIrcGlDP60Rc=", "dev": true, + "optional": true, "requires": { "kind-of": "^3.0.2", "longest": "^1.0.1", @@ -3854,7 +3855,8 @@ "ansi-regex": { "version": "2.1.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "aproba": { "version": "1.2.0", @@ -3875,12 +3877,14 @@ "balanced-match": { "version": "1.0.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "brace-expansion": { "version": "1.1.11", "bundled": true, "dev": true, + "optional": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -3895,17 +3899,20 @@ "code-point-at": { "version": "1.1.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "concat-map": { "version": "0.0.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "console-control-strings": { "version": "1.1.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "core-util-is": { "version": "1.0.2", @@ -4022,7 +4029,8 @@ "inherits": { "version": "2.0.3", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "ini": { "version": "1.3.5", @@ -4034,6 +4042,7 @@ "version": "1.0.0", "bundled": true, "dev": true, + "optional": true, "requires": { "number-is-nan": "^1.0.0" } @@ -4048,6 +4057,7 @@ "version": "3.0.4", "bundled": true, "dev": true, + "optional": true, "requires": { "brace-expansion": "^1.1.7" } @@ -4055,12 +4065,14 @@ "minimist": { "version": "0.0.8", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "minipass": { "version": "2.2.4", "bundled": true, "dev": true, + "optional": true, "requires": { "safe-buffer": "^5.1.1", "yallist": "^3.0.0" @@ -4079,6 +4091,7 @@ "version": "0.5.1", "bundled": true, "dev": true, + "optional": true, "requires": { "minimist": "0.0.8" } @@ -4159,7 +4172,8 @@ "number-is-nan": { "version": "1.0.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "object-assign": { "version": "4.1.1", @@ -4171,6 +4185,7 @@ "version": "1.4.0", "bundled": true, "dev": true, + "optional": true, "requires": { "wrappy": "1" } @@ -4256,7 +4271,8 @@ "safe-buffer": { "version": "5.1.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "safer-buffer": { "version": "2.1.2", @@ -4292,6 +4308,7 @@ "version": "1.0.2", "bundled": true, "dev": true, + "optional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -4311,6 +4328,7 @@ "version": "3.0.1", "bundled": true, "dev": true, + "optional": true, "requires": { "ansi-regex": "^2.0.0" } @@ -4354,12 +4372,14 @@ "wrappy": { "version": "1.0.2", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "yallist": { "version": "3.0.2", "bundled": true, - "dev": true + "dev": true, + "optional": true } } }, @@ -5193,7 +5213,8 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz", "integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc=", - "dev": true + "dev": true, + "optional": true }, "loose-envify": { "version": "1.4.0", @@ -5640,6 +5661,7 @@ "version": "0.1.4", "bundled": true, "dev": true, + "optional": true, "requires": { "kind-of": "^3.0.2", "longest": "^1.0.1", @@ -5961,7 +5983,8 @@ "is-buffer": { "version": "1.1.6", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "is-builtin-module": { "version": "1.0.0", @@ -6045,6 +6068,7 @@ "version": "3.2.2", "bundled": true, "dev": true, + "optional": true, "requires": { "is-buffer": "^1.1.5" } @@ -6091,7 +6115,8 @@ "longest": { "version": "1.0.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "lru-cache": { "version": "4.1.3", @@ -6357,7 +6382,8 @@ "repeat-string": { "version": "1.6.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "require-directory": { "version": "2.1.1", diff --git a/test/algorithms/math/testGcdMultipleNumbers.js b/test/algorithms/math/testGcdMultipleNumbers.js new file mode 100644 index 00000000..dc03fb45 --- /dev/null +++ b/test/algorithms/math/testGcdMultipleNumbers.js @@ -0,0 +1,31 @@ +/* eslint-env mocha */ +const gcd_multiple_numbers = + require("../../../src").algorithms.math.gcd_multiple_numbers; + +const assert = require("assert"); + +describe("GCD", () => { + it("should return 0 for either or both numbers as 0", () => { + assert.equal(gcd_multiple_numbers(0, 10), 0); + assert.equal(gcd_multiple_numbers(10, 0), 0); + assert.equal(gcd_multiple_numbers(0, 0), 0); + }); + + it("should return 1 for 1 and positive numbers >= 1", () => { + assert.equal(gcd_multiple_numbers(1, 10), 1); + assert.equal(gcd_multiple_numbers(1, 1), 1); + assert.equal(gcd_multiple_numbers(10, 1), 1); + }); + + it("should return gcd of two numbers", () => { + assert.equal(gcd_multiple_numbers(60, 10), 10); + assert.equal(gcd_multiple_numbers(65, 10), 5); + assert.equal(gcd_multiple_numbers(3, 2), 1); + }); + + it("should return gcd of negative numbers", () => { + assert.equal(gcd_multiple_numbers(-60, -10), 10); + assert.equal(gcd_multiple_numbers(65, -10), 5); + assert.equal(gcd_multiple_numbers(-3, 2), 1); + }); +}); From 5e111adc2831e0ad68edea7689a658fa896e5a52 Mon Sep 17 00:00:00 2001 From: Shreyas Shrawage Date: Fri, 1 Oct 2021 14:57:57 +0530 Subject: [PATCH 3/3] Added more test cases --- test/algorithms/math/testGcdMultipleNumbers.js | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/test/algorithms/math/testGcdMultipleNumbers.js b/test/algorithms/math/testGcdMultipleNumbers.js index dc03fb45..a068c6af 100644 --- a/test/algorithms/math/testGcdMultipleNumbers.js +++ b/test/algorithms/math/testGcdMultipleNumbers.js @@ -5,9 +5,9 @@ const gcd_multiple_numbers = const assert = require("assert"); describe("GCD", () => { - it("should return 0 for either or both numbers as 0", () => { + it("should return 0 for either or the numbers as 0", () => { assert.equal(gcd_multiple_numbers(0, 10), 0); - assert.equal(gcd_multiple_numbers(10, 0), 0); + assert.equal(gcd_multiple_numbers(10, 0, 1), 0); assert.equal(gcd_multiple_numbers(0, 0), 0); }); @@ -23,9 +23,16 @@ describe("GCD", () => { assert.equal(gcd_multiple_numbers(3, 2), 1); }); + it("should return gcd of multiple numbers", () => { + assert.equal(gcd_multiple_numbers(60, 10, 5), 5); + assert.equal(gcd_multiple_numbers(33, 10, 4), 1); + assert.equal(gcd_multiple_numbers(3, 6, 9, 12, 18), 3); + }); + it("should return gcd of negative numbers", () => { assert.equal(gcd_multiple_numbers(-60, -10), 10); assert.equal(gcd_multiple_numbers(65, -10), 5); + assert.equal(gcd_multiple_numbers(65, -10, -3), 1); assert.equal(gcd_multiple_numbers(-3, 2), 1); }); });