-
Notifications
You must be signed in to change notification settings - Fork 0
/
utils.ts
27 lines (27 loc) · 1.12 KB
/
utils.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
export function* choose<T>(items: T[], k: number, start = 0, output = new Array<T>(k)): IterableIterator<T[]> {
if (!k) {
yield output
return
}
for (let chosen = start; chosen <= items.length - k; chosen++) {
output[output.length - k] = items[chosen]
yield* choose(items, k - 1, chosen + 1, output)
}
}
export const rand = (n: number): number => (Math.random() * n) | 0 //random number from 0 to n - 1
export const times = <A>(f: () => A, n: number): A[] => new Array<A>(n).fill(0 as any).map(f) //n items generated by f
export function transpose<A>(m: A[][]): A[][] { //assumes m is square
const {length} = m
const mT = new Array<A[]>(length)
for (let i = 0; i < length; i++) {
const mTi = new Array<A>(length)
for (let j = 0; j < length; j++) mTi[j] = m[j][i]
mT[i] = mTi
}
return mT
}
export function* zip<A, B>(iter1: Iterable<A>, iter2: Iterable<B>): Iterable<[A, B]> {
const iterator1 = iter1[Symbol.iterator](), iterator2 = iter2[Symbol.iterator]()
let item1: IteratorResult<A>, item2: IteratorResult<B>
while (!((item1 = iterator1.next()).done || (item2 = iterator2.next()).done)) yield [item1.value, item2.value]
}