diff --git a/inputs/passing/projEuler/helpers/primes.ts b/inputs/passing/projEuler/helpers/primes.ts index 718a915..41c1dcb 100644 --- a/inputs/passing/projEuler/helpers/primes.ts +++ b/inputs/passing/projEuler/helpers/primes.ts @@ -1,159 +1,81 @@ -export function factorize(n: number): number[] { - let factors: number[] = []; - let p = 2; +export function* factorize(n: number) { + for (const p of primes()) { + if (p * p > n) { + yield n; + return; + } - while (true) { while (n % p === 0) { - factors.push(p); + yield p; n /= p; } if (n === 1) { - return factors; - } - - p = nextOddPrime(p); - - if (p * p > n) { - factors.push(n); - return factors; + return; } } } -export function factorizeAsPowers(n: number): [number, number][] { - const factors = factorize(n); +export function* factorizeAsPowers(n: number): Generator<[number, number]> { + let factors = factorize(n); - if (factors.length === 0) { - return []; + let currentFactor = factors.next().value; + + if (currentFactor === undefined) { + return; } - const result: [number, number][] = []; - let currentFactor = factors[0]; let currentPower = 1; - for (let i = 1; i < factors.length; i++) { - const factor = factors[i]; - + for (const factor of factors) { if (factor === currentFactor) { currentPower += 1; } else { - result.push([currentFactor, currentPower]); + yield [currentFactor, currentPower]; currentFactor = factor; currentPower = 1; } } - result.push([currentFactor, currentPower]); - - return result; + yield [currentFactor, currentPower]; } -export function nextOddPrime(n: number): number { - n += 1 + (n % 2); // Next odd number +export function* primes() { + yield 2; + yield 3; + yield 5; + yield 7; + yield 11; + yield 13; + yield 17; + yield 19; + yield 23; + yield 29; - while (!isOddPrime(n)) { - n += 2; - } + let base = 30; + let offsets = [1, 7, 11, 13, 17, 19, 23, 29]; - return n; -} - -export function isOddPrime(n: number): boolean { - let i = 3; - - while (i * i <= n) { - if (n % i === 0) { - return false; - } - - i += 2; - } - - return true; -} - -export class PrimeGenerator { - pcg: PrimeCandidatesGenerator; - - constructor() { - this.pcg = new PrimeCandidatesGenerator(); - } - - next() { - while (true) { - const candidate = this.pcg.next(); + while (true) { + for (const offset of offsets) { + let candidate = base + offset; if (isPrime(candidate)) { - return candidate; + yield candidate; } } + + base += 30; } } export function isPrime(n: number) { - let pcg = new PrimeCandidatesGenerator(); - - while (true) { - const pc = pcg.next(); - - if (pc * pc > n) { + for (const p of primes()) { + if (p * p > n) { return true; } - if (n % pc === 0) { + if (n % p === 0) { return false; } } } - -export class PrimeCandidatesGenerator { - gen: Gen235 | GenMod30; - - constructor() { - this.gen = new Gen235(); - } - - next() { - let c = this.gen.next(); - - if (c !== undefined) { - return c; - } - - this.gen = new GenMod30(); - return this.gen.next(); - } -} - -class Gen235 { - nums: number[]; - i: number; - - constructor() { - this.nums = [2, 3, 5]; - this.i = 0; - } - - next() { - return this.nums[this.i++]; - } -} - -class GenMod30 { - nums: number[]; - i: number; - - constructor() { - this.nums = [1, 7, 11, 13, 17, 19, 23, 29]; - this.i = 1; - } - - next() { - const rem = this.i % 8; - const rounds = (this.i - rem) / 8; - this.i++; - - return 30 * rounds + this.nums[rem]; - } -} diff --git a/inputs/passing/projEuler/helpers/properFactorSum.ts b/inputs/passing/projEuler/helpers/properFactorSum.ts index 5213bac..3cb0f30 100644 --- a/inputs/passing/projEuler/helpers/properFactorSum.ts +++ b/inputs/passing/projEuler/helpers/properFactorSum.ts @@ -2,7 +2,7 @@ import { factorizeAsPowers } from "./primes.ts"; export function properFactorSum(n: number) { const factors = factorizeAsPowers(n); - return 1 + factorSumMinus1(factors) - n; + return 1 + factorSumMinus1([...factors]) - n; } function factorSumMinus1(factors: [number, number][]): number { diff --git a/inputs/passing/projEuler/p10.ts b/inputs/passing/projEuler/p10.ts index 3f3d9bd..8c3e97c 100644 --- a/inputs/passing/projEuler/p10.ts +++ b/inputs/passing/projEuler/p10.ts @@ -1,12 +1,9 @@ -import { PrimeGenerator } from "./helpers/primes.ts"; +import { primes } from "./helpers/primes.ts"; export default function main() { let sum = 0; - let gen = new PrimeGenerator(); - - while (true) { - const p = gen.next(); + for (const p of primes()) { if (p >= 2000000) { return sum; } diff --git a/inputs/passing/projEuler/p12.ts b/inputs/passing/projEuler/p12.ts index 3241f92..7d602f0 100644 --- a/inputs/passing/projEuler/p12.ts +++ b/inputs/passing/projEuler/p12.ts @@ -18,15 +18,11 @@ export default function main() { } function countFactors(n: number): number { - const primeFactors = factorize(n); - let count = 1; let power = 0; let prevFactor = 0; - for (let i = 0; i <= primeFactors.length; i++) { - const factor = primeFactors[i]; - + for (const factor of factorize(n)) { if (factor !== prevFactor) { count *= power + 1; power = 1; diff --git a/inputs/passing/projEuler/p3.ts b/inputs/passing/projEuler/p3.ts index f77e13b..88ae90b 100644 --- a/inputs/passing/projEuler/p3.ts +++ b/inputs/passing/projEuler/p3.ts @@ -3,5 +3,5 @@ import { factorize } from "./helpers/primes.ts"; export default function main() { - return factorize(600851475143); + return [...factorize(600851475143)]; } diff --git a/inputs/passing/projEuler/p5.ts b/inputs/passing/projEuler/p5.ts index cd9fe44..c0f2b5b 100644 --- a/inputs/passing/projEuler/p5.ts +++ b/inputs/passing/projEuler/p5.ts @@ -10,7 +10,7 @@ export default function main() { let n: number[] = []; for (let i = 2; i <= 20; i++) { - n = lcm(n, factorize(i)); + n = lcm(n, [...factorize(i)]); } return n.reduce((a, b) => a * b); diff --git a/inputs/passing/projEuler/p7.ts b/inputs/passing/projEuler/p7.ts index 2f3d641..8c3db81 100644 --- a/inputs/passing/projEuler/p7.ts +++ b/inputs/passing/projEuler/p7.ts @@ -1,13 +1,13 @@ -import { nextOddPrime } from "./helpers/primes.ts"; +import { primes } from "./helpers/primes.ts"; export default function main() { let i = 1; - let p = 2; - while (i < 10001) { - p = nextOddPrime(p); + for (const p of primes()) { + if (i === 10000) { + return p; + } + i++; } - - return p; } diff --git a/tsconfig.json b/tsconfig.json index 485aa03..fd255c2 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -11,7 +11,7 @@ // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ /* Language and Environment */ - "target": "es2022", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ + "target": "ESNext", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ // "jsx": "preserve", /* Specify what JSX code is generated. */ // "experimentalDecorators": true, /* Enable experimental support for TC39 stage 2 draft decorators. */ @@ -24,7 +24,7 @@ // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */ /* Modules */ - "module": "commonjs", /* Specify what module code is generated. */ + "module": "ESNext", /* Specify what module code is generated. */ // "rootDir": "./", /* Specify the root folder within your source files. */ // "moduleResolution": "node", /* Specify how TypeScript looks up a file from a given module specifier. */ // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ @@ -69,12 +69,12 @@ /* Interop Constraints */ // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */ // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */ - "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables `allowSyntheticDefaultImports` for type compatibility. */ + "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables `allowSyntheticDefaultImports` for type compatibility. */ // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ - "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */ + "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */ /* Type Checking */ - "strict": true, /* Enable all strict type-checking options. */ + "strict": true, /* Enable all strict type-checking options. */ // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied `any` type.. */ // "strictNullChecks": true, /* When type checking, take into account `null` and `undefined`. */ // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ @@ -96,6 +96,10 @@ /* Completeness */ // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ - "skipLibCheck": true /* Skip type checking all .d.ts files. */ - } + "skipLibCheck": true, /* Skip type checking all .d.ts files. */ + + "noEmit": true, + "allowImportingTsExtensions": true + }, + "exclude": ["./website", "./valuescript-npm"] }