astl
Version:
AssemblyScript-STL (Standard Template Library, migrated from the C++)
57 lines (48 loc) • 1.66 kB
text/typescript
import { Vector } from "../container/Vector";
import { Comparator } from "../internal/functional/Comparator";
import { CMath } from "../internal/numeric/CMath";
import { advance, distance } from "../iterator/global";
import { sort } from "./sorting";
export function randint<T>(x: T, y: T): T
{
const value: f64 = Math.round(Math.random() * (y - x) + x);
return <T>value;
}
export function sample<InputIterator, OutputIterator>
(
first: InputIterator, last: InputIterator,
output: OutputIterator, n: usize
): OutputIterator
{
// GENERATE REMAINDERS
const step: isize = distance(first, last);
const remainders: isize[] = [];
for (let i: isize = 0; i < step; ++i)
remainders.push(i);
//----
// CONSTRUCT INDEXES
//----
const advances: Vector<isize> = new Vector();
n = CMath.min(n, step);
// PICK SAMPLE INDEXES
for (let i: isize = 0; i < <isize>n; ++i)
{
const index: isize = randint<isize>(0, <isize>remainders.length - 1);
advances.push_back(remainders.splice(<i32>index, 1)[0]);
}
sort<Vector.Iterator<isize>, Comparator<isize>>(advances.begin(), advances.end(), (x, y) => x < y);
// CHANGE INDEXES TO ADVANCES
for (let i: isize = n - 1; i >= 1; --i)
advances.set(i, advances.at(i) - advances.at(i - 1));
//----
// FILL SAMPLES
//----
for (let i: isize = 0; i < <isize>advances.size(); ++i)
{
first = advance(first, advances.at(i));
output.value = first.value;
output = output.next();
}
return output;
}