How to resolve the algorithm Sphenic numbers step by step in the C programming language

Published on 7 June 2024 03:52 AM
#C

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:

  1. All sphenic numbers less than 1,000.
  2. All sphenic triplets less than 10,000.
  3. How many sphenic numbers are there less than 1 million?
  4. How many sphenic triplets are there less than 1 million?
  5. What is the 200,000th sphenic number and its 3 prime factors?
  6. 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:

  1. 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.

  2. 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), while false indicates a prime.

  3. 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 the factors array, along with the number of factors in the length parameter.

  4. 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.

  5. 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, and prod and res are used for calculations.
    • Sieve for Sphenic Numbers:
      bool *c = sieve(limit/6);
      A modified sieve is used to efficiently find sphenic numbers. 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:
      for (i = 0; i < limit/6; ++i) {
         if (!c[i]) ++pc;
      }
      The sieve result is used to count the number of primes within the limit.
    • Primes Array:
      int *primes = (int *)malloc(pc * sizeof(int));
      An array primes is allocated to store the prime numbers.
    • Filling Primes Array:
      for (i = 0, j = 0; i < limit/6; ++i) {
         if (!c[i]) primes[j++] = i;
      }
      Primes within the limit are stored in the primes array.
    • Sphenic Numbers Array:
      int *sphenic = (int *)malloc(210000 * sizeof(int));
      An array 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:
      qsort(sphenic, count, sizeof(int), compare);
      The sphenic array is sorted in ascending order.
    • Printing Sphenic Numbers Less Than 1000:
      for (i = 0; ; ++i) {
         if (sphenic[i] >= 1000) break;
         // ...
      }
      Sphenic numbers less than 1000 are printed, and newline characters are inserted after every 15 numbers.
    • Sphenic Triplets:
      int tripCount = 0, s, t = 0;
      for (i = 0; i < count - 2; ++i) {
         // ...
      }
      Nested loops are used to find and count sphenic triplets, and these triplets are printed if they are less than 9998. t is set to the value of the first sphenic number in the 5000th triplet.
    • Printing Statistics:
      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);
      The locale is set to use thousands separators, and the number of sphenic numbers and sphenic triplets less than the limit is printed.
    • Properties of the 200,000th Sphenic Number:
      s = sphenic[199999];
      int factors[10], length = 0;
      primeFactors(s, factors, &length);
      // ...
      The 200,000th sphenic number is stored in s, and its prime factors are computed and printed.
    • 5,000th Sphenic Triplet:
      printf("The 5,000th sphenic triplet is [%d, %d, %d].\n", t, t+1, t+2);
      The first sphenic number in the 5000th triplet, along with its consecutive sphenic numbers, is printed.
    • Cleanup:
      free(c);
      free(primes);
      free(sphenic);
      The allocated memory for the arrays is freed.

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