mirror of
https://github.com/voltrevo/ValueScript.git
synced 2026-04-18 03:00:27 -04:00
Use statics in Range
This commit is contained in:
@@ -1,64 +1,6 @@
|
||||
import { primes } from "../projEuler/helpers/primes.ts";
|
||||
|
||||
export default function range<T>(iterable: Iterable<T>) {
|
||||
return new Range(iterable);
|
||||
}
|
||||
|
||||
// TODO: Static methods
|
||||
export function Range_from<T = never>(
|
||||
iter?: Iterable<T> | Iterator<T> | (() => Iterable<T>),
|
||||
) {
|
||||
if (iter === undefined) {
|
||||
return range([]);
|
||||
}
|
||||
|
||||
if (typeof iter === "function") {
|
||||
return range(iter());
|
||||
}
|
||||
|
||||
// TODO: `in` operator
|
||||
if (hasKey(iter, Symbol.iterator)) {
|
||||
return range(iter);
|
||||
}
|
||||
|
||||
if (hasKey(iter, "next")) {
|
||||
return Range_fromIterator(iter);
|
||||
}
|
||||
|
||||
never(iter);
|
||||
}
|
||||
|
||||
export function Range_fromIterable<T = never>(iterable: Iterable<T> = []) {
|
||||
return new Range<T>(iterable);
|
||||
}
|
||||
|
||||
export function Range_fromIterator<T = never>(iterator: Iterator<T>) {
|
||||
return new Range<T>({
|
||||
[Symbol.iterator]: () => iterator,
|
||||
});
|
||||
}
|
||||
|
||||
export function Range_numbers(start = 0, end?: number) {
|
||||
if (end === undefined) {
|
||||
return range((function* () {
|
||||
for (let i = start;; i++) {
|
||||
yield i;
|
||||
}
|
||||
})());
|
||||
}
|
||||
|
||||
return range((function* () {
|
||||
for (let i = start; i < end; i++) {
|
||||
yield i;
|
||||
}
|
||||
})());
|
||||
}
|
||||
|
||||
export function Range_primes() {
|
||||
return new Range(primes());
|
||||
}
|
||||
|
||||
export class Range<T = never> implements Iterable<T> {
|
||||
export default class Range<T = never> implements Iterable<T> {
|
||||
iterable: Iterable<T>;
|
||||
|
||||
constructor(iterable: Iterable<T>) {
|
||||
@@ -85,7 +27,7 @@ export class Range<T = never> implements Iterable<T> {
|
||||
}
|
||||
}
|
||||
|
||||
return range(res());
|
||||
return new Range(res());
|
||||
}
|
||||
|
||||
count() {
|
||||
@@ -189,7 +131,7 @@ export class Range<T = never> implements Iterable<T> {
|
||||
}
|
||||
}
|
||||
|
||||
return range(res());
|
||||
return new Range(res());
|
||||
}
|
||||
|
||||
flatMap<MappedT>(fn: (x: T) => Iterable<MappedT>) {
|
||||
@@ -203,7 +145,7 @@ export class Range<T = never> implements Iterable<T> {
|
||||
}
|
||||
}
|
||||
|
||||
return range(res());
|
||||
return new Range(res());
|
||||
}
|
||||
|
||||
flatten<U>(this: Range<Iterable<U>>) {
|
||||
@@ -217,7 +159,7 @@ export class Range<T = never> implements Iterable<T> {
|
||||
}
|
||||
}
|
||||
|
||||
return range(res());
|
||||
return new Range(res());
|
||||
}
|
||||
|
||||
filter(fn: (x: T) => boolean) {
|
||||
@@ -231,7 +173,7 @@ export class Range<T = never> implements Iterable<T> {
|
||||
}
|
||||
}
|
||||
|
||||
return range(res());
|
||||
return new Range(res());
|
||||
}
|
||||
|
||||
// TODO: Negative indexes
|
||||
@@ -275,7 +217,7 @@ export class Range<T = never> implements Iterable<T> {
|
||||
}
|
||||
}
|
||||
|
||||
return range(res());
|
||||
return new Range(res());
|
||||
}
|
||||
|
||||
append<U>(newItems: Iterable<U>) {
|
||||
@@ -286,7 +228,7 @@ export class Range<T = never> implements Iterable<T> {
|
||||
yield* newItems;
|
||||
}
|
||||
|
||||
return range(res());
|
||||
return new Range(res());
|
||||
}
|
||||
|
||||
prepend<U>(newItems: Iterable<U>) {
|
||||
@@ -297,7 +239,7 @@ export class Range<T = never> implements Iterable<T> {
|
||||
yield* iterable;
|
||||
}
|
||||
|
||||
return range(res());
|
||||
return new Range(res());
|
||||
}
|
||||
|
||||
zip<U>(other: Iterable<U>) {
|
||||
@@ -319,7 +261,7 @@ export class Range<T = never> implements Iterable<T> {
|
||||
}
|
||||
}
|
||||
|
||||
return range(res());
|
||||
return new Range(res());
|
||||
}
|
||||
|
||||
skip(n: number) {
|
||||
@@ -343,7 +285,7 @@ export class Range<T = never> implements Iterable<T> {
|
||||
}
|
||||
}
|
||||
|
||||
return range(res());
|
||||
return new Range(res());
|
||||
}
|
||||
|
||||
reduce<S>(state: S, fn: (state: S, x: T) => S) {
|
||||
@@ -367,7 +309,7 @@ export class Range<T = never> implements Iterable<T> {
|
||||
}
|
||||
}
|
||||
|
||||
return range(res());
|
||||
return new Range(res());
|
||||
}
|
||||
|
||||
window(len: number) {
|
||||
@@ -387,7 +329,7 @@ export class Range<T = never> implements Iterable<T> {
|
||||
memory.push(value);
|
||||
}
|
||||
|
||||
yield range(memory);
|
||||
yield new Range(memory);
|
||||
|
||||
let i = 0;
|
||||
|
||||
@@ -397,7 +339,7 @@ export class Range<T = never> implements Iterable<T> {
|
||||
const memoryCopy = memory;
|
||||
const iCopy = i;
|
||||
|
||||
yield range((function* () {
|
||||
yield new Range((function* () {
|
||||
for (let j = 1; j <= len; j++) {
|
||||
yield memoryCopy[(iCopy + j) % len];
|
||||
}
|
||||
@@ -408,7 +350,60 @@ export class Range<T = never> implements Iterable<T> {
|
||||
}
|
||||
}
|
||||
|
||||
return range(res());
|
||||
return new Range(res());
|
||||
}
|
||||
|
||||
static fromConversion<T = never>(
|
||||
iter?: Iterable<T> | Iterator<T> | (() => Iterable<T>),
|
||||
) {
|
||||
if (iter === undefined) {
|
||||
return new Range([]);
|
||||
}
|
||||
|
||||
if (typeof iter === "function") {
|
||||
return new Range(iter());
|
||||
}
|
||||
|
||||
// TODO: `in` operator
|
||||
if (hasKey(iter, Symbol.iterator)) {
|
||||
return new Range(iter);
|
||||
}
|
||||
|
||||
if (hasKey(iter, "next")) {
|
||||
return Range.fromIterator(iter);
|
||||
}
|
||||
|
||||
never(iter);
|
||||
}
|
||||
|
||||
static from<T = never>(iterable: Iterable<T> = []) {
|
||||
return new Range<T>(iterable);
|
||||
}
|
||||
|
||||
static fromIterator<T = never>(iterator: Iterator<T>) {
|
||||
return new Range<T>({
|
||||
[Symbol.iterator]: () => iterator,
|
||||
});
|
||||
}
|
||||
|
||||
static numbers(start = 0, end?: number) {
|
||||
if (end === undefined) {
|
||||
return new Range((function* () {
|
||||
for (let i = start;; i++) {
|
||||
yield i;
|
||||
}
|
||||
})());
|
||||
}
|
||||
|
||||
return new Range((function* () {
|
||||
for (let i = start; i < end; i++) {
|
||||
yield i;
|
||||
}
|
||||
})());
|
||||
}
|
||||
|
||||
static primes() {
|
||||
return new Range(primes());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
// test_output! [0,2,[2,3,5,7,11],[11,31,41,61,71],547]
|
||||
|
||||
import range from "../helpers/range.ts";
|
||||
import Range from "../helpers/Range.ts";
|
||||
import { primes } from "../projEuler/helpers/primes.ts";
|
||||
|
||||
export default function main() {
|
||||
return [
|
||||
range([]).count(),
|
||||
range([1, 2, 3]).limit(2).count(),
|
||||
[...range(primes()).limit(5)],
|
||||
[...range(primes()).filter((p) => p % 5 === 1).limit(5)],
|
||||
range(primes()).at(100),
|
||||
Range.from([]).count(),
|
||||
Range.from([1, 2, 3]).limit(2).count(),
|
||||
[...Range.from(primes()).limit(5)],
|
||||
[...Range.from(primes()).filter((p) => p % 5 === 1).limit(5)],
|
||||
Range.from(primes()).at(100),
|
||||
];
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
//! bench()
|
||||
|
||||
import { Range_primes } from "./helpers/range.ts";
|
||||
import Range from "./helpers/Range.ts";
|
||||
|
||||
export default function main() {
|
||||
return Range_primes().at(4999);
|
||||
return Range.primes().at(4999);
|
||||
}
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
//! test_output(233168)
|
||||
|
||||
import { Range_numbers } from "../helpers/range.ts";
|
||||
import Range from "../helpers/Range.ts";
|
||||
|
||||
export default function main() {
|
||||
return Range_numbers(0, 1000)
|
||||
return Range.numbers(0, 1000)
|
||||
.filter((x) => x % 3 === 0 || x % 5 === 0)
|
||||
.sum();
|
||||
}
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
//! test_output_slow(142913828922)
|
||||
|
||||
import { Range_primes } from "../helpers/range.ts";
|
||||
import Range from "../helpers/Range.ts";
|
||||
|
||||
export default function main() {
|
||||
return Range_primes()
|
||||
return Range.primes()
|
||||
.while((p) => p < 2_000_000)
|
||||
.sum();
|
||||
}
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
//! test_output_slow(76576500)
|
||||
|
||||
import range from "../helpers/range.ts";
|
||||
import Range from "../helpers/Range.ts";
|
||||
import { factorizeAsPowers } from "./helpers/primes.ts";
|
||||
|
||||
export default function main() {
|
||||
return range(triangularNumbers())
|
||||
return Range.from(triangularNumbers())
|
||||
.filter((tri) => countFactors(tri) > 500)
|
||||
.first();
|
||||
}
|
||||
|
||||
function countFactors(n: number): number {
|
||||
return range(factorizeAsPowers(n))
|
||||
return Range.from(factorizeAsPowers(n))
|
||||
.map(([_, power]) => power + 1)
|
||||
.product();
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//! test_output("5537376230")
|
||||
|
||||
import range from "../helpers/range.ts";
|
||||
import Range from "../helpers/Range.ts";
|
||||
|
||||
export default function main() {
|
||||
const nums = [
|
||||
@@ -106,7 +106,7 @@ export default function main() {
|
||||
53503534226472524250874054075591789781264330331690n,
|
||||
];
|
||||
|
||||
return range(nums)
|
||||
return Range.from(nums)
|
||||
.bigSum()
|
||||
.toString()
|
||||
.slice(0, 10);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
//! test_output(1366)
|
||||
|
||||
import range from "../helpers/range.ts";
|
||||
import Range from "../helpers/Range.ts";
|
||||
|
||||
export default function main() {
|
||||
return range(`${2n ** 1000n}`).map(Number).sum();
|
||||
return Range.from(`${2n ** 1000n}`).map(Number).sum();
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import range from "../helpers/range.ts";
|
||||
import Range from "../helpers/Range.ts";
|
||||
import SillyBigInt from "./helpers/SillyBigInt.ts";
|
||||
|
||||
export default function main() {
|
||||
@@ -8,7 +8,7 @@ export default function main() {
|
||||
sbi.add(sbi);
|
||||
}
|
||||
|
||||
return range(sbi.toString())
|
||||
return Range.from(sbi.toString())
|
||||
.map(Number)
|
||||
.sum();
|
||||
}
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
//! test_output_slow(21124)
|
||||
|
||||
import { Range_numbers } from "../helpers/range.ts";
|
||||
import Range from "../helpers/Range.ts";
|
||||
|
||||
export default function main() {
|
||||
return Range_numbers(1, 1001)
|
||||
return Range.numbers(1, 1001)
|
||||
.map(toWords)
|
||||
.map(countEligibleLetters)
|
||||
.sum();
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
//! test_output(4613732)
|
||||
|
||||
import range from "../helpers/range.ts";
|
||||
import Range from "../helpers/Range.ts";
|
||||
|
||||
export default function main() {
|
||||
return range(fibonacci())
|
||||
return Range.from(fibonacci())
|
||||
.while((x) => x < 4_000_000)
|
||||
.filter((x) => x % 2 === 0)
|
||||
.sum();
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
//! test_output(648)
|
||||
|
||||
import range, { Range_numbers } from "../helpers/range.ts";
|
||||
import Range from "../helpers/Range.ts";
|
||||
|
||||
export default function main() {
|
||||
const factorial100 = Range_numbers(2, 101).map(BigInt).bigProduct();
|
||||
const factorial100 = Range.numbers(2, 101).map(BigInt).bigProduct();
|
||||
|
||||
return range(`${factorial100}`).map(Number).sum();
|
||||
return Range.from(`${factorial100}`).map(Number).sum();
|
||||
}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
//! test_output_slow(31626)
|
||||
|
||||
import { Range_numbers } from "../helpers/range.ts";
|
||||
import Range from "../helpers/Range.ts";
|
||||
import { properFactorSum } from "./helpers/properFactorSum.ts";
|
||||
|
||||
export default function main() {
|
||||
return Range_numbers(2, 10_000)
|
||||
return Range.numbers(2, 10_000)
|
||||
.filter(isAmicable)
|
||||
.sum();
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//! test_output(2970)
|
||||
|
||||
import range from "../helpers/range.ts";
|
||||
import Range from "../helpers/Range.ts";
|
||||
|
||||
export default function main() {
|
||||
return nameListScore([
|
||||
@@ -20,14 +20,14 @@ export default function main() {
|
||||
function nameListScore(names: string[]) {
|
||||
names.sort();
|
||||
|
||||
return range(names)
|
||||
return Range.from(names)
|
||||
.indexed()
|
||||
.map(([i, name]) => (i + 1) * nameScore(name))
|
||||
.sum();
|
||||
}
|
||||
|
||||
function nameScore(name: string) {
|
||||
return range(name)
|
||||
return Range.from(name)
|
||||
.map((c) => c.codePointAt(0)! - "A".codePointAt(0)! + 1)
|
||||
.sum();
|
||||
}
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
//! test_output_slow(4179871)
|
||||
|
||||
import { Range_numbers } from "../helpers/range.ts";
|
||||
import Range from "../helpers/Range.ts";
|
||||
import { properFactorSum } from "./helpers/properFactorSum.ts";
|
||||
|
||||
export default function main() {
|
||||
const abundantNumbers = [
|
||||
...Range_numbers(1, 28123)
|
||||
...Range.numbers(1, 28123)
|
||||
.filter(isAbundant),
|
||||
];
|
||||
|
||||
return Range_numbers(1, 28123)
|
||||
return Range.numbers(1, 28123)
|
||||
.indexed()
|
||||
.flatMap(function* ([_i, n]) {
|
||||
// Uncomment to see progress (program takes ~50s with a release build)
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
//! test_output_slow([2,7,8,3,9,1,5,4,6,0])
|
||||
|
||||
import range from "../helpers/range.ts";
|
||||
import Range from "../helpers/Range.ts";
|
||||
|
||||
// TODO: Faster algorithm (it's not necessary to enumerate the permutations).
|
||||
|
||||
export default function main() {
|
||||
return range(permsOf([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])).at(999_999);
|
||||
return Range.from(permsOf([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])).at(999_999);
|
||||
}
|
||||
|
||||
function* permsOf(nums: number[]) {
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
//! test_output(4782)
|
||||
|
||||
import assert from "../helpers/assert.ts";
|
||||
import range from "../helpers/range.ts";
|
||||
import Range from "../helpers/Range.ts";
|
||||
|
||||
export default function main() {
|
||||
// TODO: Remove the temptation pull out this constant (optimization to eval
|
||||
// known expressions).
|
||||
const threshold = 10n ** 999n;
|
||||
|
||||
const result = range(fibonacci())
|
||||
const result = Range.from(fibonacci())
|
||||
.indexed()
|
||||
.filter(([_, x]) => x > threshold)
|
||||
.first();
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import assert from "../helpers/assert.ts";
|
||||
import range from "../helpers/range.ts";
|
||||
import Range from "../helpers/Range.ts";
|
||||
import SillyBigInt from "./helpers/SillyBigInt.ts";
|
||||
|
||||
export default function main() {
|
||||
const res = range(fibonacci())
|
||||
const res = Range.from(fibonacci())
|
||||
.indexed()
|
||||
.filter(([_, fib]) => fib.toString().length >= 1000)
|
||||
.first();
|
||||
|
||||
|
||||
assert(res !== undefined);
|
||||
|
||||
return res[0];
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//! test_output(669171001)
|
||||
|
||||
import range from "../helpers/range.ts";
|
||||
import Range from "../helpers/Range.ts";
|
||||
|
||||
// There's an analytic solution for this, but that kinda eliminates the need to
|
||||
// write code altogether. We're showcasing programming techniques here, not
|
||||
@@ -14,8 +14,8 @@ export default function () {
|
||||
[1, 7, 21],
|
||||
];
|
||||
|
||||
let sum = range(rayStarters)
|
||||
.map(([a, b, c]) => range(ray(a, b, c)).limit(501))
|
||||
let sum = Range.from(rayStarters)
|
||||
.map(([a, b, c]) => Range.from(ray(a, b, c)).limit(501))
|
||||
.flatten()
|
||||
.sum();
|
||||
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
//! test_output_slow(9183)
|
||||
|
||||
import { Range_numbers } from "../helpers/range.ts";
|
||||
import Range from "../helpers/Range.ts";
|
||||
|
||||
export default function main() {
|
||||
let nums = [];
|
||||
|
||||
for (const a of Range_numbers(2, 101)) {
|
||||
for (const b of Range_numbers(2, 101)) {
|
||||
for (const a of Range.numbers(2, 101)) {
|
||||
for (const b of Range.numbers(2, 101)) {
|
||||
nums.push(BigInt(a) ** BigInt(b));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
//! test_output_slow(443839)
|
||||
|
||||
import range, { Range_numbers } from "../helpers/range.ts";
|
||||
import Range from "../helpers/Range.ts";
|
||||
|
||||
export default function main() {
|
||||
return Range_numbers(10, 1_000_000)
|
||||
return Range.numbers(10, 1_000_000)
|
||||
.flatMap(function* (i) {
|
||||
const digitsPowSum = range(`${i}`)
|
||||
const digitsPowSum = Range.from(`${i}`)
|
||||
.map((d) => Number(d) ** 5)
|
||||
.sum();
|
||||
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
//! test_output(232792560)
|
||||
|
||||
import range, { Range_numbers } from "../helpers/range.ts";
|
||||
import Range from "../helpers/Range.ts";
|
||||
import { factorize } from "./helpers/primes.ts";
|
||||
|
||||
export default function main() {
|
||||
const factors = Range_numbers(2, 21)
|
||||
const factors = Range.numbers(2, 21)
|
||||
.map(factorize)
|
||||
.reduce([] as number[], (n, i) => lcm(n, [...i]));
|
||||
|
||||
return range(factors).product();
|
||||
return Range.from(factors).product();
|
||||
}
|
||||
|
||||
function lcm(leftFactors: number[], rightFactors: number[]): number[] {
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
//! test_output(25164150)
|
||||
|
||||
import { Range_numbers } from "../helpers/range.ts";
|
||||
import Range from "../helpers/Range.ts";
|
||||
|
||||
export default function main() {
|
||||
return squareOfSum(100) - sumOfSquares(100);
|
||||
}
|
||||
|
||||
function sumOfSquares(n: number) {
|
||||
return Range_numbers(1, n + 1).map((x) => x ** 2).sum();
|
||||
return Range.numbers(1, n + 1).map((x) => x ** 2).sum();
|
||||
}
|
||||
|
||||
function squareOfSum(n: number) {
|
||||
return Range_numbers(1, n + 1).sum() ** 2;
|
||||
return Range.numbers(1, n + 1).sum() ** 2;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
//! test_output_slow(104743)
|
||||
|
||||
import { Range_primes } from "../helpers/range.ts";
|
||||
import Range from "../helpers/Range.ts";
|
||||
|
||||
export default function main() {
|
||||
return Range_primes().at(10_000);
|
||||
return Range.primes().at(10_000);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//! test_output(23514624000)
|
||||
|
||||
import range from "../helpers/range.ts";
|
||||
import Range from "../helpers/Range.ts";
|
||||
|
||||
export default function main() {
|
||||
const digits = [
|
||||
@@ -26,7 +26,7 @@ export default function main() {
|
||||
"71636269561882670428252483600823257530420752963450",
|
||||
];
|
||||
|
||||
return range(digits)
|
||||
return Range.from(digits)
|
||||
.flatten()
|
||||
.window(13)
|
||||
.map((w) => w.map(Number).product())
|
||||
|
||||
@@ -2,11 +2,11 @@
|
||||
|
||||
import quickSort from "./helpers/quickSort.ts";
|
||||
import randish from "./helpers/randish.ts";
|
||||
import { Range_from } from "./helpers/range.ts";
|
||||
import Range from "./helpers/Range.ts";
|
||||
|
||||
export default function main() {
|
||||
let nums = [
|
||||
...Range_from(randish())
|
||||
...Range.from(randish())
|
||||
.map((x) => Math.floor(8_000 * x))
|
||||
.limit(10_000),
|
||||
];
|
||||
|
||||
@@ -2,12 +2,12 @@
|
||||
|
||||
import BinaryTree from "./helpers/BinaryTree.ts";
|
||||
import randish from "./helpers/randish.ts";
|
||||
import range from "./helpers/range.ts";
|
||||
import Range from "./helpers/Range.ts";
|
||||
|
||||
export default function main() {
|
||||
let tree = new BinaryTree<number>();
|
||||
|
||||
for (const rand of range(randish()).limit(5_000)) {
|
||||
for (const rand of Range.from(randish()).limit(5_000)) {
|
||||
tree.insert(Math.floor(4_000 * rand));
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user