Data commit

This commit is contained in:
Ingy döt Net 2023-07-01 11:58:00 -04:00
parent 7387c8f97b
commit cb5bb5e222
199093 changed files with 3378972 additions and 0 deletions

View file

@ -0,0 +1,45 @@
// Parses the input string for the numerators and denominators
function compile(prog, numArr, denArr) {
let regex = /\s*(\d*)\s*\/\s*(\d*)\s*(.*)/m;
let result;
while (result = regex.exec(prog)) {
numArr.push(result[1]);
denArr.push(result[2]);
prog = result[3];
}
return [numArr, denArr];
}
// Outputs the result of the compile stage
function dump(numArr, denArr) {
let output = "";
for (let i in numArr) {
output += `${numArr[i]}/${denArr[i]} `;
}
return `${output}<br>`;
}
// Step
function step(val, numArr, denArr) {
let i = 0;
while (i < denArr.length && val % denArr[i] != 0) i++;
return numArr[i] * val / denArr[i];
}
// Executes Fractran
function exec(val, i, limit, numArr, denArr) {
let output = "";
while (val && i < limit) {
output += `${i}: ${val}<br>`;
val = step(val, numArr, denArr);
i++;
}
return output;
}
// Main
// Outputs to DOM (clears and writes at the body tag)
let body = document.body;
let [num, den] = compile("17/91 78/85 19/51 23/38 29/33 77/29 95/23 77/19 1/17 11/13 13/11 15/14 15/2 55/1", [], []);
body.innerHTML = dump(num, den);
body.innerHTML += exec(2, 0, 15, num, den);

View file

@ -0,0 +1,242 @@
(() => {
'use strict';
// fractran :: [Ratio Int] -> Int -> Gen [Int]
const fractran = (xs, n) => {
function* go(n) {
const p = r => 0 === v % r.d;
let
v = n,
mb = find(p, xs);
yield v
while (!mb.Nothing) {
mb = bindMay(
find(p, xs),
r => (
v = truncate({
type: 'Ratio',
n: v * r.n,
d: r.d
}),
Just(v)
)
);
mb.Just && (yield v)
}
};
return go(n);
};
// readRatios :: String -> [Ratio]
const readRatios = s =>
map(x => ratio(...map(read, splitOn('/', x))),
splitOn(',', s)
);
// main :: IO()
const main = () => {
// strRatios :: String
const strRatios = `17/91, 78/85, 19/51, 23/38, 29/33, 77/29,
95/23 , 77/19, 1/17, 11/13, 13/11, 15/14, 15/2, 55/1`;
showLog(
'First fifteen steps:',
take(15,
fractran(readRatios(strRatios), 2)
)
);
showLog(
'First five primes:',
take(5,
mapMaybeGen(
x => fmapMay(
succ,
elemIndex(
2,
takeWhileGen(
even,
iterate(n => div(n, 2), x)
)
)
),
fractran(readRatios(strRatios), 2)
)
)
);
};
// GENERIC ABSTRACTIONS ----------------------------
// 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
});
// abs :: Num -> Num
const abs = Math.abs;
// bindMay (>>=) :: Maybe a -> (a -> Maybe b) -> Maybe b
const bindMay = (mb, mf) =>
mb.Nothing ? mb : mf(mb.Just);
// div :: Int -> Int -> Int
const div = (x, y) => Math.floor(x / y);
// elemIndex :: Eq a => a -> [a] -> Maybe Int
const elemIndex = (x, xs) => {
const i = xs.indexOf(x);
return -1 === i ? (
Nothing()
) : Just(i);
};
// even :: Int -> Bool
const even = n => 0 === n % 2;
// find :: (a -> Bool) -> [a] -> Maybe a
const find = (p, xs) => {
for (let i = 0, lng = xs.length; i < lng; i++) {
if (p(xs[i])) return Just(xs[i]);
}
return Nothing();
};
// fmapMay (<$>) :: (a -> b) -> Maybe a -> Maybe b
const fmapMay = (f, mb) =>
mb.Nothing ? (
mb
) : Just(f(mb.Just));
// foldl :: (a -> b -> a) -> a -> [b] -> a
const foldl = (f, a, xs) => xs.reduce(f, a);
// gcd :: Int -> Int -> Int
const gcd = (x, y) => {
const
_gcd = (a, b) => (0 === b ? a : _gcd(b, a % b)),
abs = Math.abs;
return _gcd(abs(x), abs(y));
};
// iterate :: (a -> a) -> a -> Gen [a]
function* iterate(f, x) {
let v = x;
while (true) {
yield(v);
v = f(v);
}
}
// map :: (a -> b) -> [a] -> [b]
const map = (f, xs) => xs.map(f);
// mapMaybeGen :: (a -> Maybe b) -> Gen [a] -> [b]
function* mapMaybeGen(mf, gen) {
let v = take(1, gen);
while (0 < v.length) {
let mb = mf(v[0]);
if (!mb.Nothing) yield mb.Just
v = take(1, gen);
}
}
// properFracRatio :: Ratio -> (Int, Ratio)
const properFracRatio = nd => {
const [q, r] = Array.from(quotRem(nd.n, nd.d));
return Tuple(q, ratio(r, nd.d));
};
// quot :: Int -> Int -> Int
const quot = (n, m) => Math.floor(n / m);
// quotRem :: Int -> Int -> (Int, Int)
const quotRem = (m, n) =>
Tuple(Math.floor(m / n), m % n);
// ratio :: Int -> Int -> Ratio Int
const ratio = (n, d) =>
0 !== d ? (() => {
const g = gcd(n, d);
return {
type: 'Ratio',
'n': quot(n, g), // numerator
'd': quot(d, g) // denominator
}
})() : undefined;
// read :: Read a => String -> a
const read = JSON.parse;
// showLog :: a -> IO ()
const showLog = (...args) =>
console.log(
args
.map(JSON.stringify)
.join(' -> ')
);
// snd :: (a, b) -> b
const snd = tpl => tpl[1];
// splitOn :: [a] -> [a] -> [[a]]
// splitOn :: String -> String -> [String]
const splitOn = (pat, src) =>
src.split(pat);
// succ :: Int -> Int
const succ = x =>
1 + x;
// take :: Int -> [a] -> [a]
// take :: Int -> String -> String
const take = (n, xs) =>
xs.constructor.constructor.name !== 'GeneratorFunction' ? (
xs.slice(0, n)
) : [].concat.apply([], Array.from({
length: n
}, () => {
const x = xs.next();
return x.done ? [] : [x.value];
}));
// takeWhileGen :: (a -> Bool) -> Gen [a] -> [a]
const takeWhileGen = (p, xs) => {
const ys = [];
let
nxt = xs.next(),
v = nxt.value;
while (!nxt.done && p(v)) {
ys.push(v);
nxt = xs.next();
v = nxt.value
}
return ys;
};
// truncate :: Num -> Int
const truncate = x =>
'Ratio' === x.type ? (
properFracRatio(x)[0]
) : properFraction(x)[0];
// MAIN ---
return main();
})();