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"; |
|||
// 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] |
([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 |
||
]; |
]; |
||
} |
})( |
||
⚫ | |||
)( |
|||
⚫ | |||
)[1]); |
)[1]); |
||
// ----------------------- TEST ------------------------ |
// ----------------------- TEST ------------------------ |
||
const main = () => |
const main = () => |
||
fTable( |
fTable( |
||
"Terms of the VanEck series:\n" |
|||
)( |
|||
n => `${str(n - 10)}-${str(n)}` |
|||
)( |
|||
xs => JSON.stringify(xs.slice(-10)) |
|||
) |
)( |
||
⚫ | |||
)([10, 1000, 10000]); |
|||
Line 1,843: | Line 1,848: | ||
// enumFromTo :: Int -> Int -> [Int] |
// enumFromTo :: Int -> Int -> [Int] |
||
const enumFromTo = |
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) -> |
|||
// |
// fTable :: String -> (a -> String) -> |
||
// (b -> String) -> (a -> b) -> [a] -> String |
|||
⚫ | |||
// Heading -> x display function -> |
// Heading -> x display function -> |
||
// fx display function -> |
// fx display function -> |
||
// f -> values -> tabular string |
// f -> values -> tabular string |
||
xShow => fxShow => f => xs => { |
|||
const |
|||
ys = xs.map(xShow), |
|||
⚫ | |||
⚫ | |||
table = zipWith( |
|||
a => b => `${a.padStart(w, " ")} -> ${b}` |
|||
)(ys)( |
|||
xs.map(x => fxShow(f(x))) |
|||
).join("\n"); |
|||
⚫ | |||
⚫ | |||
// 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 => |
|||
// A tuple of an accumulation and a list |
|||
// obtained by a combined map and fold, |
|||
// with accumulation from left to right. |
|||
acc => xs => [...xs].reduce( |
|||
⚫ | |||
⚫ | |||
)( |
|||
f(a)(x) |
|||
), |
|||
[acc, []] |
|||
); |
|||
⚫ | |||
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 = |
const zipWith = f => |
||
// A list constructed by zipping with a |
|||
⚫ | |||
// custom function, rather than with the |
|||
⚫ | |||
// default tuple constructor. |
|||
xs => ys => xs.map( |
|||
(x, i) => f(x)(ys[i]) |
|||
).slice( |
|||
0, Math.min(xs.length, ys.length) |
|||
); |
|||
// MAIN --- |
// MAIN --- |