--- title: Amicable pairs id: 5949b579404977fbaefcd737 challengeType: 5 forumTopicId: 302225 --- ## 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:
## Instructions
Calculate and show here the Amicable pairs below 20,000 (there are eight).
## Tests
```yml tests: - text: amicablePairsUpTo should be a function. testString: assert(typeof amicablePairsUpTo === 'function'); - text: amicablePairsUpTo(300) should return [[220,284]]. testString: assert.deepEqual(amicablePairsUpTo(300), answer300); - text: amicablePairsUpTo(3000) should return [[220,284],[1184,1210],[2620,2924]]. testString: assert.deepEqual(amicablePairsUpTo(3000), answer3000); - 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); ```
## Challenge Seed
```js function amicablePairsUpTo(maxNum) { return true; } ```
### After Test
```js const answer300 = [[220, 284]]; const answer3000 = [ [220, 284], [1184, 1210], [2620, 2924] ]; const answer20000 = [ [220, 284], [1184, 1210], [2620, 2924], [5020, 5564], [6232, 6368], [10744, 10856], [12285, 14595], [17296, 18416] ]; ```
## 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)); } ```