September Morn Update
This commit is contained in:
parent
4e2d22a71d
commit
aac6731f2c
6856 changed files with 141342 additions and 21127 deletions
|
|
@ -1,61 +1,135 @@
|
|||
(() => {
|
||||
'use strict';
|
||||
|
||||
const main = () =>
|
||||
unlines(
|
||||
map(n => concat(zeckendorf(n)),
|
||||
enumFromTo(0, 20)
|
||||
)
|
||||
);
|
||||
|
||||
// zeckendorf :: Int -> String
|
||||
function zeckendorf(n) {
|
||||
let f = (n, x) => (n < x ? [n, 0] : [n - x, 1]);
|
||||
|
||||
return (n === 0 ? (
|
||||
[0]
|
||||
) : mapAccumL(f, n, reverse(tail(fibUntil(n))))[1])
|
||||
.join('');
|
||||
}
|
||||
|
||||
const zeckendorf = n => {
|
||||
const go = (n, x) =>
|
||||
n < x ? (
|
||||
Tuple(n, '0')
|
||||
) : Tuple(n - x, '1')
|
||||
return 0 < n ? (
|
||||
snd(mapAccumL(
|
||||
go, n,
|
||||
reverse(fibUntil(n))
|
||||
))
|
||||
) : ['0'];
|
||||
};
|
||||
|
||||
// fibUntil :: Int -> [Int]
|
||||
let fibUntil = n => {
|
||||
let xs = [];
|
||||
until(
|
||||
([a, b]) => a > n,
|
||||
([a, b]) => (xs.push(a), [b, a + b]), [1, 1]
|
||||
)
|
||||
return xs;
|
||||
}
|
||||
const fibUntil = n =>
|
||||
cons(1, takeWhile(x => n >= x,
|
||||
map(snd, iterateUntil(
|
||||
tpl => n <= fst(tpl),
|
||||
tpl => {
|
||||
const x = snd(tpl);
|
||||
return Tuple(x, x + fst(tpl));
|
||||
},
|
||||
Tuple(1, 2)
|
||||
))));
|
||||
|
||||
// GENERIC FUNCTIONS
|
||||
// GENERIC FUNCTIONS ----------------------------
|
||||
|
||||
// Tuple (,) :: a -> b -> (a, b)
|
||||
const Tuple = (a, b) => ({
|
||||
type: 'Tuple',
|
||||
'0': a,
|
||||
'1': b,
|
||||
length: 2
|
||||
});
|
||||
|
||||
// concat :: [[a]] -> [a]
|
||||
// concat :: [String] -> String
|
||||
const concat = xs =>
|
||||
0 < xs.length ? (() => {
|
||||
const unit = 'string' !== typeof xs[0] ? (
|
||||
[]
|
||||
) : '';
|
||||
return unit.concat.apply(unit, xs);
|
||||
})() : [];
|
||||
|
||||
// cons :: a -> [a] -> [a]
|
||||
const cons = (x, xs) =>
|
||||
Array.isArray(xs) ? (
|
||||
[x].concat(xs)
|
||||
) : (x + xs);
|
||||
|
||||
// enumFromTo :: Int -> Int -> [Int]
|
||||
const enumFromTo = (m, n) =>
|
||||
m <= n ? iterateUntil(
|
||||
x => n <= x,
|
||||
x => 1 + x,
|
||||
m
|
||||
) : [];
|
||||
|
||||
// fst :: (a, b) -> a
|
||||
const fst = tpl => tpl[0];
|
||||
|
||||
// iterateUntil :: (a -> Bool) -> (a -> a) -> a -> [a]
|
||||
const iterateUntil = (p, f, x) => {
|
||||
const vs = [x];
|
||||
let h = x;
|
||||
while (!p(h))(h = f(h), vs.push(h));
|
||||
return vs;
|
||||
};
|
||||
|
||||
// map :: (a -> b) -> [a] -> [b]
|
||||
const map = (f, xs) => xs.map(f);
|
||||
|
||||
// 'The mapAccumL function behaves like a combination of map and foldl;
|
||||
// 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.' (See Hoogle)
|
||||
|
||||
// mapAccumL :: (acc -> x -> (acc, y)) -> acc -> [x] -> (acc, [y])
|
||||
let mapAccumL = (f, acc, xs) => {
|
||||
return xs.reduce((a, x) => {
|
||||
let pair = f(a[0], x);
|
||||
const mapAccumL = (f, acc, xs) =>
|
||||
xs.reduce((a, x, i) => {
|
||||
const pair = f(a[0], x, i);
|
||||
return Tuple(pair[0], a[1].concat(pair[1]));
|
||||
}, Tuple(acc, []));
|
||||
|
||||
return [pair[0], a[1].concat(pair[1])];
|
||||
}, [acc, []]);
|
||||
}
|
||||
// reverse :: [a] -> [a]
|
||||
const reverse = xs =>
|
||||
'string' !== typeof xs ? (
|
||||
xs.slice(0).reverse()
|
||||
) : xs.split('').reverse().join('');
|
||||
|
||||
// snd :: (a, b) -> b
|
||||
const snd = tpl => tpl[1];
|
||||
|
||||
// tail :: [a] -> [a]
|
||||
const tail = xs => 0 < xs.length ? xs.slice(1) : [];
|
||||
|
||||
// takeWhile :: (a -> Bool) -> [a] -> [a]
|
||||
// takeWhile :: (Char -> Bool) -> String -> String
|
||||
const takeWhile = (p, xs) => {
|
||||
const lng = xs.length;
|
||||
return 0 < lng ? xs.slice(
|
||||
0,
|
||||
until(
|
||||
i => i === lng || !p(xs[i]),
|
||||
i => 1 + i,
|
||||
0
|
||||
)
|
||||
) : [];
|
||||
};
|
||||
|
||||
// unlines :: [String] -> String
|
||||
const unlines = xs => xs.join('\n');
|
||||
|
||||
// until :: (a -> Bool) -> (a -> a) -> a -> a
|
||||
let until = (p, f, x) => {
|
||||
const until = (p, f, x) => {
|
||||
let v = x;
|
||||
while (!p(v)) v = f(v);
|
||||
return v;
|
||||
}
|
||||
|
||||
// tail :: [a] -> [a]
|
||||
let tail = xs => xs.length ? xs.slice(1) : undefined;
|
||||
|
||||
// reverse :: [a] -> [a]
|
||||
let reverse = xs => xs.slice(0)
|
||||
.reverse();
|
||||
|
||||
// range :: Int -> Int -> [Int]
|
||||
let range = (m, n) =>
|
||||
Array.from({
|
||||
length: Math.floor(n - m) + 1
|
||||
}, (_, i) => m + i);
|
||||
|
||||
// TEST
|
||||
return range(0, 20)
|
||||
.map(zeckendorf)
|
||||
.join('\n')
|
||||
};
|
||||
|
||||
// MAIN ---
|
||||
return main();
|
||||
})();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue