forked from trekhleb/javascript-algorithms
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
added prime-factors algo in src/algorithms/math (trekhleb#532)
- Loading branch information
1 parent
498ab10
commit 827906c
Showing
4 changed files
with
119 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
# Prime Factors | ||
|
||
Prime factors are basically those prime numbers which multiply together to give the orignal number. For ex: 39 will have prime factors as 3 and 13 which are also prime numbers. Another example is 15 whose prime factors are 3 and 5. | ||
|
||
#### Method for finding the prime factors and their count accurately | ||
|
||
The approach is to basically keep on dividing the natural number 'n' by indexes from i = 2 to i = n by prime indexes only. This is ensured by an 'if' check. Then value of 'n' keeps on overriding by (n/i). | ||
The time complexity till now is O(n) in worst case since the loop run from index i = 2 to i = n even when no index 'i' is left to be divided by 'n' other than n itself. This time complexity can be reduced to O(sqrt(n)) from O(n). This optimisation is acheivable when loop is ran from i = 2 to i = sqrt(n). Now, we go only till O(sqrt(n)) because when 'i' becomes greater than sqrt(n), we now have the confirmation there is no index 'i' left which can divide 'n' completely other than n itself. | ||
|
||
##### Optimised Time Complexity: O(sqrt(n)) | ||
|
||
|
||
#### Hardy-Ramanujan formula for approximate calculation of prime-factor count | ||
|
||
In 1917, a theorem was formulated by G.H Hardy and Srinivasa Ramanujan which approximately tells the total count of distinct prime factors of most 'n' natural numbers. | ||
The fomula is given by ln(ln(n)). | ||
|
||
#### Code Explaiation | ||
|
||
There are on 4 functions used: | ||
|
||
- getPrimeFactors : returns array containing all distinct prime factors for given input n. | ||
|
||
- getPrimeFactorsCount: returns accurate total count of distinct prime factors of given input n. | ||
|
||
- hardyRamanujanApprox: returns approximate total count of distinct prime factors of given input n using Hardy-Ramanujan formula. | ||
|
||
- errorPercent : returns %age of error in approximation using formula to that of accurate result. The formula used is: **[Modulus(accurate_val - approximate_val) / accurate_val ] * 100**. This shows deviation from accurate result. | ||
|
||
|
||
## References | ||
|
||
- [Youtube](https://www.youtube.com/watch?v=6PDtgHhpCHo) | ||
- [Wikipedia](https://en.wikipedia.org/wiki/Hardy%E2%80%93Ramanujan_theorem) |
40 changes: 40 additions & 0 deletions
40
src/algorithms/math/prime-factors/__test__/primefactors.test.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
import primefactors from '../primefactors'; | ||
|
||
describe('prime-factors', () => { | ||
it('should give prime factors', () => { | ||
expect(primefactors.getPrimeFactors(510510)).toEqual([2, 3, 5, 7, 11, 13, 17]); | ||
expect(primefactors.getPrimeFactors(343434)).toEqual([2, 3, 7, 13, 17, 37]); | ||
expect(primefactors.getPrimeFactors(456745)).toEqual([5, 167, 547]); | ||
expect(primefactors.getPrimeFactors(8735463)).toEqual([3, 11, 88237]); | ||
expect(primefactors.getPrimeFactors(873452453)).toEqual([149, 1637, 3581]); | ||
expect(primefactors.getPrimeFactors(52734)).toEqual([2, 3, 11, 17, 47]); | ||
}); | ||
|
||
it('should give prime factors count accurately', () => { | ||
expect(primefactors.getPrimeFactorsCount(primefactors.getPrimeFactors(510510))).toEqual(7); | ||
expect(primefactors.getPrimeFactorsCount(primefactors.getPrimeFactors(343434))).toEqual(6); | ||
expect(primefactors.getPrimeFactorsCount(primefactors.getPrimeFactors(456745))).toEqual(3); | ||
expect(primefactors.getPrimeFactorsCount(primefactors.getPrimeFactors(8735463))).toEqual(3); | ||
expect(primefactors.getPrimeFactorsCount(primefactors.getPrimeFactors(873452453))).toEqual(3); | ||
expect(primefactors.getPrimeFactorsCount(primefactors.getPrimeFactors(52734))).toEqual(5); | ||
}); | ||
|
||
it('should give prime factors count approximately using Hardy-Ramanujan-Approx', () => { | ||
expect(primefactors.hardyRamanujanApprox(510510)).toBeCloseTo(2.5759018900,5); | ||
expect(primefactors.hardyRamanujanApprox(343434)).toBeCloseTo(2.54527635538,5); | ||
expect(primefactors.hardyRamanujanApprox(456745)).toBeCloseTo(2.5673987036,5); | ||
expect(primefactors.hardyRamanujanApprox(8735463)).toBeCloseTo(2.771519494900,5); | ||
expect(primefactors.hardyRamanujanApprox(873452453)).toBeCloseTo(3.0247066455016,5); | ||
expect(primefactors.hardyRamanujanApprox(52734)).toBeCloseTo(2.386284094835,5); | ||
}); | ||
|
||
it('should give error percentage of deviation of Hardy-Ramanujan-Approx prime-factors count from accurate prime-factors count', () => { | ||
expect(primefactors.errorPercent(primefactors.getPrimeFactorsCount(primefactors.getPrimeFactors(510510)),primefactors.hardyRamanujanApprox(510510))).toBeCloseTo(63.20140157059997,5); | ||
expect(primefactors.errorPercent(primefactors.getPrimeFactorsCount(primefactors.getPrimeFactors(343434)),primefactors.hardyRamanujanApprox(343434))).toBeCloseTo(57.5787274,5); | ||
expect(primefactors.errorPercent(primefactors.getPrimeFactorsCount(primefactors.getPrimeFactors(456745)),primefactors.hardyRamanujanApprox(456745))).toBeCloseTo(14.420043212851,5); | ||
expect(primefactors.errorPercent(primefactors.getPrimeFactorsCount(primefactors.getPrimeFactors(8735463)),primefactors.hardyRamanujanApprox(8735463))).toBeCloseTo(7.61601683663378,5); | ||
expect(primefactors.errorPercent(primefactors.getPrimeFactorsCount(primefactors.getPrimeFactors(873452453)),primefactors.hardyRamanujanApprox(873452453))).toBeCloseTo(0.8235548500,5); | ||
expect(primefactors.errorPercent(primefactors.getPrimeFactorsCount(primefactors.getPrimeFactors(52734)),primefactors.hardyRamanujanApprox(52734))).toBeCloseTo(52.27431810328,5); | ||
}); | ||
}); | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
export default { | ||
|
||
getPrimeFactors : (n) => { | ||
let factorsArray = []; // an array where all the prime factors will be stored | ||
|
||
//over here optimisation is made by running loop till sqrt(n) instead of n | ||
for (let i = 2 ; i <= Math.sqrt(n); i++){ | ||
if(n % i === 0){ // if check to ensure i completely divides n | ||
let count = 0; // This count keeps track of number of times i divides n | ||
while(n % i === 0){ | ||
n = n/i; // override the value of n | ||
count++; // count value updated | ||
} | ||
factorsArray.push(i); // array gets populated | ||
} | ||
} | ||
if(n !== 1){ // finally we cannot push 1 to array since it cannot be a prime-factor | ||
factorsArray.push(n); | ||
} | ||
|
||
return factorsArray; | ||
}, | ||
|
||
//returns accurate prime-factors count | ||
getPrimeFactorsCount : (factorsArray) => { | ||
return factorsArray.length; | ||
}, | ||
|
||
|
||
//returns Hardy-Ramanujan Approximation of prime-factors count | ||
hardyRamanujanApprox : (n) => { | ||
return Math.log(Math.log(n)); | ||
}, | ||
|
||
//returns %age of error in approximation using formula to that of accurate result. | ||
errorPercent : (exactFactorCount,approximateFactorCount) => { | ||
let diff = exactFactorCount-approximateFactorCount > 0 ? exactFactorCount-approximateFactorCount: -(exactFactorCount-approximateFactorCount); | ||
return (diff/exactFactorCount * 100); | ||
} | ||
|
||
|
||
} | ||
|
||
|