How to resolve the algorithm Sphenic numbers step by step in the C programming language
How to resolve the algorithm Sphenic numbers step by step in the C programming language
Table of Contents
Problem Statement
A sphenic number is a positive integer that is the product of three distinct prime numbers. More technically it's a square-free 3-almost prime (see Related tasks below). For the purposes of this task, a sphenic triplet is a group of three sphenic numbers which are consecutive. Note that sphenic quadruplets are not possible because every fourth consecutive positive integer is divisible by 4 (= 2 x 2) and its prime factors would not therefore be distinct. 30 (= 2 x 3 x 5) is a sphenic number and is also clearly the first one. [1309, 1310, 1311] is a sphenic triplet because 1309 (= 7 x 11 x 17), 1310 (= 2 x 5 x 31) and 1311 (= 3 x 19 x 23) are 3 consecutive sphenic numbers. Calculate and show here:
- All sphenic numbers less than 1,000.
- All sphenic triplets less than 10,000.
- How many sphenic numbers are there less than 1 million?
- How many sphenic triplets are there less than 1 million?
- What is the 200,000th sphenic number and its 3 prime factors?
- What is the 5,000th sphenic triplet? Hint: you only need to consider sphenic numbers less than 1 million to answer 5. and 6.
Let's start with the solution:
Step by Step solution about How to resolve the algorithm Sphenic numbers step by step in the C programming language
This C program finds and prints sphenic numbers and sphenic triplets within a given limit. A sphenic number is a positive integer that is the product of three distinct prime numbers. A sphenic triplet is a set of three consecutive sphenic numbers.
Here's a detailed explanation of the code:
-
Header Inclusions:
#include <stdio.h> #include <stdlib.h> #include <stdbool.h> #include <math.h> #include <locale.h>
These headers provide access to various C library functions and macros.
-
Sieve of Eratosthenes:
bool *sieve(int limit) { // ... }
This function implements the Sieve of Eratosthenes algorithm to identify prime numbers up to a given limit. It returns an array of Boolean values where each index represents a number, and
true
indicates a composite number (not prime), whilefalse
indicates a prime. -
Prime Factors Function:
void primeFactors(int n, int *factors, int *length) { // ... }
This function computes the prime factors of a given integer
n
and stores them in thefactors
array, along with the number of factors in thelength
parameter. -
compare
Function:int compare(const void* a, const void* b) { // ... }
This is a comparison function used by the
qsort
function for sorting arrays. It compares two integer values and returns a negative value if the first argument is less than the second, a positive value if the first argument is greater than the second, and zero if they are equal. -
main
Function:- Variables:
int limit = 1000000; int limit2 = (int)cbrt((double)limit); int pc = 0, count = 0, prod, res;
limit
defines the limit up to which sphenic numbers and triplets are found.limit2
is used for optimization.pc
counts the number of primes within the limit,count
counts the number of sphenic numbers, andprod
andres
are used for calculations. - Sieve for Sphenic Numbers:
A modified sieve is used to efficiently find sphenic numbers.bool *c = sieve(limit/6);
limit/6
is used as the limit because each sphenic number is the product of three primes, and the largest prime factor of a sphenic number cannot exceed the cubic root of the sphenic number. - Counting Primes:
The sieve result is used to count the number of primes within the limit.for (i = 0; i < limit/6; ++i) { if (!c[i]) ++pc; }
- Primes Array:
An arrayint *primes = (int *)malloc(pc * sizeof(int));
primes
is allocated to store the prime numbers. - Filling Primes Array:
Primes within the limit are stored in thefor (i = 0, j = 0; i < limit/6; ++i) { if (!c[i]) primes[j++] = i; }
primes
array. - Sphenic Numbers Array:
An arrayint *sphenic = (int *)malloc(210000 * sizeof(int));
sphenic
is allocated to store sphenic numbers. - Finding Sphenic Numbers:
Triple nested loops are used to iterate through the primes array and compute sphenic numbers:
for (i = 0; i < pc-2; ++i) { if (primes[i] > limit2) break; for (j = i+1; j < pc-1; ++j) { prod = primes[i] * primes[j]; if (prod * primes[j+1] >= limit) break; for (k = j+1; k < pc; ++k) { res = prod * primes[k]; if (res >= limit) break; sphenic[count++] = res; } } }
- Sorting Sphenic Numbers:
Theqsort(sphenic, count, sizeof(int), compare);
sphenic
array is sorted in ascending order. - Printing Sphenic Numbers Less Than 1000:
Sphenic numbers less than 1000 are printed, and newline characters are inserted after every 15 numbers.for (i = 0; ; ++i) { if (sphenic[i] >= 1000) break; // ... }
- Sphenic Triplets:
Nested loops are used to find and count sphenic triplets, and these triplets are printed if they are less than 9998.int tripCount = 0, s, t = 0; for (i = 0; i < count - 2; ++i) { // ... }
t
is set to the value of the first sphenic number in the 5000th triplet. - Printing Statistics:
The locale is set to use thousands separators, and the number of sphenic numbers and sphenic triplets less than the limit is printed.setlocale(LC_NUMERIC, ""); printf("There are %'d sphenic numbers less than 1,000,000.\n", count); printf("There are %'d sphenic triplets less than 1,000,000.\n", tripCount);
- Properties of the 200,000th Sphenic Number:
The 200,000th sphenic number is stored ins = sphenic[199999]; int factors[10], length = 0; primeFactors(s, factors, &length); // ...
s
, and its prime factors are computed and printed. - 5,000th Sphenic Triplet:
The first sphenic number in the 5000th triplet, along with its consecutive sphenic numbers, is printed.printf("The 5,000th sphenic triplet is [%d, %d, %d].\n", t, t+1, t+2);
- Cleanup:
The allocated memory for the arrays is freed.free(c); free(primes); free(sphenic);
- Variables:
Source code in the c programming language
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <math.h>
#include <locale.h>
bool *sieve(int limit) {
int i, p;
limit++;
// True denotes composite, false denotes prime.
bool *c = calloc(limit, sizeof(bool)); // all false by default
c[0] = true;
c[1] = true;
for (i = 4; i < limit; i += 2) c[i] = true;
p = 3; // Start from 3.
while (true) {
int p2 = p * p;
if (p2 >= limit) break;
for (i = p2; i < limit; i += 2 * p) c[i] = true;
while (true) {
p += 2;
if (!c[p]) break;
}
}
return c;
}
void primeFactors(int n, int *factors, int *length) {
if (n < 2) return;
int count = 0;
int inc[8] = {4, 2, 4, 2, 4, 6, 2, 6};
while (!(n%2)) {
factors[count++] = 2;
n /= 2;
}
while (!(n%3)) {
factors[count++] = 3;
n /= 3;
}
while (!(n%5)) {
factors[count++] = 5;
n /= 5;
}
for (int k = 7, i = 0; k*k <= n; ) {
if (!(n%k)) {
factors[count++] = k;
n /= k;
} else {
k += inc[i];
i = (i + 1) % 8;
}
}
if (n > 1) {
factors[count++] = n;
}
*length = count;
}
int compare(const void* a, const void* b) {
int arg1 = *(const int*)a;
int arg2 = *(const int*)b;
if (arg1 < arg2) return -1;
if (arg1 > arg2) return 1;
return 0;
}
int main() {
const int limit = 1000000;
int limit2 = (int)cbrt((double)limit);
int i, j, k, pc = 0, count = 0, prod, res;
bool *c = sieve(limit/6);
for (i = 0; i < limit/6; ++i) {
if (!c[i]) ++pc;
}
int *primes = (int *)malloc(pc * sizeof(int));
for (i = 0, j = 0; i < limit/6; ++i) {
if (!c[i]) primes[j++] = i;
}
int *sphenic = (int *)malloc(210000 * sizeof(int));
printf("Sphenic numbers less than 1,000:\n");
for (i = 0; i < pc-2; ++i) {
if (primes[i] > limit2) break;
for (j = i+1; j < pc-1; ++j) {
prod = primes[i] * primes[j];
if (prod * primes[j+1] >= limit) break;
for (k = j+1; k < pc; ++k) {
res = prod * primes[k];
if (res >= limit) break;
sphenic[count++] = res;
}
}
}
qsort(sphenic, count, sizeof(int), compare);
for (i = 0; ; ++i) {
if (sphenic[i] >= 1000) break;
printf("%3d ", sphenic[i]);
if (!((i+1) % 15)) printf("\n");
}
printf("\nSphenic triplets less than 10,000:\n");
int tripCount = 0, s, t = 0;
for (i = 0; i < count - 2; ++i) {
s = sphenic[i];
if (sphenic[i+1] == s+1 && sphenic[i+2] == s+2) {
tripCount++;
if (s < 9998) {
printf("[%d, %d, %d] ", s, s+1, s+2);
if (!(tripCount % 3)) printf("\n");
}
if (tripCount == 5000) t = s;
}
}
setlocale(LC_NUMERIC, "");
printf("\nThere are %'d sphenic numbers less than 1,000,000.\n", count);
printf("There are %'d sphenic triplets less than 1,000,000.\n", tripCount);
s = sphenic[199999];
int factors[10], length = 0;
primeFactors(s, factors, &length);
printf("The 200,000th sphenic number is %'d (", s);
for (i = 0; i < length; ++i) {
printf("%d", factors[i]);
if (i < length-1) printf("*");
}
printf(").\n");
printf("The 5,000th sphenic triplet is [%d, %d, %d].\n", t, t+1, t+2);
free(c);
free(primes);
free(sphenic);
return 0;
}
You may also check:How to resolve the algorithm Stem-and-leaf plot step by step in the Arturo programming language
You may also check:How to resolve the algorithm Arbitrary-precision integers (included) step by step in the PowerShell programming language
You may also check:How to resolve the algorithm A+B step by step in the Self programming language
You may also check:How to resolve the algorithm Top rank per group step by step in the Dyalect programming language
You may also check:How to resolve the algorithm Factorial primes step by step in the Julia programming language