diff --git a/src/helpers/divisors.test.ts b/src/helpers/divisors.test.ts index 81ec8125..d24979dc 100644 --- a/src/helpers/divisors.test.ts +++ b/src/helpers/divisors.test.ts @@ -1,6 +1,12 @@ -import { divisors } from './divisors'; +import { divisors, nextPrimeFactor, primeFactors } from './divisors'; describe('divisors of a number', () => { + it('divisors of one', () => { + expect.assertions(1); + + expect(divisors(1)).toStrictEqual([1]); + }); + it('divisors of a number', () => { expect.assertions(5); @@ -10,4 +16,50 @@ describe('divisors of a number', () => { expect(divisors(9)).toStrictEqual([1, 3, 9]); expect(divisors(16)).toStrictEqual([1, 2, 4, 8, 16]); }); + + it('next prime factor of a target number', () => { + expect.assertions(5); + + expect(nextPrimeFactor(1)).toStrictEqual({ + factor: 1, + carry: 1, + cycles: 0 + }); + expect(nextPrimeFactor(2)).toStrictEqual({ + factor: 2, + carry: 1, + cycles: 1 + }); + expect(nextPrimeFactor(4)).toStrictEqual({ + factor: 2, + carry: 2, + cycles: 1 + }); + expect(nextPrimeFactor(9)).toStrictEqual({ + factor: 3, + carry: 3, + cycles: 2 + }); + expect(nextPrimeFactor(7)).toStrictEqual({ + factor: 7, + carry: 1, + cycles: 6 + }); + }); + + it('prime factors of number', () => { + expect.assertions(5); + + expect(primeFactors(1)).toStrictEqual({ factors: [1], cycles: 1 }); + expect(primeFactors(2)).toStrictEqual({ factors: [2], cycles: 1 }); + expect(primeFactors(6)).toStrictEqual({ factors: [2, 3], cycles: 3 }); + expect(primeFactors(12)).toStrictEqual({ + factors: [2, 2, 3], + cycles: 4 + }); + expect(primeFactors(120)).toStrictEqual({ + factors: [2, 2, 2, 3, 5], + cycles: 9 + }); + }); }); diff --git a/src/helpers/divisors.ts b/src/helpers/divisors.ts index c4f8febb..ed5f5cb0 100644 --- a/src/helpers/divisors.ts +++ b/src/helpers/divisors.ts @@ -38,6 +38,66 @@ export const divisors = (target: number): number[] => { return divs; }; +export interface PrimeFactor { + factor: number; + carry: number; + cycles: number; +} + +export const nextPrimeFactor = (_target: number): PrimeFactor => { + const top = Math.abs(_target); + let cycles = 0; + + if (top === 1) { + return { + factor: 1, + carry: 1, + cycles: cycles + }; + } + + let i = 2; + while (i < top) { + cycles += 1; + if (top % i === 0) { + return { + factor: i, + carry: top / i, + cycles: cycles + }; + } + i += 1; + } + + return { + factor: i, + carry: top / i, + cycles: cycles + 1 + }; +}; + +export const primeFactors = (target: number) => { + const factors = []; + let cycles = 0; + + if (target === 1) { + return { factors: [1], cycles: 1 }; + } + + let factor = target; + while (factor !== 1) { + const partial = nextPrimeFactor(factor); + cycles += partial.cycles; + + factors.push(partial.factor); + factor = partial.carry; + } + + return { factors: factors, cycles: cycles }; +}; + export default { - divisors + divisors, + primeFactors, + nextPrimeFactor }; diff --git a/src/helpers/index.ts b/src/helpers/index.ts index 7f5061b0..cb7d08c1 100644 --- a/src/helpers/index.ts +++ b/src/helpers/index.ts @@ -1,6 +1,6 @@ type nullable = T | null | undefined; -export { divisors } from './divisors'; +export { divisors, primeFactors, nextPrimeFactor } from './divisors'; export { isPrime } from './prime'; export { isPalindrome } from './isPalindrome'; export { nullable };