Skip to content

Instantly share code, notes, and snippets.

@duangsuse
Created November 11, 2019 09:38
Show Gist options
  • Save duangsuse/05377a33d39fa9309abc8835a59f5b02 to your computer and use it in GitHub Desktop.
Save duangsuse/05377a33d39fa9309abc8835a59f5b02 to your computer and use it in GitHub Desktop.
https://t.me/dsuse/11648 Draft typescript library
//export { fst, snd, identity };
//export { show, read };
const
fst = <T0, T1> (xs: [T0, T1]) => xs[0],
snd = <T0, T1> (xs: [T0, T1]) => xs[1],
identity = <T> (x: T) => x;
class Stream<T> {
seq: ArrayLike<T>; position: number
constructor(seq: Array<T>) {
this.seq = seq;
this.position = 0;
}
hasNext() { return this.position != this.seq.length; }
next() { return this.seq[this.position++]; }
iterator() { return () => {
var hasNext = this.hasNext();
return { value: hasNext? this.next() : undefined, done: hasNext };
};}
forEach(f: (x: T) => void) {
while (this.hasNext())
f(this.next());
}
emptySeq(): any[] { return []; }
wrapNew<T>(seq: T[]) { return new Stream(seq); }
map<R>(f: (x: T) => R): Stream<R> {
var mapped = this.emptySeq();
this.forEach(x => mapped.push(f(x)));
return this.wrapNew(mapped);
}
filter(p: (x: T) => boolean) {
var filtered = this.emptySeq();
this.forEach(x => {
if (p(x)) filtered.push(x);
});
return this.wrapNew(filtered);
}
first(p: (x0: T) => boolean) {
while (this.hasNext()) {
var x = this.next();
if (p(x)) return x;
}
return null;
}
takeWhile(p: (x0: T) => boolean) {
var taken = this.emptySeq();
while (this.hasNext()) {
let x = this.next()
if (!p(x)) break;
taken.push(x);
}
return this.wrapNew(taken);
}
zipWith<U, R>(f: (x: T, y: U) => R) { return (ys: Stream<U>): Stream<R> => {
var zipped = this.emptySeq();
while (this.hasNext() && ys.hasNext()) {
zipped.push(f(this.next(), ys.next()));
}
return this.wrapNew(zipped);
};}
collect() { return this.map(identity); }
fold<AC>(initial: AC, op: (ac: AC, x: T) => AC): AC {
var accumlated = initial;
this.forEach(x => { accumlated = op(accumlated, x); });
return accumlated;
}
}
class Sort<T> {
project: (x: T) => number
constructor(f: (x: T) => number) { this.project = f; }
ascending(xs: Array<T>) {
return xs.sort((a, b) => this.project(a) - this.project(b));
}
descending(xs: Array<T>) {
return xs.sort((a, b) => this.project(b) - this.project(a));
}
}
// [百, 100], [千, 1000], ...
function preetyUnits(units: Array<[string, number]>) {
var unitsDsc = new Sort<[string, number]>(snd).descending(units);
const simple_fmt = (r, u) => r.toString() + fst(u);
return function preetyShow<R>(n, fmt: (r: number, u: [string, number]) => R = simple_fmt) {
var unit = new Stream(unitsDsc).first(x => snd(x) <= n);
return fmt(n / snd(unit), unit);
};
}
const _cp0 = '0'.charCodeAt(0);
function toDigit(i) {
return String.fromCharCode(_cp0 + i);
}
function fromDigit(c) {
return c.charCodeAt(0) - (_cp0);
}
function show(base, n, to=toDigit) {
var buffer = [];
var sign = (n < 0)? '-' : '';
while (n != 0) {
var digi = n % base; n /= base;
buffer.push(digi);
}
return sign + buffer.reverse().map(to).join('');
}
function read(base, nrep, from=fromDigit) {
return new Stream(nrep).fold(0, (ac, x) => ac*base + from(x));
}
const han: string[] = "零一二三四五六七八九十".split(' ');
function digitToHan(i) { return han[i]; }
function digitFromHan(c) { return han.indexOf(c); }
const units: [string, number][] = [
['', 1],
['十', 10],
['百', 100],
['千', 1000],
['万', 10000],
['十万', 100000],
['百万', 1000000],
['千万', 10000000],
['亿', 100000000],
];
const np = preetyUnits(units);
// 一十 一十五 二十三 一千二百三十
function hanShow(n) {
let [fp, [name, part0u]] = np(n, (r, u) => [r, u]);
let cnt = Math.floor(fp);
return hanShow(n - cnt*part0u) + digitToHan(cnt) + name;
}
function hanRead(nrep) {
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment