Proper divisors: Difference between revisions

Content added Content deleted
(→‎{{header|Haskell}}: Corrected the reduced definition in terms of primeFactors)
(→‎JS ES6: Updated code and output.)
Line 2,328: Line 2,328:


<lang JavaScript>(() => {
<lang JavaScript>(() => {
'use strict';


// properDivisors :: Int -> [Int]
// properDivisors :: Int -> [Int]
let properDivisors = n => {
const properDivisors = n => {
let rRoot = Math.sqrt(n),
// The integer divisors of n, excluding n itself.
const
intRoot = Math.floor(rRoot),
blnPerfectSquare = rRoot === intRoot,
rRoot = Math.sqrt(n),
intRoot = Math.floor(rRoot),
blnPerfectSquare = rRoot === intRoot,
lows = enumFromTo(1)(intRoot)
.filter(x => 0 === (n % x));

// For perfect squares, we can drop
// the head of the 'highs' list
return lows.concat(lows
.map(x => n / x)
.reverse()
.slice(blnPerfectSquare | 0)
)
.slice(0, -1); // except n itself
};


lows = range(1, intRoot)
.filter(x => (n % x) === 0);


// ------------------------TESTS-----------------------
// for perfect squares, we can drop
// the head of the 'highs' list
// main :: IO ()
const main = () =>
return lows.concat(lows
.map(x => n / x)
console.log([
.reverse()
fTable('Proper divisors of [1..10]:')(str)(
.slice(blnPerfectSquare | 0)
JSON.stringify
)(properDivisors)(
enumFromTo(1)(10)
),
'',
'Example of maximum divisor count in the range [1..20000]:',
' ' + maximumBy(comparing(snd))(
enumFromTo(1)(20000).map(
n => [n, properDivisors(n).length]
)
)
.slice(0, -1); // except n itself
).join(' has ') + ' proper divisors.'
},
].join('\n'));



// range :: Int -> Int -> [Int]
// -----------------GENERIC FUNCTIONS------------------
range = (m, n) => Array.from({

length: (n - m) + 1
// comparing :: (a -> b) -> (a -> a -> Ordering)
const comparing = f =>
x => y => {
const
a = f(x),
b = f(y);
return a < b ? -1 : (a > b ? 1 : 0);
};

// enumFromTo :: Int -> Int -> [Int]
const enumFromTo = m => n =>
Array.from({
length: 1 + n - m
}, (_, i) => m + i);
}, (_, i) => m + i);


// fTable :: String -> (a -> String) -> (b -> String)
// -> (a -> b) -> [a] -> String
const fTable = s => xShow => fxShow => f => xs => {
// Heading -> x display function ->
// fx display function ->
// f -> values -> tabular string
const
ys = xs.map(xShow),
w = Math.max(...ys.map(x => x.length));
return s + '\n' + zipWith(
a => b => a.padStart(w, ' ') + ' -> ' + b
)(ys)(
xs.map(x => fxShow(f(x)))
).join('\n');
};


// maximumBy :: (a -> a -> Ordering) -> [a] -> a
const maximumBy = f => xs =>
0 < xs.length ? (
xs.slice(1)
.reduce((a, x) => 0 < f(x)(a) ? x : a, xs[0])
) : undefined;


// snd :: (a, b) -> b
return {
const snd = tpl => tpl[1];
properDivisorsOf1to10: range(1, 10)
.reduce((a, x) => (
a[x.toString()] = properDivisors(x),
a
), {}),


// str :: a -> String
intMaxDivisorsUnder20k: range(1, 20000)
.reduce((a, x) => {
const str = x => x.toString();
let intDivisors = properDivisors(x)
.length;


return intDivisors >= a.divisors ? {
// until :: (a -> Bool) -> (a -> a) -> a -> a
max: x,
const until = p => f => x => {
divisors: intDivisors
let v = x;
} : a;
while (!p(v)) v = f(v);
return v;
};


}, {
// zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]
max: 0,
const zipWith = f => xs => ys => {
divisors: 0
const
})
lng = Math.min(xs.length, xs.length),
as = xs.slice(0, lng),
bs = ys.slice(0, lng);
return Array.from({
length: lng
}, (_, i) => f(as[i])(
bs[i]
));
};
};


// MAIN ---
return main();
})();</lang>
})();</lang>


{{Out}}
{{Out}}
<pre>Proper divisors of [1..10]:
<lang JavaScript>{
1 -> []
"properDivisorsOf1to10":{
2 -> [1]
"1":[], "2":[1], "3":[1], "4":[1, 2], "5":[1],
3 -> [1]
"6":[1, 2, 3], "7":[1], "8":[1, 2, 4], "9":[1, 3], "10":[1, 2, 5]
},
4 -> [1,2]
5 -> [1]
"intMaxDivisorsUnder20k":{"max":18480, "divisors":79}
6 -> [1,2,3]
}</lang>
7 -> [1]
8 -> [1,2,4]
9 -> [1,3]
10 -> [1,2,5]

Example of maximum divisor count in the range [1..20000]:
15120 has 79 proper divisors.</pre>


=={{header|jq}}==
=={{header|jq}}==