Data commit

This commit is contained in:
Ingy döt Net 2023-07-01 11:58:00 -04:00
parent 7387c8f97b
commit cb5bb5e222
199093 changed files with 3378972 additions and 0 deletions

View file

@ -0,0 +1,3 @@
---
from: http://rosettacode.org/wiki/Unprimeable_numbers
note: Prime Numbers

View file

@ -0,0 +1,51 @@
;Definitions:
As used here, all unprimeable numbers   (positive integers)   are always expressed in base ten.
───── Definition from OEIS ─────:
<br>Unprimeable numbers are composite numbers that always remain composite when a single decimal digit of the number is changed.
───── Definition from Wiktionary &nbsp; (referenced from Adam Spencer's book) ─────:
<br>(''arithmetic'') &nbsp; that cannot be turned into a prime number by changing just one of its digits to any other
digit. &nbsp; (<small>sic</small>)
'''Unprimeable''' numbers are also spelled: &nbsp; '''unprimable'''.
All one─ and two─digit numbers can be turned into primes by changing a single decimal digit.
;Examples:
'''190''' &nbsp; isn't unprimeable, &nbsp; because by changing the zero digit into a three yields &nbsp; '''193''', &nbsp; which is a prime.
The number &nbsp; '''200''' &nbsp; <u>is</u> unprimeable, &nbsp; since none of the numbers &nbsp; '''201, 202, 203, ··· 209''' &nbsp; are
prime, and all the other numbers obtained by changing a single digit to
produce &nbsp; '''100, 300, 400, ··· 900''', &nbsp; or &nbsp; '''210, 220, 230, ··· 290''' &nbsp; which are all even.
It is valid to change &nbsp; '''189''' &nbsp; into &nbsp; '''089''' &nbsp; by changing the &nbsp; '''1''' &nbsp; (one) &nbsp; into
a &nbsp; '''0''' &nbsp; (zero), &nbsp; which then the leading zero can be removed, &nbsp; and then treated as if
the &nbsp; "new" &nbsp; number is &nbsp; '''89'''.
;Task:
::* &nbsp; show the first &nbsp; '''35''' &nbsp; unprimeable numbers &nbsp; (horizontally, on one line, preferably with a title)
::* &nbsp; show the &nbsp; '''600<sup>th</sup>''' &nbsp; unprimeable number
::* &nbsp; (optional) show the lowest unprimeable number ending in a specific decimal digit &nbsp; ('''0, 1, 2, 3, 4, 5, 6, 7, 8, 9''')
::* &nbsp; (optional) use commas in the numbers where appropriate
Show all output here, on this page.
;Also see:
:* &nbsp; the &nbsp; &nbsp; OEIS &nbsp; &nbsp; entry: &nbsp; [https://oeis.org/A118118 A118118 (unprimeable)]
:* &nbsp; with some useful counts to compare [http://www.numbersaplenty.com/set/unprimeable_number/ unprimeable number]
:* &nbsp; the Wiktionary entry (reference from below): &nbsp; [https://en.wiktionary.org/wiki/unprimeable (arithmetic definition) unprimeable]
:* &nbsp; from the Adam Spencer book &nbsp; (page 200): &nbsp; ''Adam Spencer's World of Numbers'' &nbsp; &nbsp; &nbsp; (Xoum Publishing)
<br><br>

View file

@ -0,0 +1,48 @@
V limit = 10'000'000
V is_prime = [0B] * 2 [+] [1B] * (limit - 1)
L(n) 0 .< Int(limit ^ 0.5 + 1.5)
I is_prime[n]
L(i) (n * n .< limit + 1).step(n)
is_prime[i] = 0B
F unprimeable(a)
I :is_prime[a]
R 0B
V d = 1
L d <= a
V base = (a I/ (d * 10)) * (d * 10) + (a % d)
I any((base .< base + d * 10).step(d).map(y -> :is_prime[y]))
R 0B
d *= 10
R 1B
F unprime(n)
[Int] r
L(a) 1..
I unprimeable(a)
r [+]= a
I r.len == n
L.break
R r
print(First 35:)
print(unprime(35).map(i -> String(i)).join( ))
print("\nThe 600-th:")
print(unprime(600).last)
print()
V first = [0] * 10
V need = 10
L(p) 1..
I unprimeable(p)
V i = p % 10
I first[i] != 0
L.continue
first[i] = p
I --need == 0
L.break
L(v) first
print(L.index ending: v)

View file

@ -0,0 +1,100 @@
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

View file

@ -0,0 +1,30 @@
unprimeable?: function [n][
if prime? n -> return false
nd: to :string n
loop.with:'i nd 'prevDigit [
loop `0`..`9` 'newDigit [
if newDigit <> prevDigit [
nd\[i]: newDigit
if prime? to :integer nd -> return false
]
]
nd\[i]: prevDigit
]
return true
]
cnt: 0
x: 1
unprimeables: []
while [cnt < 600][
if unprimeable? x [
unprimeables: unprimeables ++ x
cnt: cnt + 1
]
x: x + 1
]
print "First 35 unprimeable numbers:"
print first.n: 35 unprimeables
print ""
print ["600th unprimeable number:" last unprimeables]

View file

@ -0,0 +1,70 @@
#include <iostream>
#include <cstdint>
#include "prime_sieve.hpp"
typedef uint32_t integer;
// return number of decimal digits
int count_digits(integer n) {
int digits = 0;
for (; n > 0; ++digits)
n /= 10;
return digits;
}
// return the number with one digit replaced
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;
}
// returns true if n unprimeable
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);
// print numbers with commas
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;
}

View file

@ -0,0 +1,52 @@
#ifndef PRIME_SIEVE_HPP
#define PRIME_SIEVE_HPP
#include <algorithm>
#include <vector>
/**
* A simple implementation of the Sieve of Eratosthenes.
* See https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes.
*/
class prime_sieve {
public:
explicit prime_sieve(size_t);
bool is_prime(size_t) const;
private:
std::vector<bool> is_prime_;
};
/**
* Constructs a sieve with the given limit.
*
* @param limit the maximum integer that can be tested for primality
*/
inline prime_sieve::prime_sieve(size_t limit) {
limit = std::max(size_t(3), limit);
is_prime_.resize(limit/2, true);
for (size_t p = 3; p * p <= limit; p += 2) {
if (is_prime_[p/2 - 1]) {
size_t inc = 2 * p;
for (size_t q = p * p; q <= limit; q += inc)
is_prime_[q/2 - 1] = false;
}
}
}
/**
* Returns true if the given integer is a prime number. The integer
* must be less than or equal to the limit passed to the constructor.
*
* @param n an integer less than or equal to the limit passed to the
* constructor
* @return true if the integer is prime
*/
inline bool prime_sieve::is_prime(size_t n) const {
if (n == 2)
return true;
if (n < 2 || n % 2 == 0)
return false;
return is_prime_.at(n/2 - 1);
}
#endif

View file

@ -0,0 +1,141 @@
#include <assert.h>
#include <locale.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
typedef struct bit_array_tag {
uint32_t size;
uint32_t* array;
} bit_array;
bool bit_array_create(bit_array* b, uint32_t size) {
uint32_t* array = calloc((size + 31)/32, sizeof(uint32_t));
if (array == NULL)
return false;
b->size = size;
b->array = array;
return true;
}
void bit_array_destroy(bit_array* b) {
free(b->array);
b->array = NULL;
}
void bit_array_set(bit_array* b, uint32_t index, bool value) {
assert(index < b->size);
uint32_t* p = &b->array[index >> 5];
uint32_t bit = 1 << (index & 31);
if (value)
*p |= bit;
else
*p &= ~bit;
}
bool bit_array_get(const bit_array* b, uint32_t index) {
assert(index < b->size);
uint32_t* p = &b->array[index >> 5];
uint32_t bit = 1 << (index & 31);
return (*p & bit) != 0;
}
typedef struct sieve_tag {
uint32_t limit;
bit_array not_prime;
} sieve;
bool sieve_create(sieve* s, uint32_t limit) {
if (!bit_array_create(&s->not_prime, limit/2))
return false;
for (uint32_t p = 3; p * p <= limit; p += 2) {
if (bit_array_get(&s->not_prime, p/2 - 1) == false) {
uint32_t inc = 2 * p;
for (uint32_t q = p * p; q <= limit; q += inc)
bit_array_set(&s->not_prime, q/2 - 1, true);
}
}
s->limit = limit;
return true;
}
void sieve_destroy(sieve* s) {
bit_array_destroy(&s->not_prime);
}
bool is_prime(const sieve* s, uint32_t n) {
assert(n <= s->limit);
if (n == 2)
return true;
if (n < 2 || n % 2 == 0)
return false;
return bit_array_get(&s->not_prime, n/2 - 1) == false;
}
// return number of decimal digits
uint32_t count_digits(uint32_t n) {
uint32_t digits = 0;
for (; n > 0; ++digits)
n /= 10;
return digits;
}
// return the number with one digit replaced
uint32_t change_digit(uint32_t n, uint32_t index, uint32_t new_digit) {
uint32_t p = 1;
uint32_t changed = 0;
for (; index > 0; p *= 10, n /= 10, --index)
changed += p * (n % 10);
changed += (10 * (n/10) + new_digit) * p;
return changed;
}
// returns true if n unprimeable
bool unprimeable(const sieve* s, uint32_t n) {
if (is_prime(s, n))
return false;
uint32_t d = count_digits(n);
for (uint32_t i = 0; i < d; ++i) {
for (uint32_t j = 0; j <= 9; ++j) {
uint32_t m = change_digit(n, i, j);
if (m != n && is_prime(s, m))
return false;
}
}
return true;
}
int main() {
const uint32_t limit = 10000000;
setlocale(LC_ALL, "");
sieve s = { 0 };
if (!sieve_create(&s, limit)) {
fprintf(stderr, "Out of memory\n");
return 1;
}
printf("First 35 unprimeable numbers:\n");
uint32_t n = 100;
uint32_t lowest[10] = { 0 };
for (uint32_t count = 0, found = 0; n < limit && (found < 10 || count < 600); ++n) {
if (unprimeable(&s, n)) {
if (count < 35) {
if (count != 0)
printf(", ");
printf("%'u", n);
}
++count;
if (count == 600)
printf("\n600th unprimeable number: %'u\n", n);
uint32_t last_digit = n % 10;
if (lowest[last_digit] == 0) {
lowest[last_digit] = n;
++found;
}
}
}
sieve_destroy(&s);
for (uint32_t i = 0; i < 10; ++i)
printf("Least unprimeable number ending in %u: %'u\n" , i, lowest[i]);
return 0;
}

View file

@ -0,0 +1,100 @@
import std.algorithm;
import std.array;
import std.conv;
import std.range;
import std.stdio;
immutable MAX = 10_000_000;
bool[] primes;
bool[] sieve(int limit) {
bool[] p = uninitializedArray!(bool[])(limit);
p[0..2] = false;
p[2..$] = true;
foreach (i; 2..limit) {
if (p[i]) {
for (int j = 2 * i; j < limit; j += i) {
p[j] = false;
}
}
}
return p;
}
string replace(CHAR)(CHAR[] str, int position, CHAR value) {
str[position] = value;
return str.idup;
}
bool unPrimeable(int n) {
if (primes[n]) {
return false;
}
auto test = n.to!string;
foreach (i; 0 .. test.length) {
for (char j = '0'; j <= '9'; j++) {
auto r = replace(test.dup, i, j);
if (primes[r.to!int]) {
return false;
}
}
}
return true;
}
void displayUnprimeableNumbers(int maxCount) {
int test = 1;
for (int count = 0; count < maxCount;) {
test++;
if (unPrimeable(test)) {
count++;
write(test, ' ');
}
}
writeln;
}
int nthUnprimeableNumber(int maxCount) {
int test = 1;
for (int count = 0; count < maxCount;) {
test++;
if (unPrimeable(test)) {
count++;
}
}
return test;
}
int[] genLowest() {
int[] lowest = uninitializedArray!(int[])(10);
lowest[] = 0;
int count = 0;
int test = 1;
while (count < 10) {
test++;
if (unPrimeable(test) && lowest[test % 10] == 0) {
lowest[test % 10] = test;
count++;
}
}
return lowest;
}
void main() {
primes = sieve(MAX);
writeln("First 35 unprimeable numbers:");
displayUnprimeableNumbers(35);
writeln;
int n = 600;
writefln("The %dth unprimeable number = %,d", n, nthUnprimeableNumber(n));
writeln;
writeln("Least unprimeable number that ends in:");
foreach (i,v; genLowest()) {
writefln(" %d is %,d", i, v);
}
}

View file

@ -0,0 +1,4 @@
// Unprimeable numbers. Nigel Galloway: May 4th., 2021
let rec fN i g e l=seq{yield! [0..9]|>Seq.map(fun n->n*g+e+l); if g>1 then let g=g/10 in yield! fN(i+g*(e/g)) g (e%g) i}
let fG(n,g)=fN(n*(g/n)) n (g%n) 0|>Seq.exists(isPrime)
let uP()=let rec fN n g=seq{yield! {n..g-1}|>Seq.map(fun g->(n,g)); yield! fN(g)(g*10)} in fN 1 10|>Seq.filter(fG>>not)|>Seq.map snd

View file

@ -0,0 +1 @@
uP()|>Seq.take 35|>Seq.iter(printf "%d "); printfn ""

View file

@ -0,0 +1 @@
printfn "600th unprimable number is %d" (uP()|>Seq.item 599)

View file

@ -0,0 +1 @@
[0..9]|>Seq.iter(fun n->printfn "first umprimable number ending in %d is %d" n (uP()|>Seq.find(fun g->n=g%10)))

View file

@ -0,0 +1,2 @@
let uPx x=let rec fN n g=seq{yield! {n+x..10..g-1}|>Seq.map(fun g->(max 1 n,g)); yield! fN(g)(g*10)} in fN 0 10|>Seq.filter(fG>>not)|>Seq.map snd
[0..9]|>Seq.iter(fun n->printfn "first umprimable number ending in %d is %d" n (uPx n|>Seq.head))

View file

@ -0,0 +1,33 @@
USING: assocs formatting io kernel lists lists.lazy
lists.lazy.examples math math.functions math.primes math.ranges
math.text.utils prettyprint sequences tools.memory.private ;
: one-offs ( n -- seq )
dup 1 digit-groups [
swapd 10^ [ * ] keep [ - ] dip
2dup [ 9 * ] [ + ] [ <range> ] tri*
] with map-index concat ;
: (unprimeable?) ( n -- ? )
[ f ] [ one-offs [ prime? ] none? ] if-zero ;
: unprimeable? ( n -- ? )
dup prime? [ drop f ] [ (unprimeable?) ] if ;
: unprimeables ( -- list ) naturals [ unprimeable? ] lfilter ;
: ?set-at ( value key assoc -- )
2dup key? [ 3drop ] [ set-at ] if ;
: first-digits ( -- assoc )
unprimeables H{ } clone [ dup assoc-size 10 = ]
[ [ unswons dup 10 mod ] dip [ ?set-at ] keep ] until nip ;
"The first 35 unprimeable numbers:" print bl bl
35 unprimeables ltake [ pprint bl ] leach nl nl
"The 600th unprimeable number:" print bl bl
599 unprimeables lnth commas print nl
"The first unprimeable number ending with" print
first-digits [ commas " %d: %9s\n" printf ] assoc-each

View file

@ -0,0 +1,51 @@
Function isprime(n As Ulongint) As boolean
If (n=2) Or (n=3) Then Return 1
If n Mod 2 = 0 Then Return 0
If n Mod 3 = 0 Then Return 0
Dim As Ulongint limit=Sqr(N)+1
For I As Ulongint = 6 To limit Step 6
If N Mod (i-1) = 0 Then Return 0
If N Mod (i+1) = 0 Then Return 0
Next I
Return 1
End Function
Sub getnonprimeables(a() As Long)
Dim As String s,g
Dim As Long count,lim=1300000
Redim a(1 To lim)
For num As Long=1 To lim
g=Str(num)
s=g
For n As Long=0 To Len(s)-1
For m As Long=48 To 57
s[n]=m
If isprime(Vallng(s)) Then Goto lbl
Next m
s=g
Next n
count+=1
a(count)=num
lbl:
Next num
Redim Preserve a(1 To count)
End Sub
Function endings(n As String,a() As Long) As Long
For m As Long=1 To Ubound(a)
If Right(Str(a(m)),1)=n Then Return a(m)
Next m
End Function
Redim As Long n()
getnonprimeables(n())
print " First 35"
For m As Long=1 To 35
Print n(m);
Next
Print
Print "600th number ";n(600)
For z As Long=0 To 9
Print "first umprimable number ending in ";z; " is ";endings(Str(z),n())
Next z
sleep

View file

@ -0,0 +1,87 @@
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 // counts all unprimeable numbers
var firstNum [10]int // stores the first unprimeable number ending with each digit
outer:
for i, countFirst := 100, 0; countFirst < 10; i++ {
if isPrime(i) {
continue // unprimeable number must be composite
}
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] // restore j'th digit to what it was originally
}
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]))
}
}

View file

@ -0,0 +1,31 @@
import Control.Lens ((.~), ix, (&))
import Data.Numbers.Primes (isPrime)
import Data.List (find, intercalate)
import Data.Char (intToDigit)
import Data.Maybe (mapMaybe)
import Data.List.Split (chunksOf)
import Text.Printf (printf)
isUnprimable :: Int -> Bool
isUnprimable = all (not . isPrime) . swapdigits
swapdigits :: Int -> [Int]
swapdigits n = map read $ go $ pred $ length digits
where
digits = show n
go (-1) = []
go n'' = map (\x -> digits & (ix n'') .~ intToDigit x) [0..9] <> go (pred n'')
unPrimeable :: [Int]
unPrimeable = filter isUnprimable [1..]
main :: IO ()
main = do
printf "First 35 unprimeable numbers:\n%s\n\n" $ show $ take 35 unPrimeable
printf "600th unprimeable number: %d\n\n" $ unPrimeable !! 599
mapM_ (uncurry (printf "Lowest unprimeable number ending with %d: %10s\n")) $ mapMaybe lowest [0..9]
where
thousands = reverse . intercalate "," . chunksOf 3 . reverse
lowest n = do
x <- find (\x -> x `mod` 10 == n) unPrimeable
pure (n, thousands $ show x)

View file

@ -0,0 +1,11 @@
NB. replace concatenates at various ranks and in boxes to avoid fill
NB. the curtailed prefixes (}:\) with all of 0..9 (i.10) with the beheaded suffixes (}.\.)
NB. under the antibase 10 representation (10&#.inv)
replace=: ([: ; <@}:\ ,"1 L:_1 ([: < (i.10) ,"0 1 }.)\.)&.(10&#.inv)
NB. primable tests if one of the replacements is prime
primable=: (1 e. 1 p: replace)&>
unprimable=: -.@:primable
assert 0 1 -: unprimable 193 200

View file

@ -0,0 +1,95 @@
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() {
// primes
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;
}
}
}
}
}

View file

@ -0,0 +1,10 @@
Number.prototype.isPrime = function() {
let i = 2, num = this;
if (num == 0 || num == 1) return false;
if (num == 2) return true;
while (i <= Math.ceil(Math.sqrt(num))) {
if (num % i == 0) return false;
i++;
}
return true;
}

View file

@ -0,0 +1,13 @@
function isUnprimable(num) {
if (num < 100 || num.isPrime()) return false;
let arr = num.toString().split('');
for (let x = 0; x < arr.length; x++) {
let lft = arr.slice(0, x),
rgt = arr.slice(x + 1);
for (let y = 0; y < 10; y++) {
let test = lft.join('') + y.toString() + rgt.join('');
if (parseInt(test).isPrime()) return false;
}
}
return true;
}

View file

@ -0,0 +1,29 @@
let unprimeables = [],
endings = new Array(10).fill('-'),
c = 1;
function chkEnds(n) {
let e = n % 10;
if (endings[e] == '-') endings[e] = n;
}
console.time('I');
while (unprimeables.length < 1000) {
if (isUnprimable(c)) {
unprimeables.push(c);
chkEnds(c)
}
c++;
}
console.log('The first 35 unprimeables:');
console.log(unprimeables.slice(0,35).join(', '));
console.log(`The 600th unprimeable: ${unprimeables[599].toLocaleString('en')}`);
console.log(`The 1000th unprimable: ${unprimeables[999].toLocaleString('en')}`);
console.timeEnd('I');
console.time('II');
while (endings.includes('-')) {
c++;
if (isUnprimable(c)) chkEnds(c);
}
for (c = 0; c < endings.length; c++) {
console.log(`First unprimeable ending with ${c}: ${endings[c].toLocaleString('en')}`);
}
console.timeEnd('II');

View file

@ -0,0 +1,3 @@
def digits: tostring | explode | map([.] | implode | tonumber);
def lpad($len): tostring | ($len - length) as $l | (" " * $l)[:$l] + .;

View file

@ -0,0 +1,16 @@
def variants:
digits
| range(0; length) as $pos
| range(0;10) as $newdigit
| if .[$pos] == $newdigit then empty
else .[$pos] = $newdigit
| join("")|tonumber
end;
def is_unprimeable:
if is_prime or any(variants; is_prime) then false
else true
end;
def unprimeables:
range(4; infinite) | select(is_unprimeable);

View file

@ -0,0 +1,14 @@
def task:
"First 35 unprimeables: ",
[limit(35; range(0;infinite) | select(is_unprimeable))],
"\nThe 600th unprimeable is \( nth(600 - 1; unprimeables) ).",
"\nDigit First unprimeable ending with that digit",
"-----------------------------------------------",
(range(0;10) as $dig
| first( range(0;infinite) | select((. % 10 == $dig) and is_unprimeable))
| " \($dig) \(lpad(9))" )
;
task

View file

@ -0,0 +1,24 @@
using Primes, Lazy, Formatting
function isunprimeable(n)
dvec = digits(n)
for pos in 1:length(dvec), newdigit in 0:9
olddigit, dvec[pos] = dvec[pos], newdigit
isprime(foldr((i, j) -> i + 10j, dvec)) && return false
dvec[pos] = olddigit
end
return true
end
println("First 35 unprimeables: ", take(35, filter(isunprimeable, Lazy.range())))
println("\nThe 600th unprimeable is ",
collect(take(600, filter(isunprimeable, Lazy.range())))[end])
println("\nDigit First unprimeable ending with that digit")
println("-----------------------------------------")
for dig in 0:9
n = first(filter(x -> (x % 10 == dig) && isunprimeable(x), Lazy.range()))
println(" $dig ", lpad(format(n, commas=true), 9))
end

View file

@ -0,0 +1,95 @@
private const val MAX = 10000000
private val primes = BooleanArray(MAX)
fun main() {
sieve()
println("First 35 unprimeable numbers:")
displayUnprimeableNumbers(35)
val n = 600
println()
println("The ${n}th unprimeable number = ${nthUnprimeableNumber(n)}")
println()
val lowest = genLowest()
println("Least unprimeable number that ends in:")
for (i in 0..9) {
println(" $i is ${lowest[i]}")
}
}
private fun genLowest(): IntArray {
val lowest = IntArray(10)
var count = 0
var test = 1
while (count < 10) {
test++
if (unPrimable(test) && lowest[test % 10] == 0) {
lowest[test % 10] = test
count++
}
}
return lowest
}
private fun nthUnprimeableNumber(maxCount: Int): Int {
var test = 1
var count = 0
var result = 0
while (count < maxCount) {
test++
if (unPrimable(test)) {
count++
result = test
}
}
return result
}
private fun displayUnprimeableNumbers(maxCount: Int) {
var test = 1
var count = 0
while (count < maxCount) {
test++
if (unPrimable(test)) {
count++
print("$test ")
}
}
println()
}
private fun unPrimable(test: Int): Boolean {
if (primes[test]) {
return false
}
val s = test.toString() + ""
for (i in s.indices) {
for (j in 0..9) {
if (primes[replace(s, i, j).toInt()]) {
return false
}
}
}
return true
}
private fun replace(str: String, position: Int, value: Int): String {
val sChar = str.toCharArray()
sChar[position] = value.toChar()
return str.substring(0, position) + value + str.substring(position + 1)
}
private fun sieve() {
// primes
for (i in 2 until MAX) {
primes[i] = true
}
for (i in 2 until MAX) {
if (primes[i]) {
var j = 2 * i
while (j < MAX) {
primes[j] = false
j += i
}
}
}
}

View file

@ -0,0 +1,50 @@
-- FUNCS:
local function T(t) return setmetatable(t, {__index=table}) end
table.filter = function(t,f) local s=T{} for _,v in ipairs(t) do if f(v) then s[#s+1]=v end end return s end
table.firstn = function(t,n) local s=T{} n=n>#t and #t or n for i = 1,n do s[i]=t[i] end return s end
-- SIEVE:
local sieve, S = {}, 10000000
for i = 2,S do sieve[i]=true end
for i = 2,S do if sieve[i] then for j=i*i,S,i do sieve[j]=nil end end end
-- UNPRIMABLE:
local unprimables, lowests = T{}, T{}
local floor, log10 = math.floor, math.log10
local function unprimable(n)
if sieve[n] then return false end
local nd = floor(log10(n))+1
for i = 1, nd do
local pow10 = 10^(nd-i)
for j = 0, 9 do
local p = (floor(n/10/pow10) * 10 + j) * pow10 + (n % pow10)
if sieve[p] then return false end
end
end
return true
end
local n, done = 1, 0
while done < 10 do
if unprimable(n) then
unprimables:insert(n)
if not lowests[n%10] then
lowests[n%10] = n
done = done + 1
end
end
n = n + 1
end
-- OUTPUT:
local function commafy(i) return tostring(i):reverse():gsub("(%d%d%d)","%1,"):reverse():gsub("^,","") end
print("The first 35 unprimable numbers are:")
print(unprimables:firstn(35):concat(" "))
print()
print("The 600th unprimable number is: " .. commafy(unprimables[600]))
print()
print("The lowest unprimable number that ends in..")
for i = 0, 9 do
print(" " .. i .. " is: " .. commafy(lowests[i]))
end

View file

@ -0,0 +1,43 @@
ClearAll[Unprimeable]
Unprimeable[in_Integer] := Module[{id, new, pos},
id = IntegerDigits[in];
pos = Catenate@Table[
Table[
new = id;
new[[d]] = n;
new
,
{n, 0, 9}
]
,
{d, Length[id]}
];
pos //= Map[FromDigits];
NoneTrue[pos, PrimeQ]
]
res = {};
PrintTemporary[Dynamic[{Length[res], i}]];
i = 0;
While[Length[res] < 600,
If[Unprimeable[i],
AppendTo[res, i]
];
i++
];
PrintTemporary[Dynamic[{lastdig, i}]];
out = Table[
i = lastdig;
While[! Unprimeable[i],
i += 10
];
i
,
{lastdig, 0, 9}
];
res[[;; 35]]
res[[600]]
lastdigit = IntegerDigits /* Last;
Print["Least unprimeable number ending in ", lastdigit[#], ": ", #] & /@ SortBy[out, lastdigit];

View file

@ -0,0 +1,49 @@
import strutils
const N = 10_000_000
# Erastosthenes sieve.
var composite: array[0..N, bool] # Defualt is false i.e. composite.
composite[0] = true
composite[1] = true
for n in 2..N:
if not composite[n]:
for k in countup(n * n, N, n):
composite[k] = true
template isPrime(n: int): bool = not composite[n]
proc isUmprimeable(n: Positive): bool =
if n.isPrime: return false
var nd = $n
for i, prevDigit in nd:
for newDigit in '0'..'9':
if newDigit != prevDigit:
nd[i] = newDigit
if nd.parseInt.isPrime: return false
nd[i] = prevDigit # Restore initial digit.
result = true
echo "First 35 unprimeable numbers:"
var n = 100
var list: seq[int]
while list.len < 35:
if n.isUmprimeable:
list.add n
inc n
echo list.join(" "), '\n'
var count = 0
n = 199
while count != 600:
inc n
if n.isUmprimeable: inc count
echo "600th unprimeable number: ", ($n).insertSep(','), '\n'
for d in 0..9:
var n = 200 + d
while not n.isUmprimeable:
inc n, 10
echo "Lowest unprimeable number ending in ", d, " is ", ($n).insertSep(',')

View file

@ -0,0 +1,212 @@
program unprimable;
{$IFDEF FPC}{$Mode Delphi}{$ELSE}{$APPTYPE CONSOLE}{$ENDIF}
const
base = 10;
type
TNumVal = array[0..base-1] of NativeUint;
TConvNum = record
NumRest : TNumVal;
LowDgt,
MaxIdx : NativeUint;
end;
var //global
PotBase,
EndDgtFound : TNumVal;
TotalCnt,
EndDgtCnt :NativeUint;
procedure Init;
var
i,val : NativeUint;
Begin
val := 1;
For i := low(TNumVal) to High(TNumVal) do
Begin
EndDgtFound[i] :=0;
PotBase[i] := val;
val := val * Base;
end;
TotalCnt := 0;
EndDgtCnt := 0;
end;
Procedure ConvertNum(n: NativeUint;var NConv:TConvNum);
//extract digit position replace by "0" to get NumRest
// 173 -> 170 -> 103 -> 073
var
i, dgt,n_red,n_mod: NativeUint;
begin
i := 0;
n_red := n;
with NConv do
Begin
repeat
n_mod := n_red DIV Base;
dgt := n_red-Base*n_mod;
n_red := n_mod;
IF i = 0 then
LowDgt := dgt;
NumRest[i]:= n-dgt*PotBase[i];
inc(i);
until (i > High(TNumVal)) OR (n<PotBase[i]);
MaxIdx := i-1;
end;
end;
procedure CheckOutPut(n: NativeUint);
Begin
IF TotalCnt > 600 then
EXIT;
IF TotalCnt <= 35 then
write(n,' ');
IF TotalCnt = 600 then
Begin
writeln;
writeln;
writeln('the 600.th unprimable number: ',n);
end;
end;
function isPrime(n : NativeUint):boolean;inline;
var
p : NativeUint;
Begin
result := (N=2) OR (N=3);
IF result then
EXIT;
//now result = false
IF (n<2) OR (NOT(ODD(n))) or (n mod 3= 0) then
EXIT;
p := 5;
while p*p <= n do
Begin
if n mod p = 0 then
Exit;
inc(p,2);
if n mod p = 0 then
Exit;
inc(p,4);
end;
result := true;
end;
procedure InsertFound(LowDgt,n:NativeUInt);
Begin
inc(TotalCnt);
IF EndDgtFound[LowDgt] = 0 then
Begin
EndDgtFound[LowDgt] := n;
inc(EndDgtCnt);
end;
end;
function CheckUnprimable(n:NativeInt):boolean;
var
ConvNum : TConvNum;
val,dgt,i,dtfac: NativeUint;
Begin
ConvertNum(n,ConvNum);
result := false;
//lowest digit
with ConvNum do
Begin
val := NumRest[0];
For dgt := 0 to Base-1 do
IF isPrime(val+dgt) then
EXIT;
dgt := LowDgt;
result := true;
i := MaxIdx;
IF NumRest[i] >= Base then
Begin
//****Only for base=10 if even or divisible by 5***
IF Not(ODD(dgt)) OR (dgt=5) then
Begin
InsertFound(dgt,n);
EXIT;
end;
end;
result := false;
For i := MaxIdx downto 1 do
Begin
dtfac := PotBase[i];
val := NumRest[i];
For dgt := 0 to Base-1 do
Begin
IF isPrime(val) then
EXIT;
inc(val,dtfac);
end;
end;
InsertFound(LowDgt,n);
result := true;
end;
end;
function CheckUnprimableReduced(n:NativeInt):boolean;
//lowest digit already tested before
var
ConvNum : TConvNum;
val,dgt,i,dtfac: NativeUint;
Begin
ConvertNum(n,ConvNum);
result := true;
with ConvNum do
Begin
i := MaxIdx;
IF NumRest[i] >= Base then
Begin
dgt := LowDgt;
IF Not(ODD(dgt)) OR (dgt=5) then
Begin
InsertFound(dgt,n);
EXIT;
end;
end;
result := false;
For i := i downto 1 do
Begin
dtfac := PotBase[i];
val := NumRest[i];
For dgt := 0 to Base-1 do
Begin
IF isPrime(val) then
EXIT;
inc(val,dtfac);
end;
end;
InsertFound(LowDgt,n);
result := true;
end;
end;
var
n,i : NativeUint;
Begin
init;
n := Base;
repeat
If CheckUnprimable(n) then
Begin
CheckOutPut(n);
For i := 1 to Base-1 do
Begin
IF CheckUnprimableReduced(n+i) then
CheckOutPut(n+i);
end;
end;
inc(n,Base);
until EndDgtCnt = Base;
writeln;
For i := 0 to Base-1 do
Writeln ('lowest digit ',i:2,' found first ',EndDgtFound[i]:7);
writeln;
writeln('There are ',TotalCnt,' unprimable numbers upto ',n);
{$IFNDEF UNIX}readln;{$ENDIF}
end.

View file

@ -0,0 +1,417 @@
program unprimable;
{$IFDEF FPC}
{$Mode Delphi}
{$OPTIMIZATION ON,ALL}
{$ELSE}
//Delphi
{$APPTYPE CONSOLE}
{$ENDIF}
uses
sysutils;
const
Base = 10;
dgtcnt = 9;
Limit = Base* Base*Base*Base*Base* Base*Base*Base*Base;
{
Base = 18;
dgtcnt = 8;
Limit = Base*Base*Base*Base* Base*Base*Base*Base;
* }
PrimeLimit = Limit+Base;
{
Limit = 1000*1000*1000;
dgtcnt = trunc(ln(Limit-1)/ln(Base));
PrimeLimit = Trunc(exp(ln(base)*(dgtcnt+1)))+Base;
}
type
TNumVal = array[0..dgtcnt] of NativeUint;
TConvNum = record
NumRest,
Digits : TNumVal;
num,
MaxIdx : NativeUint;
end;
var //global
ConvNum:TConvNum;
PotBase: TNumVal;
EndDgtFound : array[0..Base-1] of NativeUint;
TotalCnt,
EndDgtCnt :NativeUint;
//http://rosettacode.org/wiki/Sieve_of_Eratosthenes#alternative_using_wheel
var
pPrimes : pBoolean;
//always initialized with 0 => false at startup
primes: array of boolean;
function BuildWheel: NativeUint;
var
myPrimes : pBoolean;
wheelprimes :array[0..31] of byte;
wheelSize,wpno,
pr,pw,i, k: NativeUint;
begin
myPrimes := @primes[0];
pr := 1;
myPrimes[1]:= true;
WheelSize := 1;
wpno := 0;
repeat
inc(pr);
pw := pr;
if pw > wheelsize then
dec(pw,wheelsize);
If myPrimes[pw] then
begin
k := WheelSize+1;
//turn the wheel (pr-1)-times
for i := 1 to pr-1 do
begin
inc(k,WheelSize);
if k<primeLimit then
move(myPrimes[1],myPrimes[k-WheelSize],WheelSize)
else
begin
move(myPrimes[1],myPrimes[k-WheelSize],PrimeLimit-WheelSize*i);
break;
end;
end;
dec(k);
IF k > primeLimit then
k := primeLimit;
wheelPrimes[wpno] := pr;
myPrimes[pr] := false;
inc(wpno);
//the new wheelsize
WheelSize := k;
//sieve multiples of the new found prime
i:= pr;
i := i*i;
while i <= k do
begin
myPrimes[i] := false;
inc(i,pr);
end;
end;
until WheelSize >= PrimeLimit;
//re-insert wheel-primes 1 still stays prime
while wpno > 0 do
begin
dec(wpno);
myPrimes[wheelPrimes[wpno]] := true;
end;
myPrimes[0] := false;
myPrimes[1] := false;
BuildWheel := pr+1;
writeln;
end;
procedure Sieve;
var
myPrimes : pBoolean;
sieveprime,
fakt : NativeUint;
begin
setlength(Primes,PrimeLimit+1);
pPrimes := @Primes[0];
myPrimes := pPrimes;
//pPrimes[1] = true is needed to stop for sieveprime = 2
// at //Search next smaller possible prime
sieveprime := BuildWheel;
//alternative here
//fillchar(pPrimes,SizeOf(pPrimes),chr(ord(true)));sieveprime := 2;
repeat
if myPrimes[sieveprime] then
begin
//eliminate 'possible prime' multiples of sieveprime
//must go downwards
//2*2 would unmark 4 -> 4*2 = 8 wouldnt be unmarked
fakt := PrimeLimit DIV sieveprime;
IF fakt < sieveprime then
BREAK;
repeat
//Unmark
myPrimes[sieveprime*fakt] := false;
//Search next smaller possible prime
repeat
dec(fakt);
until myPrimes[fakt];
until fakt < sieveprime;
end;
inc(sieveprime);
until false;
//remove 1
myPrimes[1] := false;
end;
procedure Init;
var
i,val : NativeUint;
Begin
val := 1;
For i := low(TNumVal) to High(TNumVal) do
Begin
EndDgtFound[i] :=0;
PotBase[i] := val;
val := val * Base;
end;
TotalCnt := 0;
EndDgtCnt := 0;
end;
procedure OutConvNum(const NConv:TConvNum);
var
i : NativeInt;
Begin
with NConv do
begin
writeln(num,MaxIdx:10);
For i := MaxIdx Downto MaxIdx do
write(Digits[i]);
writeln;
For i := MaxIdx Downto MaxIdx do
write(NumRest[i]:8);
end
end;
procedure IncConvertNum(var NConv:TConvNum);
var
i,k : NativeInt;
Begin
with NConv do
begin
i := 0;
repeat
k := Digits[i]+1;
IF k < Base then
Begin
Digits[i] := k;
BREAK;
end
else
Begin
Digits[i] := k-Base;
inc(i);
end;
until i > MaxIdx;
IF i > MaxIdx then
Begin
Digits[i] := 1;
MaxIdx := i;
end;
k := num+1;
i := MaxIdx;
repeat
NumRest[i]:= k-Digits[i]*PotBase[i];
dec(i);
until i < 0;
num := k;
end;
end;
procedure IncConvertNumBase(var NConv:TConvNum);
var
i,k : NativeInt;
Begin
with NConv do
begin
i := 1;
Digits[0] := 0;
repeat
k := Digits[i]+1;
IF k < Base then
Begin
Digits[i] := k;
BREAK;
end
else
Begin
Digits[i] := k-Base;
inc(i);
end;
until i > MaxIdx;
IF i > MaxIdx then
Begin
Digits[i] := 1;
MaxIdx := i;
end;
k := num+Base;
i := MaxIdx;
repeat
NumRest[i]:= k-Digits[i]*PotBase[i];
dec(i);
until i < 0;
num := k;
end;
end;
Procedure ConvertNum(n: NativeUint;var NConv:TConvNum);
//extract digit position replace by "0" to get NumRest
// 173 -> 170 -> 103 -> 073
var
i, dgt,n_red,n_div: NativeUint;
begin
i := 0;
with NConv do
Begin
num := n;
n_red := n;
repeat
n_div := n_red DIV Base;
dgt := n_red-Base*n_div;
n_red := n_div;
Digits[i] := dgt;
NumRest[i]:= n-dgt*PotBase[i];
inc(i);
until (n_red= 0)OR (i > High(TNumVal));
MaxIdx := i-1;
end;
end;
procedure InsertFound(dgt,n:NativeUInt);
Begin
IF EndDgtFound[dgt] = 0 then
Begin
EndDgtFound[dgt] := n;
inc(EndDgtCnt);
end;
end;
function CheckUnprimable(const ConvNum:TConvNum):boolean;
var
myPrimes : pBoolean;
val,dgt,i,dtfac: NativeUint;
Begin
myPrimes := pPrimes;
result := false;
with ConvNum do
Begin
//lowest digit. Check only resulting odd numbers num > base
val := NumRest[0];
dgt := 1- (val AND 1);
repeat
IF myPrimes[val+dgt] then
EXIT;
inc(dgt,2);
until dgt >= Base;
For i := 1 to MaxIdx do
Begin
val := NumRest[i];
dtfac := PotBase[i];
IF (val >= BASE) then
Begin
IF NOt(Odd(val)) AND NOT(ODD(dtfac)) then
continue;
For dgt := 0 to Base-1 do
Begin
IF myPrimes[val] then
EXIT;
inc(val,dtfac);
end;
end
else
Begin
For dgt := 0 to Base-1 do
Begin
IF myPrimes[val] then
EXIT;
inc(val,dtfac);
end;
end
end;
inc(TotalCnt);
result := true;
end;
end;
var
n,i,Lmt,Lmt10 : NativeUint;
Begin
init;
Sieve;
n := Base;
Lmt10 := 10;
Lmt := Base;
ConvertNum(n,ConvNum);
writeln('Base ',ConvNum.num);
//InsertFound takes a lot of time.So check it as long as neccessary
while EndDgtCnt <Base do
Begin
If CheckUnprimable(ConvNum) then
Begin
InsertFound(ConvNum.Digits[0],n);
For i := 1 to Base-1 do
Begin
inc(n);
IncConvertNum(ConvNum);
IF CheckUnprimable(ConvNum) then
InsertFound(ConvNum.Digits[0],n);
end;
inc(n);
IncConvertNum(ConvNum);
end
else
Begin
inc(n,Base);
IncConvertNumBase(ConvNum);
end;
if n >= Lmt10 then
Begin
writeln('There are ',TotalCnt,' unprimable numbers upto ',n);
Lmt10 := Lmt10*10;
end;
if (Base <> 10) AND (n >= Lmt) then
Begin
writeln('There are ',TotalCnt,' unprimable numbers upto ',n);
Lmt := Lmt*Base;
end;
end;
//All found
repeat
If CheckUnprimable(ConvNum) then
Begin
For i := 1 to Base-1 do
Begin
inc(n);
IncConvertNum(ConvNum);
CheckUnprimable(ConvNum)
end;
inc(n);
IncConvertNum(ConvNum);
end
else
Begin
inc(n,Base);
IncConvertNumBase(ConvNum);
end;
if n >= Lmt10 then
Begin
writeln('There are ',TotalCnt,' unprimable numbers upto ',n);
Lmt10 := Lmt10*10;
end;
if (Base <> 10) AND (n >= Lmt) then
Begin
writeln('There are ',TotalCnt,' unprimable numbers upto ',n);
Lmt := Lmt*Base;
end;
until n >= Limit;
writeln;
For i := 0 to Base-1 do
Writeln ('lowest digit ',i:2,' found first ',EndDgtFound[i]:7);
writeln;
writeln('There are ',TotalCnt,' unprimable numbers upto ',n);
setlength(Primes,0);
end.

View file

@ -0,0 +1,30 @@
use strict;
use warnings;
use feature 'say';
use ntheory 'is_prime';
use enum qw(False True);
sub comma { reverse ((reverse shift) =~ s/(.{3})/$1,/gr) =~ s/^,//r }
sub is_unprimeable {
my($n) = @_;
return False if is_prime($n);
my $chrs = length $n;
for my $place (0..$chrs-1) {
my $pow = 10**($chrs - $place - 1);
my $this = substr($n, $place, 1) * $pow;
map { return False if $this != $_ and is_prime($n - $this + $_ * $pow) } 0..9;
}
True
}
my($n, @ups);
do { push @ups, $n if is_unprimeable(++$n); } until @ups == 600;
say "First 35 unprimeables:\n" . join ' ', @ups[0..34];
printf "\n600th unprimeable: %s\n", comma $ups[599];
map {
my $x = $_;
while ($x += 10) { last if is_unprimeable($x) }
say "First unprimeable that ends with $_: " . sprintf "%9s", comma $x;
} 0..9;

View file

@ -0,0 +1,54 @@
(phixonline)-->
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"The first 35 unprimeable numbers are:\n"</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">count</span> <span style="color: #0000FF;">:=</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #000080;font-style:italic;">-- counts all unprimeable numbers</span>
<span style="color: #000000;">countFirst</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">,</span>
<span style="color: #000000;">i</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">100</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">firstNum</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">10</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- stores the first unprimeable number ending with each digit</span>
<span style="color: #004080;">atom</span> <span style="color: #000000;">t0</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">time</span><span style="color: #0000FF;">(),</span> <span style="color: #000000;">t1</span><span style="color: #0000FF;">=</span><span style="color: #000000;">t0</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span>
<span style="color: #008080;">while</span> <span style="color: #000000;">countFirst</span><span style="color: #0000FF;"><</span><span style="color: #000000;">10</span> <span style="color: #008080;">do</span>
<span style="color: #008080;">if</span> <span style="color: #008080;">not</span> <span style="color: #7060A8;">is_prime</span><span style="color: #0000FF;">(</span><span style="color: #000000;">i</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span> <span style="color: #000080;font-style:italic;">-- unprimeable number must be composite</span>
<span style="color: #004080;">string</span> <span style="color: #000000;">s</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">sprintf</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"%d"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">i</span><span style="color: #0000FF;">),</span> <span style="color: #000000;">b</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">s</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">le</span> <span style="color: #0000FF;">:=</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">bool</span> <span style="color: #000000;">primeable</span> <span style="color: #0000FF;">=</span> <span style="color: #004600;">false</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">j</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">le</span> <span style="color: #008080;">do</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">k</span><span style="color: #0000FF;">=</span><span style="color: #008000;">'0'</span> <span style="color: #008080;">to</span> <span style="color: #008000;">'9'</span> <span style="color: #008080;">do</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">j</span><span style="color: #0000FF;">]!=</span><span style="color: #000000;">k</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">b</span><span style="color: #0000FF;">[</span><span style="color: #000000;">j</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">k</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">n</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">to_integer</span><span style="color: #0000FF;">(</span><span style="color: #000000;">b</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">if</span> <span style="color: #7060A8;">is_prime</span><span style="color: #0000FF;">(</span><span style="color: #000000;">n</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">primeable</span> <span style="color: #0000FF;">=</span> <span style="color: #004600;">true</span>
<span style="color: #008080;">exit</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">primeable</span> <span style="color: #008080;">then</span> <span style="color: #008080;">exit</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #000000;">b</span><span style="color: #0000FF;">[</span><span style="color: #000000;">j</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">j</span><span style="color: #0000FF;">]</span> <span style="color: #000080;font-style:italic;">-- restore j'th digit to what it was originally</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">if</span> <span style="color: #008080;">not</span> <span style="color: #000000;">primeable</span> <span style="color: #008080;">then</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">lastDigit</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">le</span><span style="color: #0000FF;">]-</span><span style="color: #008000;">'0'</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">firstNum</span><span style="color: #0000FF;">[</span><span style="color: #000000;">lastDigit</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">==</span> <span style="color: #000000;">0</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">firstNum</span><span style="color: #0000FF;">[</span><span style="color: #000000;">lastDigit</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">i</span>
<span style="color: #000000;">countFirst</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #000000;">count</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">count</span> <span style="color: #0000FF;"><=</span> <span style="color: #000000;">35</span> <span style="color: #008080;">then</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%d "</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">elsif</span> <span style="color: #000000;">count</span> <span style="color: #0000FF;">==</span> <span style="color: #000000;">600</span> <span style="color: #008080;">then</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"\n\nThe 600th unprimeable number is: %,d\n\n"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">i</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">if</span> <span style="color: #7060A8;">platform</span><span style="color: #0000FF;">()!=</span><span style="color: #004600;">JS</span> <span style="color: #008080;">and</span> <span style="color: #7060A8;">time</span><span style="color: #0000FF;">()></span><span style="color: #000000;">t1</span> <span style="color: #008080;">then</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"checking %d, %d `endswiths` found\r"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">i</span><span style="color: #0000FF;">,</span><span style="color: #000000;">countFirst</span><span style="color: #0000FF;">})</span>
<span style="color: #000000;">t1</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">time</span><span style="color: #0000FF;">()+</span><span style="color: #000000;">1</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #000000;">i</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"The first unprimeable number that ends in:\n"</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">10</span> <span style="color: #008080;">do</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">" %d is: %,9d\n"</span><span style="color: #0000FF;">,</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">i</span><span style="color: #0000FF;">-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">firstNum</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]})</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #0000FF;">?</span><span style="color: #7060A8;">elapsed</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">time</span><span style="color: #0000FF;">()-</span><span style="color: #000000;">t0</span><span style="color: #0000FF;">)</span>
<!--

View file

@ -0,0 +1,39 @@
bool is_unprimeable(int i)
{
string s = i->digits();
for(int offset; offset < sizeof(s); offset++) {
foreach("0123456789"/1, string repl) {
array chars = s/1;
chars[offset] = repl;
int testme = (int)(chars*"");
if( testme->probably_prime_p() )
return false;
}
}
return true;
}
void main()
{
int i, count;
array unprimes = ({});
mapping first_enders = ([]); // first unprimeable ending with each digit
while(sizeof(first_enders) != 10) {
i++;
if( is_unprimeable(i) ) {
count++;
unprimes += ({ i });
string last_digit = i->digits()[<0..];
if( !first_enders[last_digit] )
first_enders[last_digit] = i;
}
werror("%d\r", i); // Progress output
}
write("First 35 unprimeables: %s\n\n", (array(string))unprimes[0..34]*" ");
write("The 600th unprimeable is %d\n\n", unprimes[599]);
write("The first unprimeable number that ends in\n");
foreach(sort(indices(first_enders)), string e) {
write(" %s is: %9d\n", e, first_enders[e]);
}
}

View file

@ -0,0 +1,52 @@
from itertools import count, islice
def primes(_cache=[2, 3]):
yield from _cache
for n in count(_cache[-1]+2, 2):
if isprime(n):
_cache.append(n)
yield n
def isprime(n, _seen={0: False, 1: False}):
def _isprime(n):
for p in primes():
if p*p > n:
return True
if n%p == 0:
return False
if n not in _seen:
_seen[n] = _isprime(n)
return _seen[n]
def unprime():
for a in count(1):
d = 1
while d <= a:
base = (a//(d*10))*(d*10) + (a%d) # remove current digit
if any(isprime(y) for y in range(base, base + d*10, d)):
break
d *= 10
else:
yield a
print('First 35:')
print(' '.join(str(i) for i in islice(unprime(), 35)))
print('\nThe 600-th:')
print(list(islice(unprime(), 599, 600))[0])
print()
first, need = [False]*10, 10
for p in unprime():
i = p%10
if first[i]: continue
first[i] = p
need -= 1
if not need:
break
for i,v in enumerate(first):
print(f'{i} ending: {v}')

View file

@ -0,0 +1,68 @@
/*REXX program finds and displays unprimeable numbers (non─negative integers). */
parse arg n x hp . /*obtain optional arguments from the CL*/
if n=='' | n=="," then n= 35 /*Not specified? Then use the default.*/
if x=='' | x=="," then x= 600 /* " " " " " " */
if hp=='' | hp=="," then hp= 10000000 /* " " " " " " */
u= 0 /*number of unprimeable numbers so far.*/
eds=4; ed.1= 1; ed.2= 3; ed.3= 7; ed.4= 9 /*"end" digits which are prime; prime>9*/
call genP hp /*generate primes up to & including HP.*/
$$=; $.=. /*a list " " " " " */
do j=100; if !.j then iterate /*Prime? Unprimeable must be composite*/
Lm= length(j) /*obtain the length-1 of the number J. */
meat= left(j, Lm) /*obtain the first Lm digits of J. */
/* [↑] examine the "end" digit of J. */
do e_=1 for eds; new= meat || ed.e_ /*obtain a different number (than J).*/
if new==j then iterate /*Is it the original number? Then skip.*/
if !.new then iterate j /*This new number a prime? " " */
end /*e_*/
/* [↑] examine a new 1st digit of J. */
do f_=0 for 10; new= (f_||meat) + 0 /*obtain a different number (than J).*/
if new==j then iterate /*Is it the original number? Then skip.*/
if !.new then iterate j /*This new number a prime? " " */
end /*f_*/ /* [↑] examine the front digit of J. */
do a_= 2 for Lm-1 /*traipse through the middle digits. */
meat= left(j, a_ - 1) /*use a number of left─most dec. digits*/
rest= substr(j, a_ + 1) /* " " " " right─most " " */
do n_=0 for 10 /*traipse through all 1─digit numbers. */
new= meat || n_ || rest /*construct new number, like a phoenix.*/
if new==j then iterate /*Is it the original number? Then skip.*/
if !.new then iterate j /*This new number a prime? " " */
end /*n_*/
end /*a_*/
u= u + 1 /*bump the count of unprimeable numbers*/
if u<=n then $$= $$ commas(j) /*maybe add unprimeable # to $$ list.*/
if u==x then $.ox= commas(j) /*assign the Xth unprimeable number.*/
parse var j '' -1 _ /*obtain the right─most dec digit of J.*/
if $._==. then $._= j /*the 1st unprimeable # that ends in _.*/
if $.3==. then iterate; if $.7==. then iterate /*test if specific #'s found.*/
if $.1==. then iterate; if $.9==. then iterate /* " " " " " */
leave /*if here, then we're done. */
end /*j*/
if n>0 then do; say center(' first ' n "unprimeable numbers ", 139, '')
say strip($$); say
end
if x>0 then say ' the ' th(x) " unprimeable number is: " $.ox
say
do o=0 for 10; if length($.o)==0 then iterate
say ' the first unprimeable number that ends in ' o " is:"right(commas($.o),11)
end /*o*/
exit /*stick a fork in it, we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
commas: parse arg ?; do c=length(?)-3 to 1 by -3; ?=insert(',', ?, c); end; return ?
th:procedure;parse arg x;return x||word('th st nd rd',1+(x//10)*(x//100%10\==1)*(x//10<4))
/*──────────────────────────────────────────────────────────────────────────────────────*/
genP: @.1=2; @.2=3; @.3=5; @.4=7; @.5=11; @.6=13; @.7=17; @.8=19; @.9=23; @.10=29; @.11=31
!.=0; !.2=1; !.3=1; !.5=1; !.7=1; !.11=1; !.13=1; !.17=1; !.19=1; !.23=1; !.29=1
#= 11; sq.#= @.# **2
do lim=100 until lim*lim>=hp /*only keep primes up to the sqrt(hp). */
end /*lim*/ /* [↑] find limit for storing primes. */
do j=@.#+2 by 2 to hp; parse var j '' -1 _; if _==5 then iterate /*÷ by 5?*/
if j// 3==0 then iterate; if j// 7==0 then iterate; if j//11==0 then iterate
if j//13==0 then iterate; if j//17==0 then iterate; if j//19==0 then iterate
if j//23==0 then iterate; if j//29==0 then iterate
do k=11 while sq.k<=j /*divide by some generated odd primes. */
if j//@.k==0 then iterate j /*Is J divisible by P? Then not prime*/
end /*k*/ /* [↓] a prime (J) has been found. */
#= #+1; if #<=lim then @.#=j; !.j=1 /*bump prime count; assign prime to @. */
sq.#= j*j /*calculate square of J for fast WHILE.*/

View file

@ -0,0 +1,47 @@
#lang racket
(require math/number-theory)
(define cached-prime?
(let ((hsh# (make-hash))) (λ (p) (hash-ref! hsh# p (λ () (prime? p))))))
(define (zero-digit n d)
(define p (expt 10 d))
(+ (remainder n p) (* 10 p (quotient n (* p 10)))))
(define (primeable? n)
(or (cached-prime? n)
(for*/first ((d (in-range (add1 (order-of-magnitude n))))
(n0 (in-value (zero-digit n d)))
(p (in-value (expt 10 d)))
(r (in-range 10))
(n+ (in-value (+ n0 (* r p))))
#:when (cached-prime? n+))
n+)))
(define unprimeable? (negate primeable?))
(module+
main
(printf "First 35 unprimeable numbers: ~a~%"
(let recur ((i 0) (n 1) (acc null))
(cond [(= i 35) (reverse acc)]
[(unprimeable? n) (recur (add1 i) (add1 n) (cons n acc))]
[else (recur i (add1 n) acc)])))
(printf "600th unprimeable number: ~a~%"
(let recur ((i 0) (n 1) (u #f))
(cond [(= i 600) u]
[(unprimeable? n) (recur (add1 i) (add1 n) n)]
[else (recur i (add1 n) u)])))
(for ((d 10))
(printf "Least unprimeable number ending in ~a = ~a~%" d
(for/first ((i (in-range (+ 100 d) +Inf.0 10)) #:when (unprimeable? i)) i))))
(module+ test
(require rackunit)
(check-equal? (zero-digit 1234 2) 1034)
(check-equal? (primeable? 10) 11)
(check-true (unprimeable? 200))
(check-false (unprimeable? 201)))

View file

@ -0,0 +1,27 @@
use ntheory:from<Perl5> <is_prime>;
use Lingua::EN::Numbers;
sub is-unprimeable (\n) {
return False if n.&is_prime;
my \chrs = n.chars;
for ^chrs -> \place {
my \pow = 10**(chrs - place - 1);
my \this = n.substr(place, 1) × pow;
^10 .map: -> \dgt {
next if this == dgt;
return False if is_prime(n - this + dgt × pow)
}
}
True
}
my @ups = lazy ^ .grep: { .&is-unprimeable };
say "First 35 unprimeables:\n" ~ @ups[^35];
say "\n{ordinal-digit(600, :u)} unprimeable: " ~ comma( @ups[599] ) ~ "\n";
^10 .map: -> \n {
print "First unprimeable that ends with {n}: " ~
sprintf "%9s\n", comma (n, *+10 *).race.first: { .&is-unprimeable }
}

View file

@ -0,0 +1,24 @@
require 'prime'
def unprimable?(n)
digits = %w(0 1 2 3 4 5 6 7 8 9)
s = n.to_s
size = s.size
(size-1).downto(0) do |i|
digits.each do |d|
cand = s.dup
cand[i]=d
return false if cand.to_i.prime?
end
end
true
end
ups = Enumerator.new {|y| (1..).each{|n| y << n if unprimable?(n)} }
ar = ups.first(600)
puts "First 35 unprimables:", ar[0,35].join(" ")
puts "\n600th unprimable:", ar.last, ""
(0..9).each do |d|
print "First unprimeable with last digit #{d}: "
puts (1..).detect{|k| unprimable?(k*10+d)}*10 + d
end

View file

@ -0,0 +1,77 @@
// main.rs
mod bit_array;
mod prime_sieve;
use prime_sieve::PrimeSieve;
// return number of decimal digits
fn count_digits(mut n: u32) -> u32 {
let mut digits = 0;
while n > 0 {
n /= 10;
digits += 1;
}
digits
}
// return the number with one digit replaced
fn change_digit(mut n: u32, mut index: u32, new_digit: u32) -> u32 {
let mut p = 1;
let mut changed = 0;
while index > 0 {
changed += p * (n % 10);
p *= 10;
n /= 10;
index -= 1;
}
changed += (10 * (n / 10) + new_digit) * p;
changed
}
fn unprimeable(sieve: &PrimeSieve, n: u32) -> bool {
if sieve.is_prime(n as usize) {
return false;
}
let d = count_digits(n);
for i in 0..d {
for j in 0..10 {
let m = change_digit(n, i, j);
if m != n && sieve.is_prime(m as usize) {
return false;
}
}
}
true
}
fn main() {
let mut count = 0;
let mut n = 100;
let mut lowest = vec![0; 10];
let mut found = 0;
let sieve = PrimeSieve::new(10000000);
println!("First 35 unprimeable numbers:");
while count < 600 || found < 10 {
if unprimeable(&sieve, n) {
if count < 35 {
if count > 0 {
print!(", ");
}
print!("{}", n);
}
count += 1;
if count == 600 {
println!("\n600th unprimeable number: {}", n);
}
let last_digit = n as usize % 10;
if lowest[last_digit] == 0 {
lowest[last_digit] = n;
found += 1;
}
}
n += 1;
}
for i in 0..10 {
println!("Least unprimeable number ending in {}: {}", i, lowest[i]);
}
}

View file

@ -0,0 +1,36 @@
// prime_sieve.rs
use crate::bit_array;
pub struct PrimeSieve {
composite: bit_array::BitArray,
}
impl PrimeSieve {
pub fn new(limit: usize) -> PrimeSieve {
let mut sieve = PrimeSieve {
composite: bit_array::BitArray::new(limit / 2),
};
let mut p = 3;
while p * p <= limit {
if !sieve.composite.get(p / 2 - 1) {
let inc = p * 2;
let mut q = p * p;
while q <= limit {
sieve.composite.set(q / 2 - 1, true);
q += inc;
}
}
p += 2;
}
sieve
}
pub fn is_prime(&self, n: usize) -> bool {
if n < 2 {
return false;
}
if n % 2 == 0 {
return n == 2;
}
!self.composite.get(n / 2 - 1)
}
}

View file

@ -0,0 +1,24 @@
// bit_array.rs
pub struct BitArray {
array: Vec<u32>,
}
impl BitArray {
pub fn new(size: usize) -> BitArray {
BitArray {
array: vec![0; (size + 31) / 32],
}
}
pub fn get(&self, index: usize) -> bool {
let bit = 1 << (index & 31);
(self.array[index >> 5] & bit) != 0
}
pub fn set(&mut self, index: usize, new_val: bool) {
let bit = 1 << (index & 31);
if new_val {
self.array[index >> 5] |= bit;
} else {
self.array[index >> 5] &= !bit;
}
}
}

View file

@ -0,0 +1,32 @@
func is_unprimeable(n) {
var t = 10*floor(n/10)
for k in (t+1 .. t+9 `by` 2) {
return false if k.is_prime
}
if (n.is_div(2) || n.is_div(5)) {
return true if !is_prime(n%10)
return true if (n % 10**n.ilog(10) > 9)
}
for k in (1 .. n.ilog(10)) {
var u = 10**k
var v = (n - (u * (floor(n/u) % 10)))
0..9 -> any {|d| is_prime(v + d*u) } && return false
}
return true
}
with (35) {|n|
say ("First #{n} unprimeables:\n", is_unprimeable.first(n).join(' '))
}
with (600) {|n|
say ("\n#{n}th unprimeable: ", is_unprimeable.nth(n), "\n")
}
for d in (0..9) {
say ("First unprimeable that ends with #{d}: ",
1..Inf -> lazy.map {|k| k*10 + d }.grep(is_unprimeable).first)
}

View file

@ -0,0 +1,127 @@
import Foundation
class BitArray {
var array: [UInt32]
init(size: Int) {
array = Array(repeating: 0, count: (size + 31)/32)
}
func get(index: Int) -> Bool {
let bit = UInt32(1) << (index & 31)
return (array[index >> 5] & bit) != 0
}
func set(index: Int, value: Bool) {
let bit = UInt32(1) << (index & 31)
if value {
array[index >> 5] |= bit
} else {
array[index >> 5] &= ~bit
}
}
}
class PrimeSieve {
let composite: BitArray
init(size: Int) {
composite = BitArray(size: size/2)
var p = 3
while p * p <= size {
if !composite.get(index: p/2 - 1) {
let inc = p * 2
var q = p * p
while q <= size {
composite.set(index: q/2 - 1, value: true)
q += inc
}
}
p += 2
}
}
func isPrime(number: Int) -> Bool {
if number < 2 {
return false
}
if (number & 1) == 0 {
return number == 2
}
return !composite.get(index: number/2 - 1)
}
}
// return number of decimal digits
func countDigits(number: Int) -> Int {
var digits = 0
var n = number
while n > 0 {
n /= 10
digits += 1
}
return digits
}
// return the number with one digit replaced
func changeDigit(number: Int, index: Int, digit: Int) -> Int {
var p = 1
var changed = 0
var n = number
var i = index
while i > 0 {
changed += p * (n % 10)
p *= 10
n /= 10
i -= 1
}
changed += (10 * (n / 10) + digit) * p
return changed
}
func unprimeable(sieve: PrimeSieve, number: Int) -> Bool {
if sieve.isPrime(number: number) {
return false
}
for i in 0..<countDigits(number: number) {
for j in 0..<10 {
let n = changeDigit(number: number, index: i, digit: j)
if n != number && sieve.isPrime(number: n) {
return false
}
}
}
return true
}
var count = 0
var n = 100
var lowest = Array(repeating: 0, count: 10)
var found = 0
let sieve = PrimeSieve(size: 10000000)
print("First 35 unprimeable numbers:")
while count < 600 || found < 10 {
if unprimeable(sieve: sieve, number: n) {
if count < 35 {
if count > 0 {
print(", ", terminator: "")
}
print(n, terminator: "")
}
count += 1
if count == 600 {
print("\n600th unprimeable number: \(n)")
}
let lastDigit = n % 10
if lowest[lastDigit] == 0 {
lowest[lastDigit] = n
found += 1
}
}
n += 1
}
for i in 0..<10 {
let number = NSNumber(value: lowest[i])
let str = NumberFormatter.localizedString(from: number, number: .decimal)
print("Least unprimeable number ending in \(i): \(str)")
}

View file

@ -0,0 +1,46 @@
import "/fmt" for Fmt
import "/math" for Int
System.print("The first 35 unprimeable numbers are:")
var count = 0 // counts all unprimeable numbers
var firstNum = List.filled(10, 0) // stores the first unprimeable number ending with each digit
var i = 100
var countFirst = 0
while (countFirst < 10) {
if (!Int.isPrime(i)) { // unprimeable number must be composite
var s = "%(i)"
var le = s.count
var b = s.bytes.toList
var outer = false
for (j in 0...le) {
for (k in 48..57) {
if (s[j].bytes[0] != k) {
b[j] = k
var bb = b.reduce("") { |acc, byte| acc + String.fromByte(byte) }
var n = Num.fromString(bb)
if (Int.isPrime(n)) {
outer = true
break
}
}
}
if (outer) break
b[j] = s[j].bytes[0] // restore j'th digit to what it was originally
}
if (!outer) {
var lastDigit = s[-1].bytes[0] - 48
if (firstNum[lastDigit] == 0) {
firstNum[lastDigit] = i
countFirst = countFirst + 1
}
count = count + 1
if (count <= 35) System.write("%(i) ")
if (count == 35) System.write("\n\nThe 600th unprimeable number is: ")
if (count == 600) System.print("%(Fmt.dc(0, i))\n")
}
}
i = i + 1
}
System.print("The first unprimeable number that ends in:")
for (i in 0...10) System.print(" %(i) is: %(Fmt.dc(9, firstNum[i]))")

View file

@ -0,0 +1,59 @@
func IsPrime(N); \Return 'true' if N is prime
int N, I;
[if N <= 2 then return N = 2;
if (N&1) = 0 then \even >2\ return false;
for I:= 3 to sqrt(N) do
[if rem(N/I) = 0 then return false;
I:= I+1;
];
return true;
];
func Unprimeable(N); \Return 'true' if N is unprimeable
int N, I, J, Len, D, SD;
char Num(10);
[I:= 0; \take N apart
repeat N:= N/10;
Num(I):= rem(0);
I:= I+1;
until N = 0;
Len:= I; \number of digits in N (length)
for J:= 0 to Len-1 do
[SD:= Num(J); \save digit
for D:= 0 to 9 do \replace with all digits
[Num(J):= D;
N:= 0; \rebuild N
for I:= Len-1 downto 0 do
N:= N*10 + Num(I);
if IsPrime(N) then return false;
];
Num(J):= SD; \restore saved digit
];
return true;
];
int C, N, D;
[Text(0, "First 35 unprimeables:^m^j");
C:= 0;
N:= 100;
loop [if Unprimeable(N) then
[C:= C+1;
if C <= 35 then
[IntOut(0, N); ChOut(0, ^ )];
if C = 600 then quit;
];
N:= N+1;
];
Text(0, "^m^j600th unprimeable: ");
IntOut(0, N); CrLf(0);
for D:= 0 to 9 do
[IntOut(0, D); Text(0, ": ");
N:= 100 + D;
loop [if Unprimeable(N) then
[IntOut(0, N); CrLf(0);
quit;
];
N:= N+10;
];
];
]

View file

@ -0,0 +1,16 @@
var [const] BI=Import("zklBigNum"); // libGMP
fcn isUnprimeable(n){ //--> n (!0) or Void, a filter
bn,t := BI(0),n/10*10;
foreach k in ([t+1..t+9,2]){ if(bn.set(k).probablyPrime()) return(Void.Skip) }
if(n==n/2*2 or n==n/5*5){
if(not bn.set(n%10).probablyPrime()) return(n);
if( (n % (10).pow(n.toFloat().log10()) ) > 9) return(n);
}
foreach k in ([1 .. n.toFloat().log10()]){
u,v := (10).pow(k), (n - (u * ((n/u) % 10)));
foreach d in (10){ if(bn.set(v + d*u).probablyPrime()) return(Void.Skip); }
}
n
}
fcn isUnprimeableW{ [100..].tweak(isUnprimeable) } // --> iterator

View file

@ -0,0 +1,8 @@
isUnprimeableW().walk(35).concat(" ").println();
println("The 600th unprimeable number is: %,d".fmt(isUnprimeableW().drop(600).value));
s,ups := 10, List.createLong(10,0);
foreach up in (isUnprimeableW())
{ d:=up%10; if(ups[d]==0){ ups[d]=up; if((s-=1)<=0) break; } }
println("The first unprimeable number that ends in:");
foreach n in (10){ println("%d is %8,d".fmt(n,ups[n])) }