Testing the Waters with Semiprime Numbers... thanks to this LinkedIn Post bringing them to my awereness.
import std.stdio: writeln, writefln;
import std.range;
import std.algorithm;
/// OEIS coding as a naming convention
/// Refer to https://oeis.org/A001358
/// Semiprimes (or biprimes): products of two primes.
bool isA001358(ulong n) pure nothrow @safe {
if (n < 4)
return false;
ulong factorCount = 0;
for (ulong i = 2; i * i <= n && factorCount < 3; ++i) {
while (n % i == 0) {
++factorCount;
n /= i;
}
}
if (n > 1)
++factorCount;
return factorCount == 2;
}
void main() {
const N = 100uL;
auto immutable semiprimes = iota(N+1).filter!isA001358.array;
writeln;
semiprimes.writeln;
writefln("\nSum of the 1st %s semiprime = %d", N, semiprimes.sum);
}
[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]
Sum of the 1st 100 semiprime = 1707
import std.stdio: writefln;
import std.datetime.stopwatch: StopWatch;
import std.algorithm: all, filter, until;
import std.range: iota;
import std.array: Appender, array;
import std.algorithm: sort;
import std.algorithm.iteration;
auto generate_sp(ulong limit) {
auto isPrime = (ulong number) => number >= 2 && iota(2, number).until!(x => x * x > number).all!(x => (number % x) != 0);
auto primes = (iota(limit).filter!isPrime).array;
Appender!(ulong[]) semiprimes;
foreach (p1; primes) {
if (p1 * p1 > limit) {
// Limit exceeded
break;
}
foreach (p2; primes) {
auto semiprime = p1 * p2;
if (semiprime <= limit) {
semiprimes ~= semiprime;
} else {
// Limit exceeded
break;
}
}
}
return semiprimes.data.sort.uniq;
}
void main() {
StopWatch timer;
timer.start();
const LIMIT = 100uL;
auto semiprimes = generate_sp(LIMIT);
auto sumOfSp = semiprimes.sum;
writefln("\nSum of the 1st. %,3?d semiprimes: %,3?d", '_', LIMIT, '_', sumOfSp);
timer.stop();
writefln("Elapsed time: %s milliseconds.\n", timer.peek.total!"msecs"());
}
[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]
Sum of the 1st. 100 semiprimes: 1_707
Elapsed time: 7 milliseconds.
When tackling number theory problems and developing algorithms, I occasionally employ Pari GP, a lightweight computer algebra system. I came up with the following:
generate_sp(limit) = {
my(semiprimes);
semiprimes = [];
forprime(p1=2, limit, forprime(p2=2, limit, semiprime = p1 * p2; if (semiprime <= limit, semiprimes = concat(semiprimes, semiprime))));
semiprimes = Set(semiprimes);
semiprimes = Vec(semiprimes);
semiprimes = vecsort(semiprimes);
semiprimes
}
Simple session example:
(10:24) gp > generate_sp(100)
%2 = [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]
(10:29) gp > vecsum(%2)
%3 = 1707
(10:29) gp >