Pierpont primes
A Pierpont prime is a prime number of the form: 2u3v + 1 for some non-negative integers u and v .
A Pierpont prime of the second kind is a prime number of the form: 2u3v - 1 for some non-negative integers u and v .
The term "Pierpont primes" is generally understood to mean the first definition, but will be called "Pierpont primes of the first kind" on this page to distinguish them.
- Task
- Write a routine (function, procedure, whatever) to find Pierpont primes of the first & second kinds.
- Use the routine to find and display here, on this page, the first 50 Pierpont primes of the first kind.
- Use the routine to find and display here, on this page, the first 50 Pierpont primes of the second kind
- If your language supports large integers, find and display here, on this page, the 250th Pierpont prime of the first kind and the 250th Pierpont prime of the second kind.
- See also
Factor
<lang factor>USING: fry grouping io kernel locals make math math.functions math.primes prettyprint sequences sorting ;
- pierpont ( ulim vlim quot -- seq )
'[ _ <iota> _ <iota> [ [ 2 ] [ 3 ] bi* [ swap ^ ] 2bi@ * 1 @ dup prime? [ , ] [ drop ] if ] cartesian-each ] { } make natural-sort ; inline
- .fifty ( seq -- ) 50 head 10 group simple-table. nl ;
[let
[ + ] [ - ] [ [ 120 80 ] dip pierpont ] bi@ :> ( first second ) "First 50 Pierpont primes of the first kind:" print first .fifty
"First 50 Pierpont primes of the second kind:" print second .fifty
"250th Pierpont prime of the first kind: " write 249 first nth . nl
"250th Pierpont prime of the second kind: " write 249 second nth .
]</lang>
- Output:
First 50 Pierpont primes of the first kind: 2 3 5 7 13 17 19 37 73 97 109 163 193 257 433 487 577 769 1153 1297 1459 2593 2917 3457 3889 10369 12289 17497 18433 39367 52489 65537 139969 147457 209953 331777 472393 629857 746497 786433 839809 995329 1179649 1492993 1769473 1990657 2654209 5038849 5308417 8503057 First 50 Pierpont primes of the second kind: 2 3 5 7 11 17 23 31 47 53 71 107 127 191 383 431 647 863 971 1151 2591 4373 6143 6911 8191 8747 13121 15551 23327 27647 62207 73727 131071 139967 165887 294911 314927 442367 472391 497663 524287 786431 995327 1062881 2519423 10616831 17915903 18874367 25509167 30233087 250th Pierpont prime of the first kind: 62518864539857068333550694039553 250th Pierpont prime of the second kind: 4111131172000956525894875083702271
Go
Brute force but works very quickly. <lang go>package main
import (
"fmt" "math/big" "sort"
)
var (
one = new(big.Int).SetUint64(1) two = new(big.Int).SetUint64(2) three = new(big.Int).SetUint64(3)
)
func pierpont(ulim, vlim int, first bool) []*big.Int {
p := new(big.Int) p2 := new(big.Int).Set(one) p3 := new(big.Int).Set(one) var pp []*big.Int for v := 0; v < vlim; v++ { for u := 0; u < ulim; u++ { p.Mul(p2, p3) if first { p.Add(p, one) } else { p.Sub(p, one) } if p.ProbablyPrime(10) { q := new(big.Int) q.Set(p) pp = append(pp, q) } p2.Mul(p2, two) } p3.Mul(p3, three) p2.Set(one) } sort.Slice(pp, func(i, j int) bool { return pp[i].Cmp(pp[j]) < 0 }) return pp
} func main() {
fmt.Println("First 50 Pierpont primes of the first kind:") pp := pierpont(120, 80, true) for i := 0; i < 50; i++ { fmt.Printf("%8d ", pp[i]) if (i-9)%10 == 0 { fmt.Println() } } fmt.Println("\nFirst 50 Pierpont primes of the second kind:") pp2 := pierpont(120, 80, false) for i := 0; i < 50; i++ { fmt.Printf("%8d ", pp2[i]) if (i-9)%10 == 0 { fmt.Println() } } fmt.Println("\n250th Pierpont prime of the first kind:", pp[249]) fmt.Println("\n250th Pierpont prime of the second kind:", pp2[249])
}</lang>
- Output:
First 50 Pierpont primes of the first kind: 2 3 5 7 13 17 19 37 73 97 109 163 193 257 433 487 577 769 1153 1297 1459 2593 2917 3457 3889 10369 12289 17497 18433 39367 52489 65537 139969 147457 209953 331777 472393 629857 746497 786433 839809 995329 1179649 1492993 1769473 1990657 2654209 5038849 5308417 8503057 First 50 Pierpont primes of the second kind: 2 3 5 7 11 17 23 31 47 53 71 107 127 191 383 431 647 863 971 1151 2591 4373 6143 6911 8191 8747 13121 15551 23327 27647 62207 73727 131071 139967 165887 294911 314927 442367 472391 497663 524287 786431 995327 1062881 2519423 10616831 17915903 18874367 25509167 30233087 250th Pierpont prime of the first kind: 62518864539857068333550694039553 250th Pierpont prime of the second kind: 4111131172000956525894875083702271
Julia
The generator method is very fast but does not guarantee the primes are generated in order. Therefore we generate three times the primes needed and then sort and return the bottom third. <lang julia>using Primes
function pierponts(N, firstkind = true)
count, ret, incdec = 0, BigInt[], firstkind ? 1 : -1 for k2 in 0:1000, k3 in 0:k2, switch in false:true i, j = switch ? (k3, k2) : (k2, k3) n = BigInt(2)^i * BigInt(3)^j + incdec if !(n in ret) && isprime(n) push!(ret, n) if length(ret) == N * 3 return sort(ret)[1:N] end end end throw("Failed to find $N primes")
end
println("The first 50 Pierpont primes (first kind) are: ", pierponts(50))
println("\nThe first 50 Pierpont primes (second kind) are: ", pierponts(50, false))
println("\nThe 250th Pierpont prime (first kind) is: ", pierponts(250)[250])
println("\nThe 250th Pierpont prime (second kind) is: ", pierponts(250, false)[250])
</lang>
- Output:
The first 50 Pierpont primes (first kind) are: BigInt[2, 3, 5, 7, 13, 17, 19, 37, 73, 97, 109, 163, 193, 257, 433, 487, 577, 769, 1153, 1297, 1459, 2593, 2917, 3457, 3889, 10369, 12289, 17497, 18433, 39367, 52489, 65537, 139969, 147457, 209953, 331777, 472393, 629857, 746497, 786433, 839809, 995329, 1179649, 1492993, 1769473, 1990657, 2654209, 5038849, 5308417, 8503057] The first 50 Pierpont primes (second kind) are: BigInt[2, 3, 5, 7, 11, 17, 23, 31, 47, 53, 71, 107, 127, 191, 383, 431, 647, 863, 971, 1151, 2591, 4373, 6143, 6911, 8191, 8747, 13121, 15551, 23327, 27647, 62207, 73727, 131071, 139967, 165887, 294911, 314927, 442367, 472391, 497663, 524287, 786431, 995327, 1062881, 2519423, 10616831, 17915903, 18874367, 25509167, 30233087] The 250th Pierpont prime (first kind) is: 62518864539857068333550694039553 The 250th Pierpont prime (second kind) is: 4111131172000956525894875083702271
Perl 6
This finesse version never produces more Pierpont numbers than it needs to fulfill the requested number of primes. It uses a series of parallel iterators with additional iterators added as required. No need to speculatively generate an overabundance. No need to rely on magic numbers. No need to sort them. It produces exactly what is needed, in order, on demand.
<lang perl6>use ntheory:from<Perl5> <is_prime>;
sub pierpont ($kind is copy = 1) {
fail "Unknown type: $kind. Must be one of 1 (default) or 2" if $kind !== 1|2; my $po3 = 0; my $add-one = 3; my @iterators = [2,4,8 … *].iterator, [3,9,27 … *].iterator;
gather { take 2 if $kind == 1; $kind = -1 if $kind == 2; my @head = @iterators».pull-one;
loop { my $key = @head.pairs.min( *.value ).key; my $min = @head[$key]; @head[$key] = @iterators[$key].pull-one;
take $min + $kind if "{$min + $kind}".&is_prime;
if $min >= $add-one { ++$po3; @iterators.push: ([|((2,4,8).map: * * 3 ** $po3) … *]).iterator; $add-one = @head[+@iterators - 1] = @iterators[+@iterators - 1].pull-one; } } }
}
say "First 50 Pierpont primes of the first kind:\n" ~ pierpont[^50].rotor(10)».fmt('%8d').join: "\n";
say "\nFirst 50 Pierpont primes of the second kind:\n" ~ pierpont(2)[^50].rotor(10)».fmt('%8d').join: "\n";
say "\n250th Pierpont prime of the first kind: " ~ pierpont[249];
say "\n250th Pierpont prime of the second kind: " ~ pierpont(2)[249];
- And the question absolutely nobody was asking:
say "\n1000th Pierpont prime of the first kind:\n" ~ pierpont[999];
say "\n1000th Pierpont prime of the second kind:\n" ~ pierpont(2)[999];</lang>
- Output:
First 50 Pierpont primes of the first kind: 2 3 5 7 13 17 19 37 73 97 109 163 193 257 433 487 577 769 1153 1297 1459 2593 2917 3457 3889 10369 12289 17497 18433 39367 52489 65537 139969 147457 209953 331777 472393 629857 746497 786433 839809 995329 1179649 1492993 1769473 1990657 2654209 5038849 5308417 8503057 First 50 Pierpont primes of the second kind: 2 3 5 7 11 17 23 31 47 53 71 107 127 191 383 431 647 863 971 1151 2591 4373 6143 6911 8191 8747 13121 15551 23327 27647 62207 73727 131071 139967 165887 294911 314927 442367 472391 497663 524287 786431 995327 1062881 2519423 10616831 17915903 18874367 25509167 30233087 250th Pierpont prime of the first kind: 62518864539857068333550694039553 250th Pierpont prime of the second kind: 4111131172000956525894875083702271 1000th Pierpont prime of the first kind: 69269314716439690250482558089997110961545818230232043107188537422260188701607997086273960899938499201024414931399264696270849 1000th Pierpont prime of the second kind: 1308088756227965581249669045506775407896673213729433892383353027814827286537163695213418982500477392209371001259166465228280492460735463423
REXX
The REXX language has a "big num" capability to handle almost any amount of decimal digits, but
it lacks a robust isPrime function. Without that, verifying very large primes is problematic.
<lang rexx>/*REXX program finds and displays Pierpont primes of the first and second kinds. */
parse arg n . /*obtain optional argument from the CL.*/
if n== | n=="," then n= 50 /*Not specified? Then use the default.*/
numeric digits n /*ensure enough decimal digs (bit int).*/
big= copies(9, digits() ) /*BIG: used as a max number (a limit).*/
do t=1 to -1 by -2; usum= 0; vsum= 0; s= 0 #= 0 /*number of Pierpont primes (so far). */ w= 0 /*the max width of a Pierpont prime. */ $=; do j=0 until #>=n /*$: the list of the Pierpont primes. */ if usum<=s then usum= get(2, 3); if vsum<=s then vsum= get(3, 2) s= min(vsum, usum); if \isPrime(s) then iterate /*get min; is prime? */ #= # + 1; $= $ s /*bump counter; append.*/ w= max(w, length(s) ) /*find max prime width.*/ end /*j*/ say if t==1 then @= '1st' /*choose word for type.*/ else @= '2nd' /* " " " " */ say center(n " Pierpont primes of the " @ ' kind', max(10*(w+1) -1, 79), "═") call show $ /*display the primes. */ end /*type*/
exit /*stick a fork in it, we're all done. */ /*──────────────────────────────────────────────────────────────────────────────────────*/ show: do j=1 by 10 to words($); _=
do k=j for 10; _= _ right( word($, k), w) end /*k*/ if _\== then say substr( strip(_, 'T'), 2) end /*j*/; return
/*──────────────────────────────────────────────────────────────────────────────────────*/ isPrime: procedure; parse arg x; if x<2 then return 0 /*not a prime.*/
if wordpos(x, '2 3 5 7')\==0 then return 1 /*it's a prime.*/ if x//2==0 then return 0; if x//3==0 then return 0 /*not a prime.*/ do j=5 by 6 until j*j>x if x//j==0 then return 0; if x//(j+2)==0 then return 0 /*not a prime.*/ end /*j*/; return 1 /*it's a prime.*/
/*──────────────────────────────────────────────────────────────────────────────────────*/ get: parse arg c1,c2; m=big; do ju=0; pu= c1**ju; if pu+t>s then return min(m, pu+t)
do jv=0; pv= c2**jv; if pv >s then iterate ju _= pu*pv + t; if _ >s then m= min(_, m) end /*jv*/ end /*ju*/ /*see the RETURN (above). */</lang>
- output when using the default input:
═════════════════════50 Pierpont primes of the 1st kind═════════════════════ 2 3 5 7 13 17 19 37 73 97 109 163 193 257 433 487 577 769 1153 1297 1459 2593 2917 3457 3889 10369 12289 17497 18433 39367 52489 65537 139969 147457 209953 331777 472393 629857 746497 786433 839809 995329 1179649 1492993 1769473 1990657 2654209 5038849 5308417 8503057 ══════════════════════════50 Pierpont primes of the 2nd kind══════════════════════════ 2 3 5 7 11 17 23 31 47 53 71 107 127 191 383 431 647 863 971 1151 2591 4373 6143 6911 8191 8747 13121 15551 23327 27647 62207 73727 131071 139967 165887 294911 314927 442367 472391 497663 524287 786431 995327 1062881 2519423 10616831 17915903 18874367 25509167 30233087