Definitions

As used here, all unprimeable numbers   (positive integers)   are always expressed in base ten.



───── Definition from OEIS ─────:

Unprimeable numbers are composite numbers that always remain composite when a single decimal digit of the number is changed.



───── Definition from Wiktionary   (referenced from Adam Spencer's book) ─────:

(arithmetic)   that cannot be turned into a prime number by changing just one of its digits to any other
digit.   (sic)



Unprimeable numbers are also spelled:   unprimable.

All one─ and two─digit numbers can be turned into primes by changing a single decimal digit.



Examples

190   isn't unprimeable,   because by changing the zero digit into a three yields   193,   which is a prime.



The number   200   is unprimeable,   since none of the numbers   201, 202, 203, ··· 209   are
prime, and all the other numbers obtained by changing a single digit to
produce   100, 300, 400, ··· 900,   or   210, 220, 230, ··· 290   which are all even.



It is valid to change   189   into   089   by changing the   1   (one)   into
a   0   (zero),   which then the leading zero can be removed,   and then treated as if
the   "new"   number is   89.



Task

   show the first   35   unprimeable numbers   (horizontally, on one line, preferably with a title)
   show the   600th   unprimeable number
   (optional) show the lowest unprimeable number ending in a specific decimal digit   (0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
   (optional) use commas in the numbers where appropriate


Show all output here, on this page.



Also see

   the     OEIS     entry:   A118118 (unprimeable)
   with some useful counts to compare unprimeable number
   the Wiktionary entry (reference from below):   (arithmetic definition) unprimeable
   from the Adam Spencer book   (page 200):   Adam Spencer's World of Numbers       (Xoum Publishing)


BEGIN # find unprimable numbers - numbers which can't be made into a prime by changing one digit #
    # construct a sieve of primes up to max prime #
    PR read "primes.incl.a68" PR
    INT max prime = 9 999 999;
    []BOOL prime = PRIMESIEVE max prime;
    # returns TRUE if n is unprimeable, FALSE otherwise #
    PROC is unprimeable = ( INT n )BOOL:
         IF   n < 100
         THEN FALSE
         ELIF prime[ n ]
         THEN FALSE
         ELIF
            # need to try changing a digit #
            INT last digit     = n MOD 10;
            INT leading digits = n - last digit;
            prime[ leading digits + 1 ]
         THEN FALSE
         ELIF prime[ leading digits + 3 ] THEN FALSE
         ELIF prime[ leading digits + 7 ] THEN FALSE
         ELIF prime[ leading digits + 9 ] THEN FALSE
         ELIF last digit = 2 OR last digit = 5
         THEN
            # the final digit is 2 or 5, changing the other digits can't make a prime #
            # unless there is only one other digit which we change to 0 #
            INT v  := leading digits;
            INT dc :=  1;
            WHILE ( v OVERAB 10 ) > 0 DO IF v MOD 10 /= 0 THEN dc +:= 1 FI OD;
            dc /= 2
         ELIF NOT ODD last digit
         THEN TRUE # last digit is even - can't make a prime #
         ELSE
            # last digit is 1, 3, 7, 9: must try changing the other digoits #
            INT m10     :=  10;
            INT r10     := 100;
            BOOL result := TRUE;
            WHILE result AND n > r10 DO
               INT base = ( ( n OVER r10 ) * r10 ) + ( n MOD m10 );
               FOR i FROM 0 BY m10 WHILE result AND i < r10 DO
                   result := NOT prime[ base + i ]
               OD;
               m10 *:= 10;
               r10 *:= 10
            OD;
            IF result THEN
                # still not unprimeable, try changing the first digit #
                INT base = n MOD m10;
                FOR i FROM 0 BY m10 WHILE result AND i < r10 DO
                    result := NOT prime[ base + i ]
                OD
            FI;
            result
         FI # is unprimeable # ;
    # returns a string representation of n with commas #
    PROC commatise = ( LONG LONG INT n )STRING:
         BEGIN
            STRING result      := "";
            STRING unformatted  = whole( n, 0 );
            INT    ch count    := 0;
            FOR c FROM UPB unformatted BY -1 TO LWB unformatted DO
                IF   ch count <= 2 THEN ch count +:= 1
                ELSE                    ch count  := 1; "," +=: result
                FI;
                unformatted[ c ] +=: result
            OD;
            result
         END; # commatise #
    # find unprimeable numbers #
    INT u count := 0;
    INT d count := 0;
    [ 0 : 9 ]INT first unprimeable := []INT( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 )[ AT 0 ];
    FOR i FROM 100 WHILE i < UPB prime AND d count < 10 DO
        IF is unprimeable( i ) THEN
            u count +:= 1;
            IF   u count =   1 THEN
                print( ( "First 35 unprimeable numbers: ", whole( i, 0 ) ) )
            ELIF u count <= 35 THEN
                print( ( " ", whole( i, 0 ) ) )
            ELIF u count = 600 THEN
                print( ( newline, "600th unprimeable number: ", commatise( i ) ) )
            FI;
            INT final digit = i MOD 10;
            IF first unprimeable[ final digit ] = 0 THEN
                # first unprimeable number with this final digit #
                d count +:= 1;
                first unprimeable[ final digit ] := i
            FI
        FI
    OD;
    # show the first unprimeable number that ends with each digit #
    print( ( newline ) );
    FOR i FROM 0 TO 9 DO
        print( ( "First unprimeable number ending in "
               , whole( i, 0 )
               , ": "
               , commatise( first unprimeable[ i ] )
               , newline
               )
             )
    OD
END