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;
}




Java: public class UnprimeableNumbers {

    private static int MAX = 10_000_000;
    private static boolean[] primes = new boolean[MAX];

    public static void main(String[] args) {
        sieve();
        System.out.println("First 35 unprimeable numbers:");
        displayUnprimeableNumbers(35);
        int n = 600;
        System.out.printf("%nThe %dth unprimeable number = %,d%n%n", n, nthUnprimeableNumber(n));
        int[] lowest = genLowest();
        System.out.println("Least unprimeable number that ends in:");
        for ( int i = 0 ; i <= 9 ; i++ ) {
            System.out.printf(" %d is %,d%n", i, lowest[i]);
        }
    }
    
    private static int[] genLowest() {
        int[] lowest = new int[10];
        int count = 0;
        int test = 1;
        while ( count < 10 ) {
            test++;
            if ( unPrimable(test) && lowest[test % 10] == 0 ) {
                lowest[test % 10] = test;
                count++;
            }
        }
        return lowest;
    }

    private static int nthUnprimeableNumber(int maxCount) {
        int test = 1;
        int count = 0;
        int result = 0;
        while ( count < maxCount ) {
            test++;
            if ( unPrimable(test) ) {
                count++;
                result = test;
            }
        }
        return result;
    }

    private static void displayUnprimeableNumbers(int maxCount) {
        int test = 1;
        int count = 0;
        while ( count < maxCount ) {
            test++;
            if ( unPrimable(test) ) {
                count++;
                System.out.printf("%d ", test);
            }
        }
        System.out.println();
    }
    
    private static boolean unPrimable(int test) {
        if ( primes[test] ) {
            return false;
        }
        String s = test + "";
        for ( int i = 0 ; i < s.length() ; i++ ) {
            for ( int j = 0 ; j <= 9 ; j++ ) {
                if ( primes[Integer.parseInt(replace(s, i, j))] ) {
                    return false;
                }
            }
        }
        return true;
    }
    
    private static String replace(String str, int position, int value) {
        char[] sChar = str.toCharArray();
        sChar[position] = (char) value;
        return str.substring(0, position) + value + str.substring(position + 1);
    }

    private static final void sieve() {
        
        for ( int i = 2 ; i < MAX ; i++ ) {
            primes[i] = true;            
        }
        for ( int i = 2 ; i < MAX ; i++ ) {
            if ( primes[i] ) {
                for ( int j = 2*i ; j < MAX ; j += i ) {
                    primes[j] = false;
                }
            }
        }
    }

}