September 2017 Update

This commit is contained in:
Ingy döt Net 2017-09-23 10:01:46 +02:00
parent bba7bfd280
commit ba8067c3b7
14570 changed files with 153136 additions and 63871 deletions

View file

@ -5,10 +5,13 @@ A truncatable prime is a prime number that when you successively remove digits f
The task is to find the largest left-truncatable and right-truncatable primes less than one million (base 10 is implied).
;C.f:
;Related tasks:
* [[Find largest left truncatable prime in a given base]]
* [[Sieve of Eratosthenes]]
* [http://mathworld.wolfram.com/TruncatablePrime.html Truncatable Prime] from Mathworld.
;See also:
* [http://mathworld.wolfram.com/TruncatablePrime.html Truncatable Prime] from MathWorld.
<br>
[[:Category: Prime_Numbers]]

View file

@ -1,78 +1,95 @@
#import system.
#import extensions.
import system'calendar.
import extensions.
#symbol MAXN = 1000000.
const MAXN = 1000000.
#class(extension)mathOp
extension mathOp
{
#method is &prime
isPrime
[
#var(type:int)n := self int.
int n := self int.
(n < 2) ? [ ^ false. ].
(n < 4) ? [ ^ true. ].
(n mod:2 == 0) ? [ ^ false. ].
(n < 9) ? [ ^ true. ].
(n mod:3 == 0) ? [ ^ false. ].
if (n < 2) [ ^ false. ].
if (n < 4) [ ^ true. ].
if (n mod:2 == 0) [ ^ false. ].
if (n < 9) [ ^ true. ].
if (n mod:3 == 0) [ ^ false. ].
#var(type:int)r := n sqrt.
#var(type:int)f := 5.
#loop (f <= r)?
int r := n sqrt.
int f := 5.
while (f <= r)
[
((n mod:f == 0) || (n mod:(f + 2) == 0))
? [ ^ false. ].
f := f + 6.
if ((n mod:f == 0) || (n mod:(f + 2) == 0))
[ ^ false ].
f := f + 6
].
^ true
]
isRightTruncatable
[
int n := self.
while (n != 0)
[
ifnot (n isPrime)
[ ^ false ].
n := n / 10
].
^ true.
]
#method is &rightTruncatable
isLeftTruncatable
[
#var(type:int)n := self int.
#loop (n != 0)?
[
(n is &prime)
! [ ^ false. ].
n := n / 10.
].
^ true.
]
int n := self.
int tens := 1.
#method is &leftTruncatable
[
#var(type:int)n := self int.
#var(type:int)tens := 1.
#loop (tens < n)
? [ tens := tens * 10. ].
while (tens < n)
[ tens := tens * 10. ].
#loop (n != 0)?
while (n != 0)
[
(n is &prime)
! [ ^ false. ].
ifnot (n isPrime)
[ ^ false ].
tens := tens / 10.
n := n - (n / tens * tens).
n := n - (n / tens * tens)
].
^ true.
^ true
]
}
#symbol program =
program =
[
#var n := MAXN.
#var max_lt := 0.
#var max_rt := 0.
#loop ((max_lt == 0) || (max_rt == 0))?
var n := MAXN.
var max_lt := 0.
var max_rt := 0.
while ((max_lt == 0) || (max_rt == 0))
[
(n literal indexOf:"0" == -1) ?
if(n literal; indexOf:"0" == -1)
[
((max_lt == 0) and:[ n is &leftTruncatable ])
? [ max_lt := n. ].
((max_rt == 0) and:[ n is &rightTruncatable ])
? [ max_rt := n. ].
if ((max_lt == 0) && $(n isLeftTruncatable))
[
max_lt := n.
].
if ((max_rt == 0) && $(n isRightTruncatable))
[
max_rt := n.
].
].
n := n - 1.
].
console writeLine:"Largest truncable left is ":max_lt.
console writeLine:"Largest truncable right is ":max_rt.
console printLine("Largest truncable left is ",max_lt).
console printLine("Largest truncable right is ",max_rt).
console readChar.
].

View file

@ -0,0 +1,56 @@
' FB 1.05.0 Win64
Function isPrime(n As Integer) As Boolean
If n Mod 2 = 0 Then Return n = 2
If n Mod 3 = 0 Then Return n = 3
Dim d As Integer = 5
While d * d <= n
If n Mod d = 0 Then Return False
d += 2
If n Mod d = 0 Then Return False
d += 4
Wend
Return True
End Function
Dim As UInteger i, j, p, pow, lMax = 2, rMax = 2
Dim s As String
' largest left truncatable prime less than 1000000
' It can't end with 1, 4, 6, 8 or 9 as these numbers are not prime
' Nor can it end in 2 if it has more than one digit as such a number would divide by 2
For i = 3 To 999997 Step 2
s = Str(i)
If Instr(s, "0") > 1 Then Continue For '' cannot contain 0
j = s[Len(s) - 1] - 48
If j = 1 OrElse j = 9 Then Continue For
p = i
pow = 10 ^ (Len(s) - 1)
While pow > 1
If Not isPrime(p) Then Continue For
p Mod= pow
pow \= 10
Wend
lMax = i
Next
' largest right truncatable prime less than 1000000
' It can't begin with 1, 4, 6, 8 or 9 as these numbers are not prime
For i = 3 To 799999 Step 2
s = Str(i)
If Instr(s, "0") > 1 Then Continue For '' cannot contain 0
j = s[0] - 48
If j = 1 OrElse j = 4 OrElse j = 6 Then Continue For
p = i
While p > 0
If Not isPrime(p) Then Continue For
p \= 10
Wend
rMax = i
Next
Print "Largest left truncatable prime : "; lMax
Print "Largest right truncatable prime : "; rMax
Print
Print "Press any key to quit"
Sleep

View file

@ -0,0 +1,83 @@
' version 10-12-2016
' compile with: fbc -s console
Dim Shared As Byte isPrime()
Sub sieve(m As UInteger)
Dim As Integer i, j
ReDim isPrime(m)
For i = 4 To m Step 2
isPrime(i) = 1
Next
For i = 3 To Sqr(m) Step 2
If isPrime(i) = 0 Then
For j = i * i To m Step i * 2
isPrime(j) = 1
Next
End If
Next
End Sub
' ------=< MAIN >=------
#Define max 1000000 'upto 2^30 max for 32bit OS
Dim As UInteger a(), lt_prime(5000), rt_prime(100)
Dim As UInteger i, j, j1, p1, p2, left_max, right_max
sieve(max)
' left truncatable primes
' if odd and ends with 3 or 7, never ends 1 or 9 (no prime
' never ends on a 2 or 5 and starts with 1 to 9
lt_prime(1) = 3 : lt_prime(2) = 7
p1 = 1 : p2 = 2
Do
For i = 1 To 9
j = Val( Str(i) + Str(lt_prime(p1)) )
If j > max Then Exit Do
If isPrime(j) = 0 Then ' if prime then add to the list
p2 += 1
lt_prime(p2) = j
If Left_max < j Then left_max = j
End If
Next
p1 += 1
Loop Until p1 > p2 ' no more numbers to process
' right truncatable prime
' start with 2, 3, 5 or 7 and end with 1, 3, 7 or 9
rt_prime(1) = 2 : rt_prime(2) = 3 : rt_prime(3) = 5 : rt_prime(4) = 7
p1 = 1 : p2 = 4
Dim As UInteger end_num(1 To 4) => {1, 3, 7, 9}
Do
j1 = rt_prime(p1) * 10
If j1 > max Then Exit Do
For i = 1 To 4
j = j1 + End_num(i)
If isprime(j) = 0 Then ' if prime then add to the list
p2 += 1
rt_prime(p2) = j
' If right_max < j Then right_max = j
End If
Next
p1 += 1
Loop Until p1 > p2 ' no more numbers to process
' the last one added is the biggest
right_max = rt_prime(p2)
Print
Print "The biggest left truncatable prime below"; max; " is "; left_max
Print "The biggest right truncatable prime below"; max; " is "; right_max
' empty keyboard buffer
While Inkey <> "" : Wend
Print : Print "hit any key to end program"
Sleep
End

View file

@ -0,0 +1,58 @@
// version 1.0.5-2
fun isPrime(n: Int) : Boolean {
if (n < 2) return false
if (n % 2 == 0) return n == 2
if (n % 3 == 0) return n == 3
var d : Int = 5
while (d * d <= n) {
if (n % d == 0) return false
d += 2
if (n % d == 0) return false
d += 4
}
return true
}
fun main(args: Array<String>) {
var j: Char
var p: Int
var pow: Int
var lMax: Int = 2
var rMax: Int = 2
var s: String
// calculate maximum left truncatable prime less than 1 million
loop@ for( i in 3..999997 step 2) {
s = i.toString()
if ('0' in s) continue
j = s[s.length - 1]
if (j == '1' || j == '9') continue
p = i
pow = 1
for (k in 1..s.length - 1) pow *= 10
while(pow > 1) {
if (!isPrime(p)) continue@loop
p %= pow
pow /= 10
}
lMax = i
}
// calculate maximum right truncatable prime less than 1 million
loop@ for( i in 3..799999 step 2) {
s = i.toString()
if ('0' in s) continue
j = s[0]
if (j == '1' || j == '4' || j == '6') continue
p = i
while(p > 0) {
if (!isPrime(p)) continue@loop
p /= 10
}
rMax = i
}
println("Largest left truncatable prime : " + lMax.toString())
println("Largest right truncatable prime : " + rMax.toString())
}

View file

@ -1,6 +1,6 @@
import sets, strutils, algorithm
proc primes(n): seq[int64] =
proc primes(n: int64): seq[int64] =
result = @[]
var multiples = initSet[int64]()
for i in 2..n:
@ -9,7 +9,7 @@ proc primes(n): seq[int64] =
for j in countup(i*i, n, i.int):
multiples.incl j
proc truncatablePrime(n): tuple[left: int64, right: int64] =
proc truncatablePrime(n: int64): tuple[left: int64, right: int64] =
var
primelist: seq[string] = @[]
for x in primes(n):
@ -18,14 +18,14 @@ proc truncatablePrime(n): tuple[left: int64, right: int64] =
var primeset = toSet primelist
for n in primelist:
var alltruncs = initSet[string]()
for i in 0..n.len:
alltruncs.incl n[1..n.high]
for i in 0..n.len-1:
alltruncs.incl n[i..n.high]
if alltruncs <= primeset:
result.left = parseInt(n)
break
for n in primelist:
var alltruncs = initSet[string]()
for i in 0..n.len:
for i in 0..n.len-1:
alltruncs.incl n[0..i]
if alltruncs <= primeset:
result.right = parseInt(n)

View file

@ -0,0 +1,64 @@
-- find largest left- & right-truncatable primes < 1 million.
-- an initial set of primes (not, at this time, we leave out 2 because
-- we'll automatically skip the even numbers. No point in doing a needless
-- test each time through
primes = .array~of(3, 5, 7, 11)
-- check all of the odd numbers up to 1,000,000
loop j = 13 by 2 to 1000000
loop i = 1 to primes~size
prime = primes[i]
-- found an even prime divisor
if j // prime == 0 then iterate j
-- only check up to the square root
if prime*prime > j then leave
end
-- we only get here if we don't find a divisor
primes~append(j)
end
-- get a set of the primes that we can test more efficiently
primeSet = .set~of(2)
primeSet~putall(primes)
say 'The last prime is' primes[primes~last] "("primeSet~items 'primes under one million).'
say copies('-',66)
lastLeft = 0
-- we're going to use the array version to do these in order. We're still
-- missing "2", but that's not going to be the largest
loop prime over primes
-- values containing 0 can never work
if prime~pos(0) \= 0 then iterate
-- now start the truncations, checking against our set of
-- known primes
loop i = 1 for prime~length - 1
subprime = prime~right(i)
-- not in our known set, this can't work
if \primeset~hasIndex(subprime) then iterate prime
end
-- this, by definition, with be the largest left-trunc prime
lastLeft = prime
end
-- now look for right-trunc primes
lastRight = 0
loop prime over primes
-- values containing 0 can never work
if prime~pos(0) \= 0 then iterate
-- now start the truncations, checking against our set of
-- known primes
loop i = 1 for prime~length - 1
subprime = prime~left(i)
-- not in our known set, this can't work
if \primeset~hasIndex(subprime) then iterate prime
end
-- this, by definition, with be the largest left-trunc prime
lastRight = prime
end
say 'The largest left-truncatable prime is' lastLeft '(under one million).'
say 'The largest right-truncatable prime is' lastRight '(under one million).'

View file

@ -0,0 +1,38 @@
constant N = 6, limit = power(10,N)
-- standard sieve:
enum L,R -- (with primes[i] as mini bit-field)
sequence primes = repeat(L+R, limit)
primes[1] = 0
for i=2 to floor(sqrt(limit)) do
if primes[i] then
for k=i*i to limit by i do
primes[k] = 0
end for
end if
end for
-- propagate non-truncateables up the prime table:
for p=1 to N-1 do
integer p10 = power(10,p) -- ie 10, 100, .. 100_000
for i=p10+1 to p10*10-1 by 2 do -- to 99, 999, .. 999_999
if primes[i] then
integer l = remainder(i,p10),
r = floor(i/10)
integer pi = and_bits(primes[l],L)+and_bits(primes[r],R)
if pi and find('0',sprint(i)) then pi = 0 end if
primes[i] = pi
end if
end for
end for
integer maxl=0, maxr=0
for i=limit-1 to 1 by -2 do
integer pi = primes[i]
if pi then
if maxl=0 and and_bits(pi,L) then maxl = i end if
if maxr=0 and and_bits(pi,R) then maxr = i end if
if maxl!=0 and maxr!=0 then exit end if
end if
end for
?{maxl,maxr}

View file

@ -5,7 +5,7 @@ parse arg high .; if high=='' then high=1000000 /*Not specified? The
!.2=1; !.3=1; !.5=1; !.7=1; !.11=1; !.13=1; !.17=1 /*set some low prime flags. */
#=7; s.#=@.#**2 /*number of primes so far; prime². */
/* [↓] generate more primes ≤ high.*/
do j=@.#+2 by 2 to high /*only find odd primes from here on out*/
do j=@.#+2 by 2 for max(0, high%2-@.#%2-1) /*only find odd primes from here on out*/
if j// 3==0 then iterate /*is J divisible by three? */
parse var j '' -1 _; if _==5 then iterate /* " " " " five? (right digit)*/
if j// 7==0 then iterate /* " " " " seven? */
@ -13,8 +13,8 @@ parse arg high .; if high=='' then high=1000000 /*Not specified? The
if j//13==0 then iterate /* " " " " thirteen? */
/* [↑] the above five lines saves time*/
do k=7 while s.k<=j /* [↓] divide by the known odd primes.*/
if j//@.k==0 then iterate j /*Is J divisible by X? Then not prime.*/
end /*k*/
if j//@.k==0 then iterate j /*Is J ÷ X? Then not prime. ___ */
end /*k*/ /* [↑] only process up to the √ J */
#=#+1 /*bump the number of primes found. */
@.#=j; s.#=j*j; !.j=1 /*assign next prime; prime²; prime #.*/
end /*j*/

View file

@ -0,0 +1,15 @@
const million=0d1_000_000;
var pTable=Data(million+1,Int).fill(0); // actually bytes, all zero
primes:=Utils.Generator(Import("sieve").postponed_sieve);
while((p:=primes.next())<million){ pTable[p]=1; }
fcn rightTrunc(n){
while(n){ if(not pTable[n]) return(False); n/=10; }
True
}
fcn leftTrunc(n){ // 999,907 is not allowed
ns:=n.toString(); if (ns.holds("0")) return(False);
while(ns){ if(not pTable[ns]) return(False); ns=ns[1,*]; }
True
}

View file

@ -0,0 +1,4 @@
[million..0,-1].filter1(rightTrunc):
"%,d is a right truncatable prime".fmt(_).println();
[million..0,-1].filter1(leftTrunc):
"%,d is a left truncatable prime".fmt(_).println();