Sequence of primorial primes: Difference between revisions

m
m (changed the category name.)
m (→‎{{header|Wren}}: Minor tidy)
 
(33 intermediate revisions by 11 users not shown)
Line 1:
{{task|Prime Numbers}}
[[Category:Prime Numbers]]
 
The sequence of primorial primes is given as the increasing values of n where [[Primorial numbers|primorial]](n) ± 1 is prime.
Line 18 ⟶ 17:
* This task asks for the primorial ''indices'' that create the final primorial prime numbers, so there should be no ten-or-more digit numbers in the program output (although extended precision integers ''will'' be needed for intermediate results).
* There is some confusion in the references, but for the purposes of this task the '''[[wp:Primorial prime|sequence]] begins with n = 1'''.
* Probabilistic primality tests are allowed, as long as they are good enough such that the output shown is correct.
 
 
;Related tasks:
;Cf.
* [[Primorial numbers]]
* [[Factorial]]
 
 
;See also:
* [[wp:Primorial prime|Primorial prime]] Wikipedia.
* [https://primes.utm.edu/glossary/page.php?sort=PrimorialPrime Primorial prime] from The Prime Glossary.
* [https://oeis.org/A088411 Sequence A088411] from The On-Line Encyclopedia of Integer Sequences
<br><br>
 
=={{header|ALGOL 68}}==
Uses ALGOL 68G's LONG LONG INT which has programmer-speciafable precision. The precision used and size of the prime sieve used would allow finding the sequence up to 16 members, though that would take some time.
{{works with|ALGOL 68G|Any - tested with release 3.0.3.win32}}
{{libheader|ALGOL 68-primes}}
NB: The source of the ALGOL 68 primes library is on a Rosetta Code page.<br>
NB: ALGOL 68G version 3 will issue warnings for unused items and names hiding names in outer scopes for the primes.incl.a68 file.
<syntaxhighlight lang="algol68">BEGIN # find some primorial primes - primes that are p - 1 or p + 1 #
# for some primorial p #
PR precision 2000 PR # allow up to 2000 digit numbers #
PR read "primes.incl.a68" PR # include prime utilities #
# construct a sieve of primes up to 2000 #
[]BOOL primes = PRIMESIEVE 2000;
# find the sequence members #
LONG LONG INT pn := 1;
INT p count := 0;
INT p pos := 0;
FOR n FROM 1 WHILE p count < 12 DO
# find the next prime #
WHILE NOT primes[ p pos +:= 1 ] DO SKIP OD;
pn *:= p pos;
IF is probably prime( pn - 1 )
THEN
p count +:= 1;
print( ( " ", whole( n, 0 ) ) )
ELIF is probably prime( pn + 1 )
THEN
p count +:= 1;
print( ( " ", whole( n, 0 ) ) )
FI
OD;
print( ( newline ) )
END</syntaxhighlight>
{{out}}
<pre>
1 2 3 4 5 6 11 13 24 66 68 75
</pre>
 
Alternative version (originally written for another draft task that is now slated for removal) - shows the actual primorial primes. Assumes LONG INT is at least 64 bit. Similar to the [[Factorial primes#ALGOL_68]] sample.
;Related tasks:
<syntaxhighlight lang="algol68">BEGIN # find some primorial primes - primes that are p - 1 or p + 1 #
* [[Primorial numbers]]
# for some primorial p #
<br><br>
 
# is prime PROC based on the one in the primality by trial division task #
PROC is prime = ( LONG INT p )BOOL:
IF p <= 1 OR NOT ODD p THEN
p = 2
ELSE
BOOL prime := TRUE;
FOR i FROM 3 BY 2 TO SHORTEN ENTIER long sqrt(p) WHILE prime := p MOD i /= 0 DO SKIP OD;
prime
FI;
# end of code based on the primality by trial divisio task #
 
# construct a sieve of primes up to 200 #
[ 0 : 200 ]BOOL primes;
primes[ 0 ] := primes[ 1 ] := FALSE;
primes[ 2 ] := TRUE;
FOR i FROM 3 BY 2 TO UPB primes DO primes[ i ] := TRUE OD;
FOR i FROM 4 BY 2 TO UPB primes DO primes[ i ] := FALSE OD;
FOR i FROM 3 BY 2 TO ENTIER sqrt( UPB primes ) DO
IF primes[ i ] THEN
FOR s FROM i * i BY i + i TO UPB primes DO primes[ s ] := FALSE OD
FI
OD;
 
PROC show primorial prime = ( INT p number, INT n, CHAR p op, LONG INT p )VOID:
print( ( whole( p number, -2 ), ":", whole( n, -4 )
, "# ", p op, " 1 = ", whole( p, 0 )
, newline
)
);
 
LONG INT pn := 1;
INT p count := 0;
INT p pos := 0;
# starting from primorial 0, which is defined to be 1 #
FOR n FROM 0 WHILE p count < 12 DO
IF LONG INT p = pn - 1;
is prime( p )
THEN
show primorial prime( p count +:= 1, n, "-", p )
FI;
IF LONG INT p = pn + 1;
is prime( p )
THEN
show primorial prime( p count +:= 1, n, "+", p )
FI;
# find the next prime #
WHILE NOT primes[ p pos +:= 1 ] DO SKIP OD;
pn *:= p pos
OD
END</syntaxhighlight>
{{out}}
<pre>
1: 0# + 1 = 2
2: 1# + 1 = 3
3: 2# - 1 = 5
4: 2# + 1 = 7
5: 3# - 1 = 29
6: 3# + 1 = 31
7: 4# + 1 = 211
8: 5# - 1 = 2309
9: 5# + 1 = 2311
10: 6# - 1 = 30029
11: 11# + 1 = 200560490131
12: 13# - 1 = 304250263527209
</pre>
 
=={{header|Arturo}}==
<syntaxhighlight lang="arturo">productUpTo: #["1": 1]
primorials: unique map 2..4000 'x ->
productUpTo\[x]: <= productUpTo\[x-1] * (prime? x)? -> x -> 1
 
primorials | map.with:'i 'x -> @[i x]
| select.first:20 'x -> or? [prime? x\1 + 1][prime? x\1 - 1]
| map 'x -> x\0 + 1
| print</syntaxhighlight>
 
{{out}}
 
<pre>1 2 3 4 5 6 11 13 24 66 68 75 167 171 172 287 310 352 384 457</pre>
 
=={{header|C}}==
{{libheader|GMP}}
<syntaxhighlight lang="c">
<lang c>
#include <gmp.h>
 
Line 68 ⟶ 189:
mpz_clear(p);
}
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 91 ⟶ 212:
384
457
</pre>
 
=={{header|C++}}==
{{libheader|GMP}}
<syntaxhighlight lang="cpp">#include <cstdint>
#include <iostream>
#include <sstream>
#include <gmpxx.h>
 
typedef mpz_class integer;
 
bool is_probably_prime(const integer& n) {
return mpz_probab_prime_p(n.get_mpz_t(), 25) != 0;
}
 
bool is_prime(unsigned int n) {
if (n < 2)
return false;
if (n % 2 == 0)
return n == 2;
if (n % 3 == 0)
return n == 3;
for (unsigned int p = 5; p * p <= n; p += 4) {
if (n % p == 0)
return false;
p += 2;
if (n % p == 0)
return false;
}
return true;
}
 
int main() {
const unsigned int max = 20;
integer primorial = 1;
for (unsigned int p = 0, count = 0, index = 0; count < max; ++p) {
if (!is_prime(p))
continue;
primorial *= p;
++index;
if (is_probably_prime(primorial - 1) || is_probably_prime(primorial + 1)) {
if (count > 0)
std::cout << ' ';
std::cout << index;
++count;
}
}
std::cout << '\n';
return 0;
}</syntaxhighlight>
 
{{out}}
<pre>
1 2 3 4 5 6 11 13 24 66 68 75 167 171 172 287 310 352 384 457
</pre>
 
=={{header|Clojure}}==
; Uses Java Interoop to use Java for 1) Prime Test and 2) Prime sequence generation
<langsyntaxhighlight lang="lisp">
(ns example
(:gen-class))
Line 114 ⟶ 289:
(reductions *' primes)))) ; computes the lazy sequence of product of 1 prime, 2 primes, 3 primes, etc.
 
</syntaxhighlight>
</lang>
{{Out}}
<pre>
(1 2 3 4 5 6 11 13 24 66 68 75 167 171 172 287 310 352 384 457)
</pre>
 
=={{header|EchoLisp}}==
<langsyntaxhighlight lang="lisp">
(lib 'timer) ;; for (every (proc t) interval)
(lib 'bigint)
Line 139 ⟶ 315:
(writeln 'HIT N )
(writeln N (date->time-string (current-date )))))
</syntaxhighlight>
</lang>
{{out}}
<langsyntaxhighlight lang="lisp">
;; run in batch mode to make the browser happy
;; search next N every 2000 msec
Line 171 ⟶ 347:
458 "14:07:25"
459 "14:07:29"
</syntaxhighlight>
</lang>
 
=={{header|Factor}}==
<langsyntaxhighlight lang="factor">USING: kernel lists lists.lazy math math.primes prettyprint
sequences ;
 
Line 180 ⟶ 356:
nprimes product [ 1 + ] [ 1 - ] bi [ prime? ] either? ;
 
10 1 lfrom [ pprime? ] <lazy-filter> ltake list>array .</langsyntaxhighlight>
{{out}}
<pre>
Line 188 ⟶ 364:
=={{header|Fortran}}==
===Stage one: a probe===
First comes a probe of the problem, using ordinary arithmetic and some routines written for other problems. Module PRIMEBAG can be found in [[Extensible_prime_generator#Fortran]] and the basic version of module BIGNUMBERS in [[Primorial_numbers#Fortran]] <langsyntaxhighlight Fortranlang="fortran"> PROGRAM PRIMORIALP !Simple enough, with some assistants.
USE PRIMEBAG !Some prime numbers are wanted.
USE BIGNUMBERS !Just so.
Line 255 ⟶ 431:
WRITE (MSG,*) "CPU time:",T1 - T0 !The cost.
END !So much for that.
</syntaxhighlight>
</lang>
Output, somewhat edited, because the limit on direct factorisation is soon exceeded: five lines such as "Passed the limit of 18000000 with 18000041, but Sqrt(n) = 0.43849291E+11:" and similar have been removed, corresponding to the five "?" reports.
<pre>
Line 309 ⟶ 485:
Rather than always employing in-line arithmetic expressions of ever greater complexity, defining a function offers multiple advantages. This might be via an "arithmetic statement" function if it can be written as a single expression, but more generally, a function can be named and defined as a separate unit for compilation, and then used within arithmetic expressions. This is unexceptional, and easily understood. Whatever the parameters and workings of the function, its result is returned in the computer's accumulator, or top-of-stack, or a standard register. Thus, an expression such as ''y:=x;'' would produce code such as Load x; Store y; whereas with an expression such as ''y:=F(x);'' instead of the Load there is an invocation of the function which would perform its calculation then return, whereupon the code Store y; would be executed just as before. This is easily extended for usage within an expression such as ''y:=y + 7*F(x) - 3;'' and so forth.
 
Within the function's definition would be a statement such as <code>F = ''expression''</code> followed by a return (perhaps by reaching the end of the function's code) but more complex functions introduce additional considerations. It is often the case that the final result will be developed via multiple statements and conditional branches. For instance, <langsyntaxhighlight Fortranlang="fortran"> FUNCTION SUM(A,N)
DIMENSION A(*)
SUM = 0 !Unconditionally, clear SUM.
Line 315 ⟶ 491:
SUM = A(I) + SUM
END DO !Some early compilers executed a DO-loop at least once.
END</langsyntaxhighlight>
Prior to F90, there were compilers for which this did ''not'' work. If an assignment to SUM were to be regarded as an assignment to the accumulator, as above, then when that is ''not'' followed by a RETURN but by other statements, the value that had been saved in the accumulator will be lost by the accumulator's usage in the execution of the subsequent statements. Indeed, some compilers would not allow any usage of SUM within an expression. Thus, a local variable, perhaps called ASUM, would be defined and used instead, and then, before exiting the function (by whatever path) one must remember to have an assignment <code>SUM = ASUM</code>
 
Line 378 ⟶ 554:
====Storage====
=====Run-time allocation=====
As usual, the question "How long is a piece of string?" arises with regard to the arrays of digits to be manipulated. In old-style Fortran, one would define arrays with a size that seemed "big enough" and have an associated variable that counted the number of digits in use. Having two variables to be used in tandem was tiresome and invited mistakes: a possible ploy would be to reserve the first element of the array for the count, with the digits following. The EQUIVALENCE statement could be used to help in some ways (though this is not allowed for parameters to routines), somewhat as follows: <langsyntaxhighlight Fortranlang="fortran"> INTEGER XLAST,XDIGIT(66),XFIELD(67)
EQUIVALENCE (XFIELD(1),XLAST) !The count at the start.
EQUIVALENCE (XFIELD(3),XDIGIT(1)) !Followed by XDIGIT(0)</langsyntaxhighlight>
This introduces ''three'' names, if in a systematic way... But such array indexing invites its own mistakes, especially when relying on lax bound checking. For example, an accidental assignment to XDIGIT(-1) would change XLAST.
 
With F90 came the ability to declare arrays with a lower bound other than one, and also to define compound data aggregates. Rather dubious code can be replaced by something like <langsyntaxhighlight Fortranlang="fortran"> TYPE(BIGNUM) !Define an aggregate.
INTEGER LAST !Count of digits in use.
INTEGER DIGIT(many) !The first digit is number one.
END TYPE BIGNUM
TYPE(BIGNUM) X !I'll have one.</langsyntaxhighlight>
And in this case the X.LAST variable is not a part of the digit array and so can't be damaged via misindexing X.DIGIT as with the earlier attempt using EQUIVALENCE - providing that array bound checking ''is'' engaged. Thus, one gains the ability to use X in a way that is somewhat more self-documenting, but there is still the annoyance of deciding on how many digits will be enough, and further, the BIGNUM type allows for only a fixed size. A different size would entail a different type and thereby cause parameter mismatching - should that be checked...
 
Line 622 ⟶ 798:
 
=====Support=====
<langsyntaxhighlight Fortranlang="fortran"> MODULE BIGNUMBERS !Limited services: decimal integers, no negative numbers.
INTEGER BIGORDER !A limited attempt at generality.
PARAMETER (BIGORDER = 4) !This is the order of the base of the big number arithmetic.
Line 1,286 ⟶ 1,462:
 
END MODULE BIGNUMBERS !No fancy tricks.
</syntaxhighlight>
</lang>
 
=====Use=====
With all that in hand, big numbers can be manipulated, and function BIGFACTOR can be used where others use something like IsProbablyPrime. So the task is solvable via <langsyntaxhighlight Fortranlang="fortran"> PROGRAM PRIMORIALP !Simple enough, with some assistants.
USE PRIMEBAG !Some prime numbers are wanted.
USE BIGNUMBERS !Just so.
Line 1,372 ⟶ 1,548:
WRITE (MSG,*) "CPU time:",T1 - T0 !The cost.
END !So much for that.
</syntaxhighlight>
</lang>
A slightly more complex scheme to interpret the more complex mumbling from BIGFACTOR, which is less sure of its reports in more ways.
 
Line 1,500 ⟶ 1,676:
 
====The source====
This requires modification to function BIGMRPRIME, which now invokes revised versions of its bignumber routines and conveniently, is the routine that decides on the value N for the modulus (it is the number whose primality is to be tested) and so is in a position to declare the REM table empty each time it is presented with a new N. Since Algol in the 1960s it has been possible for routines to be defined inside other routines (thus sharing variables) but this facility has only become available to Fortran with F90, if in a rather odd way. As for the REM array, in the past it would be defined as "big enough", but with F90 it is possible for a routine to declare an array of a size determined on entry to the routine. It could be defined as a BIGNUMBER, but the whole point of the exercise is that its numbers need no more digits than are in N, specifically N.LAST digits, rather than BIGLIMIT digits. Aside from avoiding wastage, it is better to keep related items close together in memory. Similarly for the number of entries in the REM table: instead of some large collection, the highest-order value corresponds to 2*N.LAST, and further, the first needed entry is at index N.LAST + 1. In the past, the lower bound of an array in Fortran was fixed at one, and the code could either ignore the wasted entries, or else employ suitable offsets so as to employ them - at the cost of careful thought and checking. But employing such offsets is a simple clerical task, and computers excel at simple clerical tasks, and with F90 can be called upon to do so. The declaration is <code>INTEGER REM(N.LAST,N.LAST + 1:2*N.LAST)</code> and it is because adjacent storage is indexed by the first index, not the last, that the digits of a REM entry are accessed by the first index, not the last. The table is cleared, not by setting all its digits to zero even though <code>REM = 0</code> would be easy, but instead by setting <code>NR = N.LAST</code>, which is one short of the first entry in the REM table, it being known that entries will be produced progressively. <langsyntaxhighlight Fortranlang="fortran"> LOGICAL FUNCTION BIGMRPRIME(N,TRIALS) !Could N be a prime number?
USE DFPORT !To get RAND, which returns a "random" number in 0.0 to 1.0. Inclusive.
TYPE(BIGNUM) N !The number to taste.
Line 1,688 ⟶ 1,864:
END SUBROUTINE BMODEXP !"Bit" presence by arithmetic: works for non-binary arithmetic too.
END FUNCTION BIGMRPRIME !Are some numbers resistant to this scheme?
</syntaxhighlight>
</lang>
 
====The results====
Line 2,183 ⟶ 2,359:
=={{header|FreeBASIC}}==
{{libheader|GMP}}
<langsyntaxhighlight lang="freebasic">' version 23-10-2016
' compile with: fbc -s console
 
Line 2,236 ⟶ 2,412:
Print : Print "hit any key to end program"
Sleep
End</langsyntaxhighlight>
{{out}}
<pre> 1, 2, 3, 4, 5, 6, 11, 13, 24, 66, 68, 75, 167, 171, 172, 287, 310, 352, 384, 457,</pre>
 
=={{header|Go}}==
<langsyntaxhighlight lang="go">package main
import (
Line 2,299 ⟶ 2,475:
}
}
}</langsyntaxhighlight>
{{out}}
<pre>
Line 2,306 ⟶ 2,482:
 
=={{header|Haskell}}==
<langsyntaxhighlight Haskelllang="haskell">import Data.List (scanl1, elemIndices, nub)
 
primes :: [Integer]
Line 2,332 ⟶ 2,508:
 
main :: IO ()
main = mapM_ print $ take 10 sequenceOfPrimorialPrimes</langsyntaxhighlight>
{{out}}
<pre>1
Line 2,347 ⟶ 2,523:
=={{header|J}}==
 
<langsyntaxhighlight Jlang="j">primoprim=: [: I. [: +./ 1 p: (1,_1) +/ */\@:p:@i.</langsyntaxhighlight>
 
This isn't particularly fast - J's current extended precision number implementation favors portability over speed.
Line 2,353 ⟶ 2,529:
Example use:
 
<langsyntaxhighlight Jlang="j"> primoprim 600x
0 1 2 3 4 5 10 12 23 65 67 74 166 170 171 286 309 351 383 456 563 589</langsyntaxhighlight>
 
Note that the task specifies that index zero is not a part of the sequence for this task. So pretend you didn't see it.
 
=={{header|Java}}==
<langsyntaxhighlight lang="java">import java.math.BigInteger;
 
public class PrimorialPrimes {
Line 2,407 ⟶ 2,583:
return composite;
}
}</langsyntaxhighlight>
 
<pre>1 2 3 4 5 6 11 13 24 66 68 75 167 171 172 287 310 352 384 457</pre>
Line 2,413 ⟶ 2,589:
=={{header|Julia}}==
{{trans|Go}}
<langsyntaxhighlight lang="julia">using Primes
 
function primordials(N)
Line 2,438 ⟶ 2,614:
 
primordials(20)
</langsyntaxhighlight>{{output}}<pre>
The first 20 primorial indices sequentially producing primorial primes are: 1 2 3 4 5 6 11 13 24 66 68 75 167 171 172 287 310 352 384 457
</pre>
 
=={{header|Kotlin}}==
<langsyntaxhighlight lang="scala">// version 1.0.6
 
import java.math.BigInteger
Line 2,485 ⟶ 2,661:
p += 2
}
}</langsyntaxhighlight>
 
{{out}}
Line 2,492 ⟶ 2,668:
1 2 3 4 5 6 11 13 24 66 68 75 167 171 172 287 310 352 384 457
</pre>
 
=={{header|Mathematica}} / {{header|Wolfram Language}}==
<syntaxhighlight lang="mathematica">primorials = Rest@FoldList[Times, 1, Prime[Range[500]]];
primorials = MapIndexed[{{First[#2], #1 - 1}, {First[#2], #1 + 1}} &, primorials];
Select[primorials, AnyTrue[#[[All, 2]], PrimeQ] &][[All, 1, 1]]</syntaxhighlight>
{{out}}
<pre>{1, 2, 3, 4, 5, 6, 11, 13, 24, 66, 68, 75, 167, 171, 172, 287, 310, 352, 384, 457}</pre>
 
=={{header|Nim}}==
{{libheader|bignum}}
Using a sieve of Erathosthenes to find the prime numbers up to 4000 and a probabilistic test of primality. The program runs typically in 6 seconds.
 
<syntaxhighlight lang="nim">import strutils, sugar
import bignum
 
## Run a sieve of Erathostenes.
const N = 4000
var isComposite: array[2..N, bool] # False (default) means "is prime".
for n in 2..isComposite.high:
if not isComposite[n]:
for k in countup(n * n, N, n):
isComposite[k] = true
 
# Collect the list of primes.
let primes = collect(newSeq):
for n, comp in isComposite:
if not comp:
n
 
iterator primorials(): Int =
## Yield the successive primorial numbers.
var result = newInt(1)
for prime in primes:
result *= prime
yield result
 
template isPrime(n: Int): bool =
## Return true if "n" is certainly or probably prime.
## Use the probabilistic test provided by "bignum" (i.e. "gmp" probabilistic test).
probablyPrime(n, 25) != 0
 
func isPrimorialPrime(n: Int): bool =
## Return true if "n" is a primorial prime.
(n - 1).isPrime or (n + 1).isPrime
 
 
const Lim = 20 # Number of indices to keep.
var idx = 0 # Primorial index.
var indices = newSeqOfCap[int](Lim) # List of indices.
 
for p in primorials():
inc idx
if p.isPrimorialPrime():
indices.add idx
if indices.len == LIM: break
 
echo indices.join(" ")</syntaxhighlight>
 
{{out}}
<pre>1 2 3 4 5 6 11 13 24 66 68 75 167 171 172 287 310 352 384 457
 
real 0m5,960s
user 0m5,953s
sys 0m0,004s</pre>
 
=={{header|PARI/GP}}==
This program, in principle, generates arbitrarily many primirial prime indices. Practically speaking it depends on your patience; it generates them up to 643 in about 5 seconds.
<langsyntaxhighlight lang="parigp">n=0; P=1; forprime(p=2,, P*=p; n++; if(ispseudoprime(P+1) || ispseudoprime(P-1), print1(n", ")))</langsyntaxhighlight>
{{out}}
<pre>1, 2, 3, 4, 5, 6, 11, 13, 24, 66, 68, 75, 167, 171, 172, 287, 310, 352, 384, 457, 564, 590, 616, 620, 643, 849,</pre>
Line 2,501 ⟶ 2,741:
=={{header|Perl}}==
{{libheader|ntheory}}
<langsyntaxhighlight lang="perl">use ntheory ":all";
my $i = 0;
for (1..1e6) {
Line 2,509 ⟶ 2,749:
last if ++$i >= 20;
}
}</langsyntaxhighlight>
{{out}}
<pre>1
Line 2,531 ⟶ 2,771:
384
457</pre>
 
=={{header|Perl 6}}==
<lang perl6>constant @primes = |grep *.is-prime, 2..*;
constant @primorials = [\*] 1, @primes;
 
my @pp_indexes := |@primorials.pairs.map: {
.key if ( .value + any(1, -1) ).is-prime
};
 
say ~ @pp_indexes[ 0 ^.. 20 ]; # Skipping bogus first element.</lang>
{{out}}
<pre>1 2 3 4 5 6 11 13 24 66 68 75 167 171 172 287 310 352 384 457</pre>
 
=={{header|Phix}}==
{{libheader|Phix/mpfr}}
Horribly slow...
<!--<syntaxhighlight lang="phix">(phixonline)-->
Uses primes[] and add_block() from [[Extensible_prime_generator#Phix|Extensible_prime_generator]]
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
and Miller_Rabin() from [[Miller–Rabin_primality_test#Phix|Miller–Rabin_primality_test]]
<span style="color: #008080;">include</span> <span style="color: #004080;">mpfr</span><span style="color: #0000FF;">.</span><span style="color: #000000;">e</span>
<lang Phix>while length(primes)<100 do add_block() end while
<span style="color: #008080;">constant</span> <span style="color: #000000;">limit</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">9999</span><span style="color: #0000FF;">,</span>
 
<span style="color: #000000;">flimit</span> <span style="color: #0000FF;">=</span> <span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">platform</span><span style="color: #0000FF;">()=</span><span style="color: #004600;">JS</span><span style="color: #0000FF;">?</span><span style="color: #000000;">15</span><span style="color: #0000FF;">:</span><span style="color: #000000;">20</span><span style="color: #0000FF;">)</span>
integer primorial = 1
<span style="color: #004080;">mpz</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">p</span><span style="color: #0000FF;">,</span><span style="color: #000000;">p1</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">mpz_inits</span><span style="color: #0000FF;">(</span><span style="color: #000000;">2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)</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>
constant integer base = iff(machine_bits()=32?1000:1000000000)
<span style="color: #004080;">integer</span> <span style="color: #000000;">found</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">i</span>
constant integer digits_per = length(sprint(base-1))
<span style="color: #008080;">for</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">limit</span> <span style="color: #008080;">do</span>
constant string dpfmt = sprintf("%%0%dd",digits_per)
<span style="color: #7060A8;">mpz_mul_si</span><span style="color: #0000FF;">(</span><span style="color: #000000;">p</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">p</span><span style="color: #0000FF;">,</span> <span style="color: #7060A8;">get_prime</span><span style="color: #0000FF;">(</span><span style="color: #000000;">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: #0000FF;">+</span><span style="color: #000000;">1</span> <span style="color: #008080;">do</span>
-- start at the back, number grows to the right (like little endian)
<span style="color: #7060A8;">mpz_add_si</span><span style="color: #0000FF;">(</span><span style="color: #000000;">p1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">p</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">)</span>
sequence bigint = {primorial}
<span style="color: #008080;">if</span> <span style="color: #7060A8;">mpz_prime</span><span style="color: #0000FF;">(</span><span style="color: #000000;">p1</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span>
atom result
<span style="color: #004080;">integer</span> <span style="color: #000000;">l</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">mpz_sizeinbase</span><span style="color: #0000FF;">(</span><span style="color: #000000;">p</span><span style="color: #0000FF;">,</span><span style="color: #000000;">10</span><span style="color: #0000FF;">)</span>
 
<span style="color: #004080;">string</span> <span style="color: #000000;">ps</span> <span style="color: #0000FF;">=</span> <span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #000000;">l</span><span style="color: #0000FF;">></span><span style="color: #000000;">20</span><span style="color: #0000FF;">?</span><span style="color: #7060A8;">sprintf</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"%d digits"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">l</span><span style="color: #0000FF;">)</span>
procedure bi_mul(integer pn)
<span style="color: #0000FF;">:</span><span style="color: #7060A8;">mpz_get_str</span><span style="color: #0000FF;">(</span><span style="color: #000000;">p</span><span style="color: #0000FF;">))</span>
integer carry = 0
<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 (%s) is a primorial prime\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">n</span><span style="color: #0000FF;">,</span><span style="color: #000000;">ps</span><span style="color: #0000FF;">})</span>
for i=1 to length(bigint) do
<span style="color: #000000;">found</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span>
result = pn*bigint[i]+carry
carry <span style="color: floor(result#008080;">exit</base)span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
bigint[i] = result-carry*base
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
end for
<span style="color: #008080;">if</span> <span style="color: #000000;">found</span><span style="color: #0000FF;">>=</span><span style="color: #000000;">flimit</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>
while carry <> 0 do
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
result = carry
<span style="color: #0000FF;">{</span><span style="color: #000000;">p</span><span style="color: #0000FF;">,</span><span style="color: #000000;">p1</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">mpz_free</span><span style="color: #0000FF;">({</span><span style="color: #000000;">p</span><span style="color: #0000FF;">,</span><span style="color: #000000;">p1</span><span style="color: #0000FF;">})</span>
carry = floor(carry/base)
<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>
bigint &= result-carry*base
<!--</syntaxhighlight>-->
end while
end procedure
 
procedure bi_add(integer carry)
for i=1 to length(bigint) do
result = bigint[i]+carry
carry = floor(result/base)
bigint[i] = result-carry*base
if carry=0 then return end if
end for
if carry!=0 then
if carry<0
or carry!=floor(carry/base) then
?9/0 -- sanity check
end if
bigint &= carry
end if
end procedure
 
integer found = 0
for n=1 to 100 do
bi_mul(primes[n])
sequence save_bigint = bigint
for pm1=-1 to 2 by 3 do -- (ie n-1 then n+1)
bi_add(pm1)
string bis = sprint(bigint[$])
for i=length(bigint)-1 to 1 by -1 do
bis &= sprintf(dpfmt,bigint[i])
end for
printf(1,"working [%d]...\r",{n})
if Miller_Rabin(bis,1)=PROBABLY_PRIME then
if length(bis)>20 then
bis = sprintf("[big (%d digits)]",length(bis))
end if
printf(1,"%d (%s) is a primorial prime\n",{n,bis})
found += 1
exit
end if
end for
bigint = save_bigint
if found>=12 then exit end if
end for</lang>
{{out}}
<pre>
1 (32) is a primorial prime
2 (56) is a primorial prime
3 (2930) is a primorial prime
4 (211210) is a primorial prime
5 (23092310) is a primorial prime
6 (3002930030) is a primorial prime
11 (200560490131200560490130) is a primorial prime
13 (304250263527209304250263527210) is a primorial prime
24 ([big (35 digits)]) is a primorial prime
66 ([big (131 digits)]) is a primorial prime
68 ([big (136 digits)]) is a primorial prime
75 ([big (154 digits)]) is a primorial prime
167 (413 digits) is a primorial prime
171 (425 digits) is a primorial prime
172 (428 digits) is a primorial prime
287 (790 digits) is a primorial prime
310 (866 digits) is a primorial prime
352 (1007 digits) is a primorial prime
384 (1116 digits) is a primorial prime
457 (1368 digits) is a primorial prime
</pre>
 
Line 2,632 ⟶ 2,827:
Uses the pure python library [https://pypi.python.org/pypi/pyprimes/0.1.1a pyprimes ]. Note that pyprimes.isprime switches to a fast and good probabilistic algorithm for larger integers.
 
<langsyntaxhighlight lang="python">import pyprimes
 
def primorial_prime(_pmax=500):
Line 2,646 ⟶ 2,841:
pyprimes.warn_probably = False
for i, n in zip(range(20), primorial_prime()):
print('Primorial prime %2i at primorial index: %3i' % (i+1, n))</langsyntaxhighlight>
 
{{out}}
Line 2,672 ⟶ 2,867:
=={{header|Racket}}==
We use a memorized version of <code>primordial</code> to make it faster.
<langsyntaxhighlight Racketlang="racket">#lang racket
 
(require math/number-theory
Line 2,694 ⟶ 2,889:
(when (or (prime? (add1 pr)) (prime? (sub1 pr)))
(yield i))))])
(displayln n))</langsyntaxhighlight>
{{out}}
<pre>1
Line 2,716 ⟶ 2,911:
384
457</pre>
 
=={{header|Raku}}==
(formerly Perl 6)
<syntaxhighlight lang="raku" line>constant @primes = |grep *.is-prime, 2..*;
constant @primorials = [\*] 1, @primes;
 
my @pp_indexes := |@primorials.pairs.map: {
.key if ( .value + any(1, -1) ).is-prime
};
 
say ~ @pp_indexes[ 0 ^.. 20 ]; # Skipping bogus first element.</syntaxhighlight>
{{out}}
<pre>1 2 3 4 5 6 11 13 24 66 68 75 167 171 172 287 310 352 384 457</pre>
 
===Alternate implementation===
merged from another removed draft task.
 
<syntaxhighlight lang="raku" line>my @primorials = 1, |[\*] (2..*).grep: &is-prime;
sub abr ($_) { .chars < 41 ?? $_ !! .substr(0,20) ~ '..' ~ .substr(*-20) ~ " ({.chars} digits)" }
 
my $limit;
 
for ^∞ {
my \p = @primorials[$_];
++$limit and printf "%2d: %5s - 1 = %s\n", $limit, "p$_#", abr p -1 if (p -1).is-prime;
++$limit and printf "%2d: %5s + 1 = %s\n", $limit, "p$_#", abr p +1 if (p +1).is-prime;
exit if $limit >= 30
}</syntaxhighlight>
{{out}}
<pre> 1: p0# + 1 = 2
2: p1# + 1 = 3
3: p2# - 1 = 5
4: p2# + 1 = 7
5: p3# - 1 = 29
6: p3# + 1 = 31
7: p4# + 1 = 211
8: p5# - 1 = 2309
9: p5# + 1 = 2311
10: p6# - 1 = 30029
11: p11# + 1 = 200560490131
12: p13# - 1 = 304250263527209
13: p24# - 1 = 23768741896345550770650537601358309
14: p66# - 1 = 19361386640700823163..29148240284399976569 (131 digits)
15: p68# - 1 = 21597045956102547214..98759003964186453789 (136 digits)
16: p75# + 1 = 17196201054584064334..62756822275663694111 (154 digits)
17: p167# - 1 = 19649288510530675457..35580823050358968029 (413 digits)
18: p171# + 1 = 20404068993016374194..29492908966644747931 (425 digits)
19: p172# + 1 = 20832554441869718052..12260054944287636531 (428 digits)
20: p287# - 1 = 71488723083486699645..63871022000761714929 (790 digits)
21: p310# - 1 = 40476351620665036743..10663664196050230069 (866 digits)
22: p352# - 1 = 13372477493552802137..21698973741675973189 (1007 digits)
23: p384# + 1 = 78244737296323701708..84011652643245393971 (1115 digits)
24: p457# + 1 = 68948124012218025568..25023568563926988371 (1368 digits)
25: p564# - 1 = 12039145942930719470..56788854266062940789 (1750 digits)
26: p590# - 1 = 19983712295113492764..61704122697617268869 (1844 digits)
27: p616# + 1 = 13195724337318102247..85805719764535513291 (1939 digits)
28: p620# - 1 = 57304682725550803084..81581766766846907409 (1953 digits)
29: p643# + 1 = 15034815029008301639..38987057002293989891 (2038 digits)
30: p849# - 1 = 11632076146197231553..78739544174329780009 (2811 digits)</pre>
 
=={{header|Ring}}==
<langsyntaxhighlight lang="ring">
# Project : Sequence of primorial primes
 
Line 2,745 ⟶ 2,999:
next
return 1
</syntaxhighlight>
</lang>
Output:
<pre>
1, 2, 3, 4, 5, 6, 11, 13, 24, 66, 68, 75, 167, 171, 172, 287, 310, 352, 384, 457
</pre>
 
=={{header|Ruby}}==
<syntaxhighlight lang="ruby">
 
# Sequence of primorial primes
 
require 'prime' # for creating prime_array
require 'openssl' # for using fast Miller–Rabin primality test (just need 10.14 seconds to complete)
i, urutan, primorial_number = 1, 1, OpenSSL::BN.new(1)
start = Time.now
prime_array = Prime.first (500)
 
until urutan > 20
primorial_number *= prime_array[i-1]
if (primorial_number - 1).prime_fasttest? || (primorial_number + 1).prime_fasttest?
puts "#{Time.now - start} \tPrimorial prime #{urutan}: #{i}"
urutan += 1
end
i += 1
end
 
</syntaxhighlight>
 
Output:
<pre>
0.000501 Primorial prime 1: 1
0.00094 Primorial prime 2: 2
0.001474 Primorial prime 3: 3
0.001969 Primorial prime 4: 4
0.002439 Primorial prime 5: 5
0.003557 Primorial prime 6: 6
0.004167 Primorial prime 7: 11
0.004849 Primorial prime 8: 13
0.006287 Primorial prime 9: 24
0.020018 Primorial prime 10: 66
0.022049 Primorial prime 11: 68
0.026954 Primorial prime 12: 75
0.213867 Primorial prime 13: 167
0.243797 Primorial prime 14: 171
0.256598 Primorial prime 15: 172
1.469281 Primorial prime 16: 287
2.012719 Primorial prime 17: 310
3.598149 Primorial prime 18: 352
5.252034 Primorial prime 19: 384
10.147519 Primorial prime 20: 457
</pre>
 
=={{header|Sidef}}==
<langsyntaxhighlight lang="ruby">func primorial_primes(n) {
 
var k = 1
Line 2,773 ⟶ 3,074:
}
 
say primorial_primes(20)</langsyntaxhighlight>
{{out}}
<pre>
[1, 2, 3, 4, 5, 6, 11, 13, 24, 66, 68, 75, 167, 171, 172, 287, 310, 352, 384, 457]
</pre>
 
=={{header|Swift}}==
 
{{libheader|AttaSwift BigInt}}
 
<syntaxhighlight lang="swift">import BigInt
import Foundation
 
extension BinaryInteger {
@inlinable
public var isPrime: Bool {
if self == 0 || self == 1 {
return false
} else if self == 2 {
return true
}
 
let max = Self(ceil((Double(self).squareRoot())))
 
for i in stride(from: 2, through: max, by: 1) where self % i == 0 {
return false
}
 
return true
}
}
 
let limit = 20
var primorial = 1
var count = 1
var p = 3
var prod = BigInt(2)
 
print(1, terminator: " ")
 
while true {
defer {
p += 2
}
 
guard p.isPrime else {
continue
}
 
prod *= BigInt(p)
primorial += 1
 
if (prod + 1).isPrime() || (prod - 1).isPrime() {
print(primorial, terminator: " ")
 
count += 1
 
fflush(stdout)
 
if count == limit {
break
}
}
}</syntaxhighlight>
 
{{out}}
 
<pre>1 2 3 4 5 6 11 13 24 66 68 75 167 171 172 287 310 352 384 457</pre>
 
=={{header|Wren}}==
===Wren-CLI (BigInt)===
{{libheader|Wren-big}}
{{libheader|Wren-math}}
Just the first 15 (about 4 minutes on my machine) as waiting for the first 20 would take too long.
<syntaxhighlight lang="wren">import "./big" for BigInt
import "./math" for Int
import "io" for Stdout
 
var primes = Int.primeSieve(4000) // more than enough for this task
System.print("The indices of the first 15 primorial numbers, p, where p + 1 or p - 1 is prime are:")
var count = 0
var prod = BigInt.two
for (i in 1...primes.count) {
if ((prod-1).isProbablePrime(5) || (prod+1).isProbablePrime(5)) {
count = count + 1
System.write("%(i) ")
Stdout.flush()
if (count == 15) break
}
prod = prod * primes[i]
}
System.print()</syntaxhighlight>
 
{{out}}
<pre>
The indices of the first 15 primorial numbers, p, where p + 1 or p - 1 is prime are:
1 2 3 4 5 6 11 13 24 66 68 75 167 171 172
</pre>
===Embedded (GMP)===
{{libheader|Wren-gmp}}
{{libheader|Wren-fmt}}
Merged from another removed draft task which is the reason for the more fulsome output here. Much quicker than BigInt running in around 53.4 seconds.
<syntaxhighlight lang="wren">import "./gmp" for Mpz
import "./math" for Int
import "./fmt" for Fmt
 
var limit = 30
var c = 0
var i = 0
var primes = Int.primeSieve(9999) // more than enough
var p = Mpz.one
var two64 = Mpz.two.pow(64)
System.print("First %(limit) factorial primes:")
while (true) {
var r = (p < two64) ? 1 : 0 // test for definite primeness below 2^64
for (qs in [[p-1, "-"], [p+1, "+"]]) {
if (qs[0].probPrime(15) > r) {
var s = qs[0].toString
var sc = s.count
var digs = sc > 40 ? "(%(sc) digits)" : ""
var pn = "p%(i)#"
Fmt.print("$2d: $5s $s 1 = $20a $s", c = c + 1, pn, qs[1], s, digs)
if (c == limit) return
}
}
p.mul(primes[i])
i = i + 1
}</syntaxhighlight>
 
{{out}}
<pre>
First 30 factorial primes:
1: p0# + 1 = 2
2: p1# + 1 = 3
3: p2# - 1 = 5
4: p2# + 1 = 7
5: p3# - 1 = 29
6: p3# + 1 = 31
7: p4# + 1 = 211
8: p5# - 1 = 2309
9: p5# + 1 = 2311
10: p6# - 1 = 30029
11: p11# + 1 = 200560490131
12: p13# - 1 = 304250263527209
13: p24# - 1 = 23768741896345550770650537601358309
14: p66# - 1 = 19361386640700823163...29148240284399976569 (131 digits)
15: p68# - 1 = 21597045956102547214...98759003964186453789 (136 digits)
16: p75# + 1 = 17196201054584064334...62756822275663694111 (154 digits)
17: p167# - 1 = 19649288510530675457...35580823050358968029 (413 digits)
18: p171# + 1 = 20404068993016374194...29492908966644747931 (425 digits)
19: p172# + 1 = 20832554441869718052...12260054944287636531 (428 digits)
20: p287# - 1 = 71488723083486699645...63871022000761714929 (790 digits)
21: p310# - 1 = 40476351620665036743...10663664196050230069 (866 digits)
22: p352# - 1 = 13372477493552802137...21698973741675973189 (1007 digits)
23: p384# + 1 = 78244737296323701708...84011652643245393971 (1115 digits)
24: p457# + 1 = 68948124012218025568...25023568563926988371 (1368 digits)
25: p564# - 1 = 12039145942930719470...56788854266062940789 (1750 digits)
26: p590# - 1 = 19983712295113492764...61704122697617268869 (1844 digits)
27: p616# + 1 = 13195724337318102247...85805719764535513291 (1939 digits)
28: p620# - 1 = 57304682725550803084...81581766766846907409 (1953 digits)
29: p643# + 1 = 15034815029008301639...38987057002293989891 (2038 digits)
30: p849# - 1 = 11632076146197231553...78739544174329780009 (2811 digits)
</pre>
 
Line 2,782 ⟶ 3,241:
{{trans|C}}
Uses libGMP (GNU MP Bignum Library)
<langsyntaxhighlight lang="zkl">var [const] BN=Import("zklBigNum"); // libGMP
p,s,i,n:=BN(1),BN(1), 0,0;
do{ n+=1;
Line 2,791 ⟶ 3,250:
i+=1;
}
}while(i<20);</langsyntaxhighlight>
{{out}}
<pre>
9,476

edits