Jump to content

Forward difference: Difference between revisions

→‎JS ES6: Updated primitives, refactored main.
(→‎JS ES6: Updated primitives, refactored main.)
Line 1,398:
'use strict';
 
// forwardDifference :: Num a => [Inta] -> [Inta]
const forwardDifference = (n, xs) => {
const fd = xs => zipWith(subtract)(a, bxs) => a - b, (tail(xs), xs);
return until(
m => m.index < 1,
m => ({
index: m.index - 1,
list: fd(m.list)
}), {
index: n,
list: xs
}
)
.list;
};
 
 
// nthForwardDifference :: Num a => Int -> [a] -> [a]
// GENERIC FUNCTIONS ---------------------------------------
const nthForwardDifference = xs =>
index(iterate(forwardDifference)(xs)).Just;
 
// zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]
const zipWith = (f, xs, ys) => {
const ny = ys.length;
return (xs.length <= ny ? xs : xs.slice(0, ny))
.map((x, i) => f(x, ys[i]));
};
 
//----------------------- TEST ------------------------
// until :: (a -> Bool) -> (a -> a) -> a -> a
const// untilmain =:: IO (p, f, x) => {
const gomain = x() => p(x) ? x : go(f(x));
return gounlines(x);
take(10)(
iterate(forwardDifference)(
[90, 47, 58, 29, 22, 32, 55, 5, 55, 73]
)
).map((x, i) => justifyRight(2)('x')(i) + (
' -> '
) + JSON.stringify(x))
);
 
 
//----------------- GENERIC FUNCTIONS -----------------
 
// Just :: a -> Maybe a
const Just = x => ({
type: 'Maybe',
Nothing: false,
Just: x
});
 
 
// Nothing :: Maybe a
const Nothing = () => ({
type: 'Maybe',
Nothing: true,
});
 
 
// Tuple (,) :: a -> b -> (a, b)
const Tuple = a =>
b => ({
type: 'Tuple',
'0': a,
'1': b,
length: 2
});
 
 
// index (!!) :: [a] -> Int -> Maybe a
// index (!!) :: Generator (Int, a) -> Int -> Maybe a
// index (!!) :: String -> Int -> Maybe Char
const index = xs => i => {
const s = xs.constructor.constructor.name;
return 'GeneratorFunction' !== s ? (() => {
const v = xs[i];
return undefined !== v ? Just(v) : Nothing();
})() : Just(take(i)(xs), xs.next().value);
};
 
 
// iterate :: (a -> a) -> a -> Gen [a]
const iterate = f =>
function*(x) {
let v = x;
while (true) {
yield(v);
v = f(v);
}
};
 
// justifyRight :: Int -> Char -> String -> String
const justifyRight = n =>
// The string s, preceded by enough padding (with
// the character c) to reach the string length n.
c => s => n > s.length ? (
s.padStart(n, c)
) : s;
 
// 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
(Array.isArray(xs) || 'string' === typeof xs) ? (
xs.length
) : Infinity;
 
 
// map :: (a -> b) -> [a] -> [b]
const map = f =>
// The list obtained by applying f
// to each element of xs.
// (The image of xs under f).
xs => (
Array.isArray(xs) ? (
xs
) : xs.split('')
).map(f);
 
 
// subtract :: Num -> Num -> Num
const subtract = x =>
y => y - x;
 
 
// tail :: [a] -> [a]
const tail = xs => xs.length ? xs.slice(1) : undefined;
// A new list consisting of all
// items of xs except the first.
0 < xs.length ? xs.slice(1) : [];
 
 
// take :: Int -> [a] -> [a]
// TEST ----------------------------------------------------
// 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];
}));
 
// range :: Int -> Int -> [Int]
const range = (m, n) =>
Array.from({
length: Math.floor(n - m) + 1
}, (_, i) => m + i);
 
// showunlines :: a[String] -> String
const showunlines = xxs => JSON.stringify(x);
// A single string formed by the intercalation
// of a list of strings with the newline character.
xs.join('\n');
 
// Sample
const test = [90, 47, 58, 29, 22, 32, 55, 5, 55, 73];
 
// zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]
return range(1, 9)
const zipWith = f => xs => ys => {
.map(x => `${x} ${show(forwardDifference(x, test))}`)
.join('\n');const
lng = Math.min(length(xs), length(ys)),
[as, bs] = [xs, ys].map(take(lng));
return Array.from({
length: lng
}, (_, i) => f(as[i])(
bs[i]
));
};
 
// MAIN ---
return main();
})();</lang>
 
{{Out}}
<pre>1 0 -> [-4390,1147,58,-29,-722,1032,2355,-505,5055,1873]
2 1 -> [54-43,11,-4029,22-7,1710,1323,-7350,10050,-3218]
3 2 -> [54,-9440,6222,-517,-413,-8673,173100,-13232]
4 3 -> [156-94,62,-675,1-4,-8286,259173,-305132]
5 4 -> [156,-22367,681,-8382,341259,-564305]
6 5 -> [291-223,68,-15183,424341,-905564]
7 6 -> [291,-442151,575424,-1329905]
8 7 -> [1017-442,575,-19041329]
8 -> [1017,-1904]
9 [-2921]</pre>
9 -> [-2921]</pre>
 
=={{header|jq}}==
9,655

edits

Cookies help us deliver our services. By using our services, you agree to our use of cookies.