Task: Unprimeable numbers


C++: #include <iostream>
#include <cstdint>
#include "prime_sieve.hpp"

typedef uint32_t integer;


int count_digits(integer n) {
    int digits = 0;
    for (; n > 0; ++digits)
        n /= 10;
    return digits;
}


integer change_digit(integer n, int index, int new_digit) {
    integer p = 1;
    integer changed = 0;
    for (; index > 0; p *= 10, n /= 10, --index)
        changed += p * (n % 10);
    changed += (10 * (n/10) + new_digit) * p;
    return changed;
}


bool unprimeable(const prime_sieve& sieve, integer n) {
    if (sieve.is_prime(n))
        return false;
    int d = count_digits(n);
    for (int i = 0; i < d; ++i) {
        for (int j = 0; j <= 9; ++j) {
            integer m = change_digit(n, i, j);
            if (m != n && sieve.is_prime(m))
                return false;
        }
    }
    return true;
}

int main() {
    const integer limit = 10000000;
    prime_sieve sieve(limit);

    
    std::cout.imbue(std::locale(""));

    std::cout << "First 35 unprimeable numbers:\n";
    integer n = 100;
    integer lowest[10] = { 0 };
    for (int count = 0, found = 0; n < limit && (found < 10 || count < 600); ++n) {
        if (unprimeable(sieve, n)) {
            if (count < 35) {
                if (count != 0)
                    std::cout << ", ";
                std::cout << n;
            }
            ++count;
            if (count == 600)
                std::cout << "\n600th unprimeable number: " << n << '\n';
            int last_digit = n % 10;
            if (lowest[last_digit] == 0) {
                lowest[last_digit] = n;
                ++found;
            }
        }
    }
    for (int i = 0; i < 10; ++i)
        std::cout << "Least unprimeable number ending in " << i << ": " << lowest[i] << '\n';
    return 0;
}



Go: package main

import (
    "fmt"
    "strconv"
)

func isPrime(n int) bool {
    switch {
    case n < 2:
        return false
    case n%2 == 0:
        return n == 2
    case n%3 == 0:
        return n == 3
    default:
        d := 5
        for d*d <= n {
            if n%d == 0 {
                return false
            }
            d += 2
            if n%d == 0 {
                return false
            }
            d += 4
        }
        return true
    }
}

func commatize(n int) string {
    s := fmt.Sprintf("%d", n)
    le := len(s)
    for i := le - 3; i >= 1; i -= 3 {
        s = s[0:i] + "," + s[i:]
    }
    return s
}

func main() {
    fmt.Println("The first 35 unprimeable numbers are:")
    count := 0           
    var firstNum [10]int 
outer:
    for i, countFirst := 100, 0; countFirst < 10; i++ {
        if isPrime(i) {
            continue 
        }
        s := strconv.Itoa(i)
        le := len(s)
        b := []byte(s)
        for j := 0; j < le; j++ {
            for k := byte('0'); k <= '9'; k++ {
                if s[j] == k {
                    continue
                }
                b[j] = k
                n, _ := strconv.Atoi(string(b))
                if isPrime(n) {
                    continue outer
                }
            }
            b[j] = s[j] 
        }
        lastDigit := s[le-1] - '0'
        if firstNum[lastDigit] == 0 {
            firstNum[lastDigit] = i
            countFirst++
        }
        count++
        if count <= 35 {
            fmt.Printf("%d ", i)
        }
        if count == 35 {
            fmt.Print("\n\nThe 600th unprimeable number is: ")
        }
        if count == 600 {
            fmt.Printf("%s\n\n", commatize(i))
        }
    }

    fmt.Println("The first unprimeable number that ends in:")
    for i := 0; i < 10; i++ {
        fmt.Printf("  %d is: %9s\n", i, commatize(firstNum[i]))
    }
}