Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 52 additions & 0 deletions Maths/ModularArithmetic.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { extendedEuclideanGCD } from './ExtendedEuclideanGCD'

/**
* https://brilliant.org/wiki/modular-arithmetic/
* @param {Number} arg1 first argument
* @param {Number} arg2 second argument
* @returns {Number}
*/

const MOD = 10000007

const isInputValid = (arg1, arg2) => {
if (typeof arg1 !== 'number' || typeof arg2 !== 'number') {
throw new TypeError('Input must be Numbers')
}
}

/**
* Modulus is Distributive property,
* As a result, we separate it into numbers in order to keep it within MOD's range
*/

const add = (arg1, arg2) => {
isInputValid(arg1, arg2)
return ((arg1 % MOD) + (arg2 % MOD)) % MOD
}

const subtract = (arg1, arg2) => {
isInputValid(arg1, arg2)
// An extra MOD is added to check negative results
return ((arg1 % MOD) - (arg2 % MOD) + MOD) % MOD
}

const multiply = (arg1, arg2) => {
isInputValid(arg1, arg2)
return ((arg1 % MOD) * (arg2 % MOD)) % MOD
}

/**
*
* It is not Possible to find Division directly like the above methods,
* So we have to use the Extended Euclidean Theorem for finding Multiplicative Inverse
* https://github.com/TheAlgorithms/JavaScript/blob/master/Maths/ExtendedEuclideanGCD.js
*/

const divide = (arg1, arg2) => {
// 1st Index contains the required result
// The theorem may have return Negative value, we need to add MOD to make it Positive
return (extendedEuclideanGCD(arg1, arg2)[1] + MOD) % MOD
}

export { add, subtract, multiply, divide }
39 changes: 39 additions & 0 deletions Maths/test/ModularArithmetic.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { add, subtract, multiply, divide } from '../ModularArithmetic'

describe('Modular Arithmetic', () => {
describe('add', () => {
it('Should return 9999993 for 10000000 and 10000000', () => {
expect(add(10000000, 10000000)).toBe(9999993)
})
it('Should return 9999986 for 10000000 and 20000000', () => {
expect(add(10000000, 20000000)).toBe(9999986)
})
})

describe('subtract', () => {
it('Should return 1000000 for 10000000 and 9000000', () => {
expect(subtract(10000000, 9000000)).toBe(1000000)
})
it('Should return 7 for 10000000 and 20000000', () => {
expect(subtract(10000000, 20000000)).toBe(7)
})
})

describe('multiply', () => {
it('Should return 1000000 for 100000 and 10000', () => {
expect(multiply(100000, 10000)).toBe(9999307)
})
it('Should return 7 for 100000 and 10000100', () => {
expect(multiply(10000000, 20000000)).toBe(98)
})
})

describe('divide', () => {
it('Should return 4 for 3 and 11', () => {
expect(divide(3, 11)).toBe(4)
})
it('Should return 2 for 18 and 7', () => {
expect(divide(18, 7)).toBe(2)
})
})
})