--- title: Amicable pairs id: 5949b579404977fbaefcd737 challengeType: 5 --- ## Description
Two integers $N$ and $M$ are said to be amicable pairs if $N \neq M$ and the sum of the proper divisors of $N$ ($\mathrm{sum}(\mathrm{propDivs}(N))$) $= M$ as well as $\mathrm{sum}(\mathrm{propDivs}(M)) = N$. Example: 1184 and 1210 are an amicable pair, with proper divisors: 1, 2, 4, 8, 16, 32, 37, 74, 148, 296, 592 and 1, 2, 5, 10, 11, 22, 55, 110, 121, 242, 605 respectively. Task: Calculate and show here the Amicable pairs below 20,000 (there are eight). Related tasks Proper divisors Abundant, deficient and perfect number classifications Aliquot sequence classifications and its amicable classification.
## Instructions
## Tests
```yml tests: - text: amicablePairsUpTo is a function. testString: 'assert(typeof amicablePairsUpTo === "function", "amicablePairsUpTo is a function.");' - text: 'amicablePairsUpTo(300) should return [[220,284]].' testString: 'assert.deepEqual(amicablePairsUpTo(300), answer300, "amicablePairsUpTo(300) should return [[220,284]].");' - text: 'amicablePairsUpTo(3000) should return [[220,284],[1184,1210],[2620,2924]].' testString: 'assert.deepEqual(amicablePairsUpTo(3000), answer3000, "amicablePairsUpTo(3000) should return [[220,284],[1184,1210],[2620,2924]].");' - text: 'amicablePairsUpTo(20000) should return [[220,284],[1184,1210],[2620,2924],[5020,5564],[6232,6368],[10744,10856],[12285,14595],[17296,18416]].' testString: 'assert.deepEqual(amicablePairsUpTo(20000), answer20000, "amicablePairsUpTo(20000) should return [[220,284],[1184,1210],[2620,2924],[5020,5564],[6232,6368],[10744,10856],[12285,14595],[17296,18416]].");' ```
## Challenge Seed
```js function amicablePairsUpTo (maxNum) { // Good luck! return true; } ```
### After Test
```js console.info('after the test'); ```
## Solution
```js // amicablePairsUpTo :: Int -> [(Int, Int)] function amicablePairsUpTo (maxNum) { return range(1, maxNum) .map(x => properDivisors(x) .reduce((a, b) => a + b, 0)) .reduce((a, m, i, lst) => { const n = i + 1; return (m > n) && lst[m - 1] === n ? a.concat([ [n, m] ]) : a; }, []); } // properDivisors :: Int -> [Int] function properDivisors (n) { if (n < 2) return []; const rRoot = Math.sqrt(n); const intRoot = Math.floor(rRoot); const blnPerfectSquare = rRoot === intRoot; const lows = range(1, intRoot) .filter(x => (n % x) === 0); return lows.concat(lows.slice(1) .map(x => n / x) .reverse() .slice(blnPerfectSquare | 0)); } // Int -> Int -> Maybe Int -> [Int] function range (m, n, step) { const d = (step || 1) * (n >= m ? 1 : -1); return Array.from({ length: Math.floor((n - m) / d) + 1 }, (_, i) => m + (i * d)); } ```