Task: Sphenic numbers


C++: #include <algorithm>
#include <cassert>
#include <iomanip>
#include <iostream>
#include <vector>

std::vector<bool> prime_sieve(int limit) {
    std::vector<bool> sieve(limit, true);
    if (limit > 0)
        sieve[0] = false;
    if (limit > 1)
        sieve[1] = false;
    for (int i = 4; i < limit; i += 2)
        sieve[i] = false;
    for (int p = 3, sq = 9; sq < limit; p += 2) {
        if (sieve[p]) {
            for (int q = sq; q < limit; q += p << 1)
                sieve[q] = false;
        }
        sq += (p + 1) << 2;
    }
    return sieve;
}

std::vector<int> prime_factors(int n) {
    std::vector<int> factors;
    if (n > 1 && (n & 1) == 0) {
        factors.push_back(2);
        while ((n & 1) == 0)
            n >>= 1;
    }
    for (int p = 3; p * p <= n; p += 2) {
        if (n % p == 0) {
            factors.push_back(p);
            while (n % p == 0)
                n /= p;
        }
    }
    if (n > 1)
        factors.push_back(n);
    return factors;
}

int main() {
    const int limit = 1000000;
    const int imax = limit / 6;
    std::vector<bool> sieve = prime_sieve(imax + 1);
    std::vector<bool> sphenic(limit + 1, false);
    for (int i = 0; i <= imax; ++i) {
        if (!sieve[i])
            continue;
        int jmax = std::min(imax, limit / (i * i));
        if (jmax <= i)
            break;
        for (int j = i + 1; j <= jmax; ++j) {
            if (!sieve[j])
                continue;
            int p = i * j;
            int kmax = std::min(imax, limit / p);
            if (kmax <= j)
                break;
            for (int k = j + 1; k <= kmax; ++k) {
                if (!sieve[k])
                    continue;
                assert(p * k <= limit);
                sphenic[p * k] = true;
            }
        }
    }

    std::cout << "Sphenic numbers < 1000:\n";
    for (int i = 0, n = 0; i < 1000; ++i) {
        if (!sphenic[i])
            continue;
        ++n;
        std::cout << std::setw(3) << i << (n % 15 == 0 ? '\n' : ' ');
    }

    std::cout << "\nSphenic triplets < 10,000:\n";
    for (int i = 0, n = 0; i < 10000; ++i) {
        if (i > 1 && sphenic[i] && sphenic[i - 1] && sphenic[i - 2]) {
            ++n;
            std::cout << "(" << i - 2 << ", " << i - 1 << ", " << i << ")"
                      << (n % 3 == 0 ? '\n' : ' ');
        }
    }

    int count = 0, triplets = 0, s200000 = 0, t5000 = 0;
    for (int i = 0; i < limit; ++i) {
        if (!sphenic[i])
            continue;
        ++count;
        if (count == 200000)
            s200000 = i;
        if (i > 1 && sphenic[i - 1] && sphenic[i - 2]) {
            ++triplets;
            if (triplets == 5000)
                t5000 = i;
        }
    }

    std::cout << "\nNumber of sphenic numbers < 1,000,000: " << count << '\n';
    std::cout << "Number of sphenic triplets < 1,000,000: " << triplets << '\n';

    auto factors = prime_factors(s200000);
    assert(factors.size() == 3);
    std::cout << "The 200,000th sphenic number: " << s200000 << " = "
              << factors[0] << " * " << factors[1] << " * " << factors[2]
              << '\n';

    std::cout << "The 5,000th sphenic triplet: (" << t5000 - 2 << ", "
              << t5000 - 1 << ", " << t5000 << ")\n";
}



Go: package main

import (
    "fmt"
    "math"
    "rcu"
    "sort"
)

func main() {
    const limit = 1000000
    limit2 := int(math.Cbrt(limit)) 
    primes := rcu.Primes(limit / 6)
    pc := len(primes)
    var sphenic []int
    fmt.Println("Sphenic numbers less than 1,000:")
    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 = append(sphenic, res)
            }
        }
    }
    sort.Ints(sphenic)
    ix := sort.Search(len(sphenic), func(i int) bool { return sphenic[i] >= 1000 })
    rcu.PrintTable(sphenic[:ix], 15, 3, false)
    fmt.Println("\nSphenic triplets less than 10,000:")
    var triplets [][3]int
    for i := 0; i < len(sphenic)-2; i++ {
        s := sphenic[i]
        if sphenic[i+1] == s+1 && sphenic[i+2] == s+2 {
            triplets = append(triplets, [3]int{s, s + 1, s + 2})
        }
    }
    ix = sort.Search(len(triplets), func(i int) bool { return triplets[i][2] >= 10000 })
    for i := 0; i < ix; i++ {
        fmt.Printf("%4d ", triplets[i])
        if (i+1)%3 == 0 {
            fmt.Println()
        }
    }
    fmt.Printf("\nThere are %s sphenic numbers less than 1,000,000.\n", rcu.Commatize(len(sphenic)))
    fmt.Printf("There are %s sphenic triplets less than 1,000,000.\n", rcu.Commatize(len(triplets)))
    s := sphenic[199999]
    pf := rcu.PrimeFactors(s)
    fmt.Printf("The 200,000th sphenic number is %s (%d*%d*%d).\n", rcu.Commatize(s), pf[0], pf[1], pf[2])
    fmt.Printf("The 5,000th sphenic triplet is %v.\n.", triplets[4999])
}