Van Eck sequence: Difference between revisions

Content added Content deleted
(→‎{{header|Haskell}}: Tidied mapAccumL version.)
(→‎{{header|JavaScript}}: mapAccumL version: tidied, updated primitives.)
Line 1,809: Line 1,809:
{{Trans|Python}}
{{Trans|Python}}
<lang javascript>(() => {
<lang javascript>(() => {
'use strict';
"use strict";


// vanEck :: Int -> [Int]
// vanEck :: Int -> [Int]
Line 1,815: Line 1,815:
// First n terms of the vanEck series.
// First n terms of the vanEck series.
[0].concat(mapAccumL(
[0].concat(mapAccumL(
([x, seen], i) => {
([x, seen]) => i => {
const
const
prev = seen[x],
prev = seen[x],
Line 1,821: Line 1,821:
i - prev
i - prev
) : 0;
) : 0;

return [
return [
[v, (seen[x] = i, seen)], v
[v, (seen[x] = i, seen)], v
];
];
}, [0, {}],
})(
[0, {}]

enumFromTo(1, n - 1)
)(
enumFromTo(1)(n - 1)
)[1]);
)[1]);



// ----------------------- TEST ------------------------
// ----------------------- TEST ------------------------
const main = () =>
const main = () =>
fTable(
fTable(
'Terms of the VanEck series:\n',
"Terms of the VanEck series:\n"
n => str(n - 10) + '-' + str(n),
)(
xs => JSON.stringify(xs.slice(-10)),
n => `${str(n - 10)}-${str(n)}`
vanEck,
)(
[10, 1000, 10000]
xs => JSON.stringify(xs.slice(-10))
)
)(
vanEck
)([10, 1000, 10000]);




Line 1,843: Line 1,848:


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



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


return `${s}\n${table}`;
// Map-accumulation is a combination of map and a catamorphism;
};
// it applies a function to each element of a list, passing an accumulating
// parameter from left to right, and returning a final value of this
// accumulator together with the new list.


// mapAccumL :: (acc -> x -> (acc, y)) -> acc -> [x] -> (acc, [y])
const mapAccumL = (f, acc, xs) =>
xs.reduce((a, x, i) => {
const pair = f(a[0], x, i);
return [pair[0], a[1].concat(pair[1])];
}, [acc, []]);


// replicate :: Int -> a -> [a]
// mapAccumL :: (acc -> x -> (acc, y)) -> acc ->
const replicate = (n, x) =>
// [x] -> (acc, [y])
Array.from({
const mapAccumL = f =>
length: n
// A tuple of an accumulation and a list
}, () => x);
// obtained by a combined map and fold,
// with accumulation from left to right.
acc => xs => [...xs].reduce(
([a, bs], x) => second(
v => bs.concat(v)
)(
f(a)(x)
),
[acc, []]
);


// second :: (a -> b) -> ((c, a) -> (c, b))
const second = f =>
// A function over a simple value lifted
// to a function over a tuple.
// f (a, b) -> (a, f(b))
([x, y]) => [x, f(y)];



// str :: a -> String
// str :: a -> String
const str = x => x.toString();
const str = x => x.toString();



// zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]
// zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]
const zipWith = (f, xs, ys) => {
const zipWith = f =>
// A list constructed by zipping with a
const
// custom function, rather than with the
lng = Math.min(xs.length, ys.length),
as = xs.slice(0, lng),
// default tuple constructor.
bs = ys.slice(0, lng);
xs => ys => xs.map(
return Array.from({
(x, i) => f(x)(ys[i])
length: lng
).slice(
}, (_, i) => f(as[i], bs[i], i));
0, Math.min(xs.length, ys.length)
};
);


// MAIN ---
// MAIN ---