Sum multiples of 3 and 5: Difference between revisions

→‎JS ES6: Tidied code, added formatting for output.
(→‎{{header|Ruby}}: use sum method)
(→‎JS ES6: Tidied code, added formatting for output.)
Line 1,827:
<lang JavaScript>(() => {
 
// Areasum35 under:: straightInt line-> Int
//const betweensum35 first= multiplen and=> last.{
// The sum of all positive multiples of
// 3 or 5 below n.
const f = sumMults(n);
return f(3) + f(5) - f(15);
};
 
 
// sumMults :: Int -> Int -> Int
const sumMults = (n, factor) => {
const// n1Area =under quot(nstraight - 1, factor);line
return// quot(factorbetween *first n1multiple *and (n1 + 1), 2);last.
}; factor => {
const n1 = quot(n - 1)(factor);
return quot(factor * n1 * (n1 + 1))(2);
};
 
// ------------------------- TEST --------------------------
// sum35 :: Int -> Int
const sum35 = n => sumMults(n, 3) + sumMults(n, 5) - sumMults(n, 15);
 
// main :: IO ()
const main = () =>
fTable('Sums for n = 10^1 thru 10^8:')(str)(str)(
sum35
)(
enumFromTo(1)(8)
.map(n => Math.pow(10, n))
);
 
 
// GENERIC ----------------------------------------------------------------
// ------------------------ GENERIC ------------------------
 
// enumFromTo :: Int -> Int -> [Int]
const enumFromTo = (m, n) =>
Array.fromn => !isNaN(m) ? ({
length: MathArray.floorfrom(n - m) + 1{
}, (_, i) => m length: 1 + i);n - m
}, (_, i) => m + i)
) : enumFromTo_(m)(n);
 
 
// quot :: Int -> Int -> Int
const quot = n =>
m => Math.floor(n / m);
 
 
// ------------------------ DISPLAY ------------------------
 
// compose (<<<) :: (b -> c) -> (a -> b) -> a -> c
const compose = (...fs) =>
// A function defined by the right-to-left
// composition of all the functions in fs.
fs.reduce(
(f, g) => x => f(g(x)),
x => x
);
 
 
// fTable :: String -> (a -> String) -> (b -> String)
// -> (a -> b) -> [a] -> String
const fTable = s =>
// Heading -> x display function ->
// fx display function ->
// f -> values -> tabular string
xShow => fxShow => f => xs => {
const
ys = xs.map(xShow),
w = Math.max(...ys.map(length));
return s + '\n' + zipWith(
a => b => a.padStart(w, ' ') + ' -> ' + b
)(ys)(
xs.map(x => fxShow(f(x)))
).join('\n');
};
 
 
// length :: [a] -> Int
const length = xs =>
// Returns Infinity over objects without finite
// length. This enables zip and zipWith to choose
// the shorter argument when one is non-finite,
// like cycle, repeat etc
'GeneratorFunction' !== xs.constructor.constructor.name ? (
xs.length
) : Infinity;
 
 
// list :: StringOrArrayLike b => b -> [a]
const list = xs =>
// xs itself, if it is an Array,
// or an Array derived from xs.
Array.isArray(xs) ? (
xs
) : Array.from(xs);
 
 
// str :: a -> String
const str = x =>
Array.isArray(x) && x.every(
v => ('string' === typeof v) && (1 === v.length)
) ? (
x.join('')
) : x.toString();
 
 
// take :: Int -> [a] -> [a]
// take :: Int -> String -> String
const take = n =>
// The first n elements of a list,
// string of characters, or stream.
xs => 'GeneratorFunction' !== xs
.constructor.constructor.name ? (
xs.slice(0, n)
) : [].concat.apply([], Array.from({
length: n
}, () => {
const x = xs.next();
return x.done ? [] : [x.value];
}));
 
// Integral a => a -> a -> a
const quot = (n, m) => Math.floor(n / m);
 
// zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]
// TEST -------------------------------------------------------------------
const zipWith = f =>
// Use of `take` and `length` here allows zipping with non-finite lists
// i.e. generators like cycle, repeat, iterate.
xs => ys => {
const n = Math.min(length(xs), length(ys));
return (([as, bs]) => Array.from({
length: n
}, (_, i) => f(as[i])(
bs[i]
)))([xs, ys].map(
compose(take(n), list)
));
};
 
// Sums for 10^1 thru 10^8---
return enumFromTomain(1, 8);
.map(n => Math.pow(10, n))
.reduce((a, x) => (
a[x.toString()] = sum35(x),
a
), {});
})();</lang>
{{Out}}
<pre>Sums for n = 10^1 thru 10^8:
<lang JavaScript>{"10":23, "100":2318, "1000":233168, "10000":23331668,
10 -> 23
"100000":2333316668, "1000000":233333166668, "10000000":23333331666668,
100 -> 2318
"100000000":2333333316666668}</lang>
1000 -> 233168
10000 -> 23331668
100000 -> 2333316668
1000000 -> 233333166668
10000000 -> 23333331666668
100000000 -> 2333333316666668</pre>
 
=={{header|jq}}==
9,655

edits