Task: Ormiston triples


C++: #include <array>
#include <iostream>

#include <primesieve.hpp>

class ormiston_triple_generator {
public:
    ormiston_triple_generator() {
        for (int i = 0; i < 2; ++i) {
            primes_[i] = pi_.next_prime();
            digits_[i] = get_digits(primes_[i]);
        }
    }
    std::array<uint64_t, 3> next_triple() {
        for (;;) {
            uint64_t prime = pi_.next_prime();
            auto digits = get_digits(prime);
            bool is_triple = digits == digits_[0] && digits == digits_[1];
            uint64_t prime0 = primes_[0];
            primes_[0] = primes_[1];
            primes_[1] = prime;
            digits_[0] = digits_[1];
            digits_[1] = digits;
            if (is_triple)
                return {prime0, primes_[0], primes_[1]};
        }
    }

private:
    static std::array<int, 10> get_digits(uint64_t n) {
        std::array<int, 10> result = {};
        for (; n > 0; n /= 10)
            ++result[n % 10];
        return result;
    }
    primesieve::iterator pi_;
    std::array<uint64_t, 2> primes_;
    std::array<std::array<int, 10>, 2> digits_;
};

int main() {
    ormiston_triple_generator generator;
    int count = 0;
    std::cout << "Smallest members of first 25 Ormiston triples:\n";
    for (; count < 25; ++count) {
        auto primes = generator.next_triple();
        std::cout << primes[0] << ((count + 1) % 5 == 0 ? '\n' : ' ');
    }
    std::cout << '\n';
    for (uint64_t limit = 1000000000; limit <= 10000000000; ++count) {
        auto primes = generator.next_triple();
        if (primes[2] > limit) {
            std::cout << "Number of Ormiston triples < " << limit << ": "
                      << count << '\n';
            limit *= 10;
        }
    }
}



Go: package main

import (
    "fmt"
    "rcu"
)

func main() {
    const limit = 1e10
    primes := rcu.Primes(limit)
    var orm25 []int
    j := int(1e9)
    count := 0
    var counts []int
    for i := 0; i < len(primes)-2; i++ {
        p1 := primes[i]
        p2 := primes[i+1]
        p3 := primes[i+2]
        if (p2-p1)%18 != 0 || (p3-p2)%18 != 0 {
            continue
        }
        key1 := 1
        for _, dig := range rcu.Digits(p1, 10) {
            key1 *= primes[dig]
        }
        key2 := 1
        for _, dig := range rcu.Digits(p2, 10) {
            key2 *= primes[dig]
        }
        if key1 != key2 {
            continue
        }
        key3 := 1
        for _, dig := range rcu.Digits(p3, 10) {
            key3 *= primes[dig]
        }
        if key2 == key3 {
            if count < 25 {
                orm25 = append(orm25, p1)
            }
            if p1 >= j {
                counts = append(counts, count)
                j *= 10
            }
            count++
        }
    }
    counts = append(counts, count)
    fmt.Println("Smallest members of first 25 Ormiston triples:")
    for i := 0; i < 25; i++ {
        fmt.Printf("%8v ", orm25[i])
        if (i+1)%5 == 0 {
            fmt.Println()
        }
    }
    fmt.Println()
    j = int(1e9)
    for i := 0; i < len(counts); i++ {
        fmt.Printf("%s Ormiston triples before %s\n", rcu.Commatize(counts[i]), rcu.Commatize(j))
        j *= 10
        fmt.Println()
    }
}