This commit is contained in:
2025-02-02 18:50:09 +01:00
parent 978844ed75
commit 0ebad86104
3 changed files with 152 additions and 0 deletions

View File

@@ -0,0 +1,25 @@
A natural number is called k-prime if it has exactly k prime factors, counted with multiplicity. For example:
k = 2 --> 4, 6, 9, 10, 14, 15, 21, 22, ...
k = 3 --> 8, 12, 18, 20, 27, 28, 30, ...
k = 5 --> 32, 48, 72, 80, 108, 112, ...
A natural number is thus prime if and only if it is 1-prime.
Task:
Complete the function count_Kprimes (or countKprimes, count-K-primes, kPrimes) which is given parameters k, start, end (or nd) and returns an array (or a list or a string depending on the language - see "Solution" and "Sample Tests") of the k-primes between start (inclusive) and end (inclusive).
Example:
countKprimes(5, 500, 600) --> [500, 520, 552, 567, 588, 592, 594]
Notes:
The first function would have been better named: findKprimes or kPrimes :-)
In C some helper functions are given (see declarations in 'Solution').
For Go: nil slice is expected when there are no k-primes between start and end.
Second Task: puzzle (not for Shell)
Given a positive integer s, find the total number of solutions of the equation a + b + c = s, where a is 1-prime, b is 3-prime, and c is 7-prime.
Call this function puzzle(s).
Examples:
puzzle(138) --> 1 because [2 + 8 + 128] is the only solution
puzzle(143) --> 2 because [3 + 12 + 128] and [7 + 8 + 128] are the solutions

106
5kyu/k-primes/solution.ts Normal file
View File

@@ -0,0 +1,106 @@
// sieve of eratosthenes
const primesBelow = (n: number): number[] => {
const primes: number[] = [];
const isPrime: boolean[] = Array(n).fill(true);
isPrime[0] = false;
isPrime[1] = false;
for (let i = 2; i < n; i++) {
if (isPrime[i]) {
primes.push(i);
for (let j = i * i; j < n; j += i) {
isPrime[j] = false;
}
}
}
return primes;
}
// prime factorization using trial division
const primeFactors = (n: number, primesList: number[]): number[] => {
const factors: number[] = [];
const sqrtN = Math.sqrt(n);
const primes = [...primesList];
let currPrime = primes.shift() as number;
while (currPrime <= sqrtN) {
if (n % currPrime === 0) {
factors.push(currPrime);
n /= currPrime;
} else {
currPrime = primes.shift() as number;
}
}
if (n > 1) {
factors.push(n);
}
return factors;
}
const generatePrimeFactors = (upper: number): number[] => {
// this stores the number of times a number is marked as a prime factor
const factors: number[] = Array(upper + 1).fill(0);
for (let p = 2; p <= upper; p++) {
if (factors[p] === 0) {
// p is prime
// mark all multiples of p
for (let j = p; j <= upper; j += p) {
// also mark all multiples of p^2, p^3, ...
for(let k = j; k <= upper; k *= p) {
factors[k]++;
}
}
}
}
return factors;
}
// create static class which can be called a single time for a very large range
export class KPrimes {
private static limit = 10001000;
private static primeFactors = generatePrimeFactors(KPrimes.limit);
public static countKprimes(k: number, start: number, nd: number): number[] {
if(nd > KPrimes.limit) {
throw new Error(`nd: ${nd} is greater than the limit: ${KPrimes.limit}`);
}
// filter out the numbers that have k prime factors
const result = [];
for (let i = start; i <= nd; i++) {
if (KPrimes.primeFactors[i] === k) {
result.push(i);
}
}
return result;
}
}
// using modified sieve of eratosthenes
export const countKprimes = (k: number, start: number, nd: number): number[] => {
return KPrimes.countKprimes(k, start, nd);
}
export const puzzle = (s: number): number => {
const onePrimes = countKprimes(1, 0, s);
const threePrimes = countKprimes(3, 0, s);
const sevenPrimes = countKprimes(7, 0, s);
let count = 0;
onePrimes.forEach(onePrime => {
threePrimes.forEach(threePrime => {
sevenPrimes.forEach(sevenPrime => {
if (onePrime + threePrime + sevenPrime === s) {
count++;
}
});
});
});
return count;
}

21
5kyu/k-primes/tests.ts Normal file
View File

@@ -0,0 +1,21 @@
import { countKprimes, puzzle } from './solution'
import { assert, config } from "chai";
config.truncateThreshold = 0
function testing(actual: number | number[], expected: number | number[]) {
assert.deepEqual(actual, expected);
}
describe("Fixed Tests", function () {
it("Basic tests countKprimes", function () {
testing(countKprimes(2, 0, 100), [4, 6, 9, 10, 14, 15, 21, 22, 25, 26, 33, 34, 35, 38, 39, 46, 49, 51, 55, 57, 58, 62, 65, 69, 74, 77, 82, 85, 86, 87, 91, 93, 94, 95]);
testing(countKprimes(3, 0, 100), [8, 12, 18, 20, 27, 28, 30, 42, 44, 45, 50, 52, 63, 66, 68, 70, 75, 76, 78, 92, 98, 99]);
testing(countKprimes(5, 1000, 1100), [1020, 1026, 1032, 1044, 1050, 1053, 1064, 1072, 1092, 1100]);
testing(countKprimes(5, 500, 600), [500, 520, 552, 567, 588, 592, 594]);
});
it("Basic tests puzzle", function () {
testing(puzzle(138), 1);
testing(puzzle(143), 2);
});
});