|
| 1 | +import assert from 'node:assert'; |
| 2 | + |
| 3 | +import {nth} from '@iterable-iterator/select'; |
| 4 | +import {list} from '@iterable-iterator/list'; |
| 5 | +import {map} from '@iterable-iterator/map'; |
| 6 | +import {range} from '@iterable-iterator/range'; |
| 7 | +import {take} from '@iterable-iterator/slice'; |
| 8 | + |
| 9 | +import {query, gen} from '../../src/index.js'; |
| 10 | + |
| 11 | +// eslint-disable-next-line no-return-assign |
| 12 | +export const iadd = (a, b) => (a += b); |
| 13 | +export const zero = () => 1; |
| 14 | +export const one = () => 2; |
| 15 | +export const type = {zero, one, iadd}; |
| 16 | + |
| 17 | +export const zeron = () => 1n; |
| 18 | +export const onen = () => 2n; |
| 19 | +export const typen = {zero: zeron, one: onen, iadd}; |
| 20 | + |
| 21 | +export const repr = (x) => { |
| 22 | + const s = typeof x === 'bigint' ? `${x}n` : JSON.stringify(x); |
| 23 | + if (s.length <= 40) return s; |
| 24 | + return s.slice(0, 19) + '..' + s.slice(-19); |
| 25 | +}; |
| 26 | + |
| 27 | +const concat = (a, b) => a.concat(b); |
| 28 | +export const string = (x, y) => (n) => nth(gen(concat, y, x), n - 1); |
| 29 | + |
| 30 | +export const gs = function* ({a, b}, n) { |
| 31 | + if (n === 0) return; |
| 32 | + if (n === 1) { |
| 33 | + for (let i = 0; i < b.length; ++i) { |
| 34 | + yield a.length + i; |
| 35 | + } |
| 36 | + |
| 37 | + return; |
| 38 | + } |
| 39 | + |
| 40 | + const F = Array.from(take(gen(iadd, a.length, a.length + b.length), n - 1)); |
| 41 | + const Fn = F.pop(); |
| 42 | + for (const i of range(Fn)) yield query(undefined, F, i); |
| 43 | +}; |
| 44 | + |
| 45 | +export const makeSymbol = ({a, b}) => { |
| 46 | + const m = a.length; |
| 47 | + const n = b.length; |
| 48 | + const number = (i) => { |
| 49 | + assert(i >= 0); |
| 50 | + assert(i <= m + n); |
| 51 | + return i < m ? a[i] : b[i - m]; |
| 52 | + }; |
| 53 | + |
| 54 | + const mn = BigInt(m); |
| 55 | + const nn = BigInt(n); |
| 56 | + const bigint = (_in) => { |
| 57 | + assert(_in >= 0n); |
| 58 | + assert(_in <= mn + nn); |
| 59 | + const i = Number(_in); |
| 60 | + return i < m ? a[i] : b[i - m]; |
| 61 | + }; |
| 62 | + |
| 63 | + return (x) => (typeof x === 'bigint' ? bigint(x) : number(x)); |
| 64 | +}; |
| 65 | + |
| 66 | +export const fs = (alphabet, n) => |
| 67 | + list(map(makeSymbol(alphabet), gs(alphabet, n))).join(''); |
0 commit comments