Data commit
This commit is contained in:
parent
7387c8f97b
commit
cb5bb5e222
199093 changed files with 3378972 additions and 0 deletions
|
|
@ -0,0 +1,161 @@
|
|||
(() => {
|
||||
'use strict';
|
||||
|
||||
// main :: IO ()
|
||||
const main = () => {
|
||||
|
||||
// clockWorkTick :: Dict -> (Dict, Char)
|
||||
const clockWorkTick = wheelMap => {
|
||||
// The new configuration of the wheels, tupled with
|
||||
// a digit found by recursive descent from a single
|
||||
// click of the first wheel.
|
||||
const click = wheels => wheelName => {
|
||||
const
|
||||
wheel = wheels[wheelName] || ['?'],
|
||||
v = wheel[0];
|
||||
return bool(click)(Tuple)(isDigit(v) || '?' === v)(
|
||||
insertDict(wheelName)(
|
||||
leftRotate(wheel)
|
||||
)(wheels)
|
||||
)(v);
|
||||
};
|
||||
return click(wheelMap)('A');
|
||||
};
|
||||
|
||||
// leftRotate ::[a] -> [a]
|
||||
const leftRotate = xs =>
|
||||
// The head of the list appended
|
||||
// to the tail of of the list.
|
||||
0 < xs.length ? (
|
||||
xs.slice(1).concat(xs[0])
|
||||
) : [];
|
||||
|
||||
|
||||
// TEST -------------------------------------------
|
||||
// State of each wheel-set after 20 clicks,
|
||||
// paired with the resulting series of characters.
|
||||
|
||||
const tuple = uncurry(Tuple);
|
||||
const wheelLists = [
|
||||
[tuple('A', '123')],
|
||||
[tuple('A', '1B2'), tuple('B', '34')],
|
||||
[tuple('A', '1DD'), tuple('D', '678')],
|
||||
[tuple('A', '1BC'), tuple('B', '34'), tuple('C', '5B')]
|
||||
];
|
||||
|
||||
console.log([
|
||||
'Series and state of each wheel-set after 20 clicks:\n',
|
||||
unlines(
|
||||
map(tuples => showWheels(
|
||||
mapAccumL(
|
||||
compose(constant, clockWorkTick)
|
||||
)(dictFromList(tuples))(replicate(20)(''))
|
||||
))(wheelLists)
|
||||
),
|
||||
'\nInitial state of each wheel-set:\n',
|
||||
map(map(compose(
|
||||
JSON.stringify,
|
||||
dictFromList,
|
||||
x => [Array.from(x)]
|
||||
)))(wheelLists).join('\n')
|
||||
].join('\n'));
|
||||
};
|
||||
|
||||
// DISPLAY FORMATTING ---------------------------------
|
||||
|
||||
// showWheels :: (Dict, [Char]) -> String
|
||||
const showWheels = tpl =>
|
||||
JSON.stringify(
|
||||
Array.from(secondArrow(concat)(tpl))
|
||||
);
|
||||
|
||||
// GENERIC FUNCTIONS ----------------------------------
|
||||
|
||||
// Tuple (,) :: a -> b -> (a, b)
|
||||
const Tuple = a => b => ({
|
||||
type: 'Tuple',
|
||||
'0': a,
|
||||
'1': b,
|
||||
length: 2
|
||||
});
|
||||
|
||||
// bool :: a -> a -> Bool -> a
|
||||
const bool = f => t => p =>
|
||||
p ? t : f;
|
||||
|
||||
// compose (<<<) :: (b -> c) -> (a -> b) -> a -> c
|
||||
const compose = (...fs) =>
|
||||
x => fs.reduceRight((a, f) => f(a), x);
|
||||
|
||||
// concat :: [[a]] -> [a]
|
||||
// concat :: [String] -> String
|
||||
const concat = xs =>
|
||||
0 < xs.length ? (() => {
|
||||
const unit = 'string' !== typeof xs[0] ? (
|
||||
[]
|
||||
) : '';
|
||||
return unit.concat.apply(unit, xs);
|
||||
})() : [];
|
||||
|
||||
// constant :: a -> b -> a
|
||||
const constant = k => _ => k;
|
||||
|
||||
// dictFromList :: [(k, v)] -> Dict
|
||||
const dictFromList = kvs =>
|
||||
Object.fromEntries(kvs);
|
||||
|
||||
// secondArrow :: (a -> b) -> ((c, a) -> (c, b))
|
||||
const secondArrow = f => xy =>
|
||||
// A function over a simple value lifted
|
||||
// to a function over a tuple.
|
||||
// f (a, b) -> (a, f(b))
|
||||
Tuple(xy[0])(
|
||||
f(xy[1])
|
||||
);
|
||||
|
||||
// insertDict :: String -> a -> Dict -> Dict
|
||||
const insertDict = k => v => dct =>
|
||||
Object.assign({}, dct, {
|
||||
[k]: v
|
||||
});
|
||||
|
||||
// isDigit :: Char -> Bool
|
||||
const isDigit = c => {
|
||||
const n = c.codePointAt(0);
|
||||
return 48 <= n && 57 >= n;
|
||||
};
|
||||
|
||||
// map :: (a -> b) -> [a] -> [b]
|
||||
const map = f => xs =>
|
||||
(Array.isArray(xs) ? (
|
||||
xs
|
||||
) : xs.split('')).map(f);
|
||||
|
||||
// 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) => {
|
||||
const pair = f(a[0])(x);
|
||||
return Tuple(pair[0])(a[1].concat(pair[1]));
|
||||
}, Tuple(acc)([]));
|
||||
|
||||
// replicate :: Int -> a -> [a]
|
||||
const replicate = n => x =>
|
||||
Array.from({
|
||||
length: n
|
||||
}, () => x);
|
||||
|
||||
// uncurry :: (a -> b -> c) -> ((a, b) -> c)
|
||||
const uncurry = f =>
|
||||
(x, y) => f(x)(y);
|
||||
|
||||
// unlines :: [String] -> String
|
||||
const unlines = xs => xs.join('\n');
|
||||
|
||||
// MAIN ---
|
||||
return main();
|
||||
})();
|
||||
Loading…
Add table
Add a link
Reference in a new issue