Primorial numbers: Difference between revisions
Content deleted Content added
m C code depends on GMP |
m →{{header|JavaScript}}: typo |
||
(37 intermediate revisions by 19 users not shown) | |||
Line 1:
{{task|Prime Numbers}}
Primorial numbers are those formed by multiplying successive prime numbers.
The primorial number series is:
::* primorial(0) = 1 (by definition)
::* primorial(1) = 2 (2)
Line 15:
To express this mathematically, '''primorial<sub><big>''n''</big></sub>''' is
the product of the first <big>''n''</big> (successive) primes:
<big><big><big>
: <math>primorial_n = \prod_{k=1}^n prime_k</math>
Line 28 ⟶ 29:
;Task:
* Show the first ten primorial numbers (0 ──► 9, inclusive).
* Show the length of primorial numbers whose index is: 10 100 1,000 10,000 and 100,000.
Line 39:
;Related tasks:
* [[Sequence of primorial primes]]
* [[Factorial]]
* [[Fortunate_numbers]]
;See also:
* the MathWorld webpage: [http://mathworld.wolfram.com/Primorial.html primorial]
* the Wikipedia webpage: [[wp:Primorial|primorial]].
* the OEIS webpage: [[oeis:A002110|A002110]].
<br><br>
=={{header|11l}}==
{{trans|Python}}
<syntaxhighlight lang="11l">F get_primes(primes_count)
V limit = 17 * primes_count
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
[Int] primes
L(prime) is_prime
I prime
primes.append(L.index)
I primes.len == primes_count
L.break
R primes
V primes = get_primes(100000)
F primorial(n)
BigInt r = 1
L(i) 0 .< n
r *= :primes[i]
R r
print(‘First ten primorials: ’(0.<10).map(n -> primorial(n)))
L(e) 6
V n = 10 ^ e
print(‘primorial(#.) has #. digits’.format(n, String(primorial(n)).len))</syntaxhighlight>
{{out}}
<pre>
First ten primorials: [1, 2, 6, 30, 210, 2310, 30030, 510510, 9699690, 223092870]
primorial(1) has 1 digits
primorial(10) has 10 digits
primorial(100) has 220 digits
primorial(1000) has 3393 digits
primorial(10000) has 45337 digits
primorial(100000) has 563921 digits
</pre>
=={{header|Arturo}}==
<syntaxhighlight lang="arturo">primes: [2] ++ select.first: 99999 range.step: 2 3 ∞ => prime?
primorial: function [n][
if 0 = n -> return 1
product take primes n
]
print "First ten primorials:"
loop 0..9 => [print primorial &]
print ""
loop 1..5 'm -> print [
"primorial" 10^m "has" size ~"|primorial 10^m|" "digits"
]</syntaxhighlight>
{{out}}
<pre>First ten primorials:
1
2
6
30
210
2310
30030
510510
9699690
223092870
primorial 10 has 10 digits
primorial 100 has 220 digits
primorial 1000 has 3393 digits
primorial 10000 has 45337 digits
primorial 100000 has 563921 digits</pre>
=={{header|C}}==
{{libheader|GMP}}
Uses a custom bit-sieve to generate primes, and GMP to keep track of the value of the primorial. Output takes ~3m to generate on a typical laptop.
<syntaxhighlight lang="c">
#include <inttypes.h>
#include <math.h>
Line 133 ⟶ 209:
return 0;
}
</syntaxhighlight>
{{out}}
<pre>
Line 154 ⟶ 230:
</pre>
=={{header|C#|Csharp}}==
The first 10 primorial numbers are calculated exactly, using integers. The number of digits are calculated exactly, using the summation of Log10()'s of the set of prime numbers. Nowhere in the task description does it say to calculate the larger-than-integer numbers, then count the digits, it just says to indicate the exact number of digits. This allows the program to execute rather quickly, as in just over 1/8 of a second at Tio.run. This is quite a bit quicker than the product tree algorithms presented elsewhere on this page that take 2 to 4 seconds on faster machines than are available at Tio.run.
<syntaxhighlight lang="cpp">using System;
class Program {
static int l;
static int[] gp(int n) {
var c = new bool[n]; var r = new int[(int)(1.28 * n)];
l = 0; r[l++] = 2; r[l++] = 3; int j, d, lim = (int)Math.Sqrt(n);
for (int i = 9; i < n; i += 6) c[i] = true;
for (j = 5, d = 4; j < lim; j += (d = 6 - d)) if (!c[j]) { r[l++] = j;
for (int k = j * j, ki = j << 1; k < n; k += ki) c[k] = true; }
for ( ; j < n; j += (d = 6 - d)) if (!c[j]) r[l++] = j; return r; }
static void Main(string[] args) {
var sw = System.Diagnostics.Stopwatch.StartNew();
var res = gp(15485864); sw.Stop();
double gpt = sw.Elapsed.TotalMilliseconds, tt;
var s = new string[19]; int si = 0;
s[si++] = String.Format("primes gen time: {0} ms", gpt); sw.Restart();
s[si++] = " Nth Primorial";
double y = 0; int x = 1, i = 0, lmt = 10;
s[si++] = String.Format("{0,7} {1}", 0, x);
while (true) {
if (i < 9) s[si++] = String.Format("{0,7} {1}", i + 1, x *= res[i]);
if (i == 8) s[si++] = " Nth Digits Time";
y += Math.Log10(res[i]);
if (++i == lmt) {
s[si++] = String.Format("{0,7} {1,-7} {2,7} ms", lmt, 1 + (int)y,
sw.Elapsed.TotalMilliseconds);
if ((lmt *= 10) > (int)1e6) break; } }
sw.Stop();
Console.WriteLine("{0}\n Tabulation: {1} ms", string.Join("\n", s),
tt = sw.Elapsed.TotalMilliseconds);
Console.Write(" Total:{0} ms", gpt + tt); } }</syntaxhighlight>
{{out}}
<pre>primes gen time: 85.4715 ms
Nth Primorial
0 1
1 2
2 6
3 30
4 210
5 2310
6 30030
7 510510
8 9699690
9 223092870
Nth Digits Time
10 10 0.0695 ms
100 220 0.0898 ms
1000 3393 0.1335 ms
10000 45337 0.5501 ms
100000 563921 4.4646 ms
1000000 6722809 44.4457 ms
Tabulation: 44.4968 ms
Total:129.9683 ms</pre>
=={{header|C++}}==
{{libheader|GMP}}
{{libheader|Primesieve}}
<syntaxhighlight lang="cpp">#include <gmpxx.h>
#include <primesieve.hpp>
#include <cstdint>
#include <iomanip>
#include <iostream>
size_t digits(const mpz_class& n) { return n.get_str().length(); }
mpz_class primorial(unsigned int n) {
mpz_primorial_ui(p.get_mpz_t(), n);
return
}
int main() {
primesieve::iterator pi;
std::cout << "First 10 primorial numbers:\n";
for (mpz_class pn = 1; index < 10; ++index) {
unsigned int prime = pi.next_prime();
std::cout << index << ": " << pn << '\n';
pn *=
}
for (uint64_t power =
uint64_t prime = primesieve::nth_prime(power);
}
return 0;
}</
{{out}}
<pre>
First 10 primorial numbers:
0: 1
1: 2
2: 6
3: 30
4: 210
5: 2310
6: 30030
7: 510510
8: 9699690
9: 223092870
Length of primorial
10: 10
100: 220
1000: 3393
10000: 45337
100000: 563921
1000000: 6722809
</pre>
Line 268 ⟶ 351:
===Single Process===
Using HashMap prime number generation from https://rosettacode.org/wiki/Sieve_of_Eratosthenes#Unbounded_Versions
<
(:gen-class))
Line 314 ⟶ 397:
(println (format "primorial ( %7d ) has %8d digits\tafter %.3f secs" ; Output with time since starting for remainder
(long i) (count (str p)) (elapsed-secs))))))
</syntaxhighlight>
{{Output}}
<pre>
Line 337 ⟶ 420:
===Parallel Process===
Using HashMap prime number generation from https://rosettacode.org/wiki/Sieve_of_Eratosthenes#Unbounded_Versions
<
(:gen-class))
(defn primes-hashmap
Line 389 ⟶ 472:
(println (format "primorial ( %7d ) has %8d digits\tafter %.3f secs" ; Output with time since starting for remainder
(long i) (count (str p)) (elapsed-secs))))))
</syntaxhighlight>
{{Output}}
<pre>
Line 409 ⟶ 492:
Using: i7 920 @ 2.67 GHz CPU with Windows 10 /64 bit OS
</pre>
=={{header|CLU}}==
<syntaxhighlight lang="clu">% This program uses the 'bigint' cluster from
% the 'misc.lib' included with PCLU.
isqrt = proc (s: int) returns (int)
x0: int := s/2
if x0=0 then return(s) end
x1: int := (x0 + s/x0)/2
while x1 < x0 do
x0 := x1
x1 := (x0 + s/x0)/2
end
return(x0)
end isqrt
sieve = proc (n: int) returns (array[bool])
prime: array[bool] := array[bool]$fill(0,n+1,true)
prime[0] := false
prime[1] := false
for p: int in int$from_to(2, isqrt(n)) do
if prime[p] then
for c: int in int$from_to_by(p*p,n,p) do
prime[c] := false
end
end
end
return(prime)
end sieve
% Calculate the N'th primorial given a boolean array denoting primes
primorial = proc (n: int, prime: array[bool])
returns (bigint) signals (out_of_primes)
% 0'th primorial = 1
p: bigint := bigint$i2bi(1)
for i: int in array[bool]$indexes(prime) do
if ~prime[i] then continue end
if n=0 then break end
p := p * bigint$i2bi(i)
n := n-1
end
if n>0 then signal out_of_primes end
return(p)
end primorial
% Find the length in digits of a bigint without converting it to a string.
% The naive way takes over an hour to count the digits for p(100000),
% this one ~5 minutes.
n_digits = proc (n: bigint) returns (int)
own zero: bigint := bigint$i2bi(0)
own ten: bigint := bigint$i2bi(10)
digs: int := 1
dstep: int := 1
tenfac: bigint := ten
step: bigint := ten
while n >= tenfac do
digs := digs + dstep
step := step * ten
dstep := dstep + 1
next: bigint := tenfac*step
if n >= next then
tenfac := next
else
step, dstep := ten, 1
tenfac := tenfac*step
end
end
return(digs)
end n_digits
start_up = proc ()
po: stream := stream$primary_output()
% Sieve a million primes
prime: array[bool] := sieve(15485863)
% Show the first 10 primorials
for i: int in int$from_to(0,9) do
stream$puts(po, "primorial(" || int$unparse(i) || ") = ")
stream$putright(po, bigint$unparse(primorial(i, prime)), 15)
stream$putl(po, "")
end
% Show the length of some bigger primorial numbers
for tpow: int in int$from_to(1,5) do
p_ix: int := 10**tpow
stream$puts(po, "length of primorial(")
stream$putright(po, int$unparse(p_ix), 7)
stream$puts(po, ") = ")
stream$putright(po, int$unparse(n_digits(primorial(p_ix, prime))), 7)
stream$putl(po, "")
end
end start_up</syntaxhighlight>
{{out}}
<pre>primorial(0) = 1
primorial(1) = 2
primorial(2) = 6
primorial(3) = 30
primorial(4) = 210
primorial(5) = 2310
primorial(6) = 30030
primorial(7) = 510510
primorial(8) = 9699690
primorial(9) = 223092870
length of primorial( 10) = 10
length of primorial( 100) = 220
length of primorial( 1000) = 3393
length of primorial( 10000) = 45337
length of primorial( 100000) = 563921</pre>
=={{header|Common Lisp}}==
<
(defun primorial-number-length (n w)
(values (primorial-number n) (primorial-length w)))
Line 426 ⟶ 620:
(defun primep (n)
(loop for a from 2 to (isqrt n) never (zerop (mod n a))))
</syntaxhighlight>
{{out}}
<pre>
Line 436 ⟶ 630:
=={{header|D}}==
{{trans|Java}}
<syntaxhighlight lang="d">
import std.stdio;
import std.format;
Line 495 ⟶ 689:
}
</syntaxhighlight>
{{out}}
Line 516 ⟶ 710:
</pre>
=={{header|Delphi}}==
See [https://rosettacode.org/wiki/Primorial_numbers#alternative Pascal].
=={{header|Elixir}}==
Prime generator works too inefficiently to generate 1 million in a short time, but it will work eventually. This solution is efficient up to 100,000 primes.
<syntaxhighlight lang="elixir">
defmodule SieveofEratosthenes do
def init(lim) do
Line 534 ⟶ 730:
end
end
</syntaxhighlight>
<syntaxhighlight lang="elixir">
defmodule Primorial do
def first(n,primes) do
Line 572 ⟶ 768:
defp str_fr(pri,i), do: IO.puts("Primorial #{i} has length: #{pri}")
end
</syntaxhighlight>
<syntaxhighlight lang="elixir">
Primorial.first(10,SieveofEratosthenes.init(50))
Primorial.numbers([10,100,1_000,10_000,100_000],SieveofEratosthenes.init(1_300_000))
</syntaxhighlight>
{{out}}
Line 597 ⟶ 793:
=={{header|F_Sharp|F#}}==
This task uses [http://www.rosettacode.org/wiki/Extensible_prime_generator#
<syntaxhighlight lang="fsharp">
// Primorial Numbers. Nigel Galloway: August 3rd., 2021
primes32()|>Seq.scan((*)) 1|>Seq.take 10|>Seq.iter(printf "%d "); printfn "\n"
[10;100;1000;10000;100000]|>List.iter(fun n->printfn "%d" ((int)(System.Numerics.BigInteger.Log10 (Seq.item n (primesI()|>Seq.scan((*)) 1I)))+1))
</syntaxhighlight>
{{out}}
<pre>
1 2 6 30 210 2310 30030 510510 9699690 223092870
10
220
Line 636 ⟶ 811:
=={{header|Factor}}==
<syntaxhighlight lang="text">USING: formatting kernel literals math math.functions
math.primes sequences ;
IN: rosetta-code.primorial-numbers
Line 659 ⟶ 834:
: main ( -- ) part1 part2 ;
MAIN: main</
{{out}}
<pre>
Line 699 ⟶ 874:
The overflow happens in D*N + C, and converting D from INTEGER*4 to INTEGER*8 prevented the overflow, but introduces its own slowness. Activating "maximum optimisations" reduced 241 to 199, and reverting to base 100 with no INTEGER*8 converted 278 to 133. Then, abandoning the array bound checking reduced it further, to 121. The end result of the trick is to limit the base to 100. Given that, INTEGER*2 could be used for DIGIT, but a trial run showed almost the same time taken for Primorial(100000).
Hopefully, the compiler recognises the connection between the consecutive statements <code>D = B.DIGIT(I)</code> then <code>D = D*N + C</code> (rather than <code>D = B.DIGIT(I)*N + C</code>) which was done to facilitate trying INTEGER*8 D without needing to blabber on about conversion routines. But more importantly, one can dream that the compiler will recognise the classic sequence <
C = D/BIGBASE</
An alternative method, once consecutive primorials are not required, would be to compute the big number product of say ten consecutive primes then multiply the main big number by that, using multi-precision arithmetic for both. Abandoning the trick that restricts the base to 100 (for the current upper limit of the millionth prime) would allow the use of larger bases. Another possibility would be to calculate in a base more directly matching that of the computer (since the variable-length decimal arithmetic of the IBM1620 ''et al'' is no longer available), for instance base 65536 with sixteen-bit words, etc. Inspection of the result to calculate the number of decimal digits required would not be troublesome. In such a case, one might try something like<
INTEGER*2 II(2),C,R !Some 16-bit variables.
EQUIVALENCE (D,II) !Align.
EQUIVALENCE (II(1),C),(II(2),R) !Carry in the high order half of D, Result in the low.</
Supposing that unsigned 16-bit arithmetic was available then the product in D need not be split into a carry and a digit via the MOD and divide as above. But this is unlikely. Only in assembly would good code be possible.
Line 716 ⟶ 891:
On the other hand, the modifying prefix nP for E (and F) format codes has long been available. This shifts the position of the decimal point left or right by n places, and with the E format code modifies the exponent accordingly. Thus, 1.2345E+5 can become .12345E+6 via the prefix -1P as in FORMAT 113. Evidently, this is the same value. When used with a F code there is no exponent part to modify accordingly, but here, the exponent is calculated separately (and presented via the I0 format code), and, one is added in the WRITE statement's output expressions, thus I4 + 1 and I8 + 1. The point of all this is that the resulting exponent part gives the number of decimal digits in the number, as per the specification.
<syntaxhighlight lang="fortran">
MODULE BIGNUMBERS !Limited services: decimal integers, no negative numbers.
INTEGER BIGORDER !A limit attempt at generality.
Line 911 ⟶ 1,086:
IF (MARK.LE.LASTP) GO TO 112 !Are we there yet?
END !So much for that.
</syntaxhighlight>
===Results===
Line 954 ⟶ 1,129:
=={{header|FreeBASIC}}==
<
' compile with: fbc -s console
Line 1,050 ⟶ 1,225:
Print : Print "hit any key to end program"
Sleep
End</
{{out}}
<pre> primorial(0) = 1
Line 1,071 ⟶ 1,246:
=={{header|Frink}}==
===Simple version===
<
for n = 0 to 9
Line 1,078 ⟶ 1,253:
for n = [10, 100, 1000, 10000, 100000, million]
println["Length of primorial $n is " + length[toString[primorial[n]]] + " decimal digits."]
</syntaxhighlight>
{{out}}
<pre>
Line 1,102 ⟶ 1,277:
The program above can be made much faster by using a "binary splitting" algorithm that recursively breaks the number range into halves, and then multiplies these smaller numbers together, which will be faster when run under a Java Virtual Machine version 1.8 and later which have a better-than-O(n<SUP>2</SUP>) multiply operation. (Did you know that Frink's author submitted the changes to Java that made <CODE>BigInteger</CODE> and <CODE>BigDecimal</CODE> much faster with lots of digits?)
<
primorialSplitting[n] :=
{
Line 1,133 ⟶ 1,308:
for n = [10, 100, 1000, 10000, 100000, million]
println["Length of primorial $n is " + length[toString[primorialSplitting[n]]] + " decimal digits."]
</syntaxhighlight>
=={{header|Go}}==
Line 1,140 ⟶ 1,315:
a fast external package is used to generate the primes.
The Go standard <tt>math/big</tt> package is used to multiply these as exact integers.
<
import (
Line 1,169 ⟶ 1,344:
fmt.Printf("\t(after %v)\n", time.Since(start))
}
}</
{{out}}
<pre>
Line 1,199 ⟶ 1,374:
{{libheader|GMP(Go wrapper)}}
As noted elsewhere, it is far quicker to use a product tree to multiply the primes together. In the following version, the vecprod() function follows the lines of the Phix example with a GMP wrapper (rather than Go's native big.Int type) being used for extra speed.
<
import (
Line 1,246 ⟶ 1,421:
}
fmt.Printf("\nTook %s\n", time.Since(start))
}</
{{out}}
Line 1,274 ⟶ 1,449:
=={{header|Haskell}}==
<syntaxhighlight lang="haskell">
import Control.Arrow ((&&&))
import Data.List (scanl1, foldl1')
Line 1,307 ⟶ 1,482:
calculate primorialTens
</syntaxhighlight>
{{out}}
Line 1,325 ⟶ 1,500:
Implementation:
<
Task examples:
<
1 2 6 30 210 2310 30030 510510 9699690 223092870
#":primorial 10x NB. lengths (of decimal representations)...
Line 1,342 ⟶ 1,517:
563921
#":primorial 1000000x
6722809</
Note that the x suffix on a decimal number indicates that calculations should be exact (what the lisp community has dubbed "bignums"). This is a bit slow (internally, every number winds up being represented as a list of what might be thought of as "digits" in a very large base), but it gets the job done.
=={{header|Java}}==
<
public class PrimorialNumbers {
Line 1,391 ⟶ 1,566:
return composite;
}
}</
<pre>primorial(0): 1
Line 1,408 ⟶ 1,583:
primorial(10^4) has length 45337
primorial(10^5) has length 563921</pre>
=={{header|JavaScript}}==
===Exact integers===
{{works with|Node.js}}
Uses the native BigInt type availiable in Node.js. As this takes a while, some values between 10 000 and 100 000 are shown to help suggest it is still doing stuff...
<syntaxhighlight lang="javascript">
{ // calculate and show some primorial numbers
'use strict'
let primorial = 1n
let prime = 1n
let pn = []
const maxNumber = 2000000
let isPrime = []
for( let i = 1; i <= maxNumber; i ++ ){ isPrime[ i ] = i % 2 != 0 }
isPrime[ 1 ] = false
isPrime[ 2 ] = true
const rootMaxNumber = Math.floor( Math.sqrt( maxNumber ) )
for( let s = 3; s <= rootMaxNumber; s += 2 ){
if( isPrime[ s ] ){
for( let p = s * s; p <= maxNumber; p += s ){ isPrime[ p ] = false }
}
}
const primeMax = 100000
pn[ 0 ] = 1
let nextToShow = 10
for( let i = 1; i <= primeMax; i ++ ){
// find the next prime
prime += 1n
while( ! isPrime[ prime ] ){ prime += 1n }
primorial *= prime
if( i < 10 ){
pn[ i ] = primorial
}
else if( i == nextToShow ){
if( nextToShow < 10000 ){
nextToShow *= 10
}
else{
nextToShow += 10000
}
if( i == 10 ){ console.log( "primorials 0-9: ", pn.toString() ) }
// show the number of digits in the primorial
let p = primorial
let length = 0
while( p > 0 ){
length += 1
p /= 10n
}
console.log( "length of primorial " + i + " is "+ length )
}
}
}
</syntaxhighlight>
{{out}}
<pre>
primorials 0-9: 1,2,6,30,210,2310,30030,510510,9699690,223092870
length of primorial 10 is 10
length of primorial 100 is 220
length of primorial 1000 is 3393
length of primorial 10000 is 45337
length of primorial 20000 is 97389
length of primorial 30000 is 151937
length of primorial 40000 is 208100
length of primorial 50000 is 265460
length of primorial 60000 is 323772
length of primorial 70000 is 382876
length of primorial 80000 is 442655
length of primorial 90000 is 503026
length of primorial 100000 is 563921
</pre>
Runtime is around 10 minutes on the Windows 11 laptop I'm using (too long for TIO.RUN).
===Using a reduced number of digits===
{{works with|Node.js}}
A modification of the Exact integers version, also using the native BigInt type.
As we only need to show digit counts, this deviates from the task requirement to use exact integers by only keeping around 500 leading digits., which is MUCH faster.
<syntaxhighlight lang="javascript">
{ // calculate and show some primorial numbers
'use strict'
let primorial = 1n
let prime = 1n
let pn = []
const maxNumber = 2000000
let isPrime = []
for( let i = 1; i <= maxNumber; i ++ ){ isPrime[ i ] = i % 2 != 0 }
isPrime[ 1 ] = false
isPrime[ 2 ] = true
const rootMaxNumber = Math.floor( Math.sqrt( maxNumber ) )
for( let s = 3; s <= rootMaxNumber; s += 2 ){
if( isPrime[ s ] ){
for( let p = s * s; p <= maxNumber; p += s ){ isPrime[ p ] = false }
}
}
const primeMax = 100000
pn[ 0 ] = 1
let nextToShow = 10
let reducedDigits = 0
const n500 = 10n**500n
const n1000 = 10n**1000n
for( let i = 1; i <= primeMax; i ++ ){
// find the next prime
prime += 1n
while( ! isPrime[ prime ] ){ prime += 1n }
primorial *= prime
if( i < 10 ){
pn[ i ] = primorial
}
else if( i == nextToShow ){
if( nextToShow < 10000 ){
nextToShow *= 10
}
else{
nextToShow += 10000
}
if( i == 10 ){ console.log( "primorials 0-9: ", pn.toString() ) }
// show the number of digits in the primorial
let p = primorial
let length = 0
while( p > 0 ){
length += 1
p /= 10n
}
console.log( "length of primorial " + i + " is "+ ( reducedDigits + length ) )
}
if( primorial > n1000 ){
// the number has more than 1000 digits - reduce it to 500-ish
primorial /= n500
reducedDigits += 500
}
}
}
</syntaxhighlight>
{{out}}
<pre>
primorials 0-9: 1,2,6,30,210,2310,30030,510510,9699690,223092870
length of primorial 10 is 10
length of primorial 100 is 220
length of primorial 1000 is 3393
length of primorial 10000 is 45337
length of primorial 20000 is 97389
length of primorial 30000 is 151937
length of primorial 40000 is 208100
length of primorial 50000 is 265460
length of primorial 60000 is 323772
length of primorial 70000 is 382876
length of primorial 80000 is 442655
length of primorial 90000 is 503026
length of primorial 100000 is 563921
</pre>
Runtime is around 1 second on TIO.RUN.
=={{header|jq}}==
'''Works with gojq, the Go implementation of jq'''
See [[Erdős-primes#jq]] for a suitable definition of `is_prime` as used here.
<syntaxhighlight lang="jq">def primes:
2, range(3; infinite; 2) | select(is_prime);
# generate an infinite stream of primorials beginning with primorial(0)
def primorials:
0, foreach primes as $p (1; .*$p; .);
"The first ten primorial numbers are:",
limit(10; primorials),
"\nThe primorials with the given index have the lengths shown:",
([10, 100, 1000, 10000, 100000] as $sample
| limit($sample|length;
foreach primes as $p ([0,1]; # [index, primorial]
.[0]+=1 | .[1] *= $p;
select(.[0]|IN($sample[])) | [.[0], (.[1]|tostring|length)] ) ))</syntaxhighlight>
{{out}}
<pre>
The first ten primorial numbers are:
0
2
6
30
210
2310
30030
510510
9699690
223092870
The primorials with the given index have the lengths shown:
[10,10]
[100,220]
[1000,3393]
[10000,45337]
[100000,563921]</pre>
=={{header|Julia}}==
{{trans|Python}}
<
using Primes
Line 1,426 ⟶ 1,799:
println("primorial($n) has length $plen digits in base 10.")
end
</syntaxhighlight>
{{output}}
<pre>The first ten primorials are: BigInt[2, 6, 30, 210, 2310, 30030, 510510, 9699690, 223092870, 6469693230]
Line 1,438 ⟶ 1,811:
=={{header|Kotlin}}==
<
import java.math.BigInteger
Line 1,483 ⟶ 1,856:
p += 2
}
}</
{{out}}
Line 1,508 ⟶ 1,881:
=={{header|Lingo}}==
For generating the list of primes an auto-extending Sieve of Eratosthenes lib is used (fast), and for the larger primorials a simple custom big-integer lib (very slow).
<
sieve = script("math.primes").new()
bigint = script("bigint").new()
Line 1,529 ⟶ 1,902:
pow10 = pow10 * 10
end if
end repeat</
{{out}}
<pre>
Line 1,550 ⟶ 1,923:
=={{header|Maple}}==
<syntaxhighlight lang="maple">
with(NumberTheory):
Line 1,581 ⟶ 1,954:
end;
</syntaxhighlight>
{{out}}<pre>
"The first 10 primorial numbers"
Line 1,617 ⟶ 1,990:
</pre>
=={{header|Mathematica}}/{{header|Wolfram Language}}==
The first 10 primorial numbers are:
<
{{out}}
<pre>
{1,2,6,30,210,2310,30030,510510,9699690,223092870}</pre>
From the first million primes:
<syntaxhighlight lang="mathematica">primes = Prime @ Range[10^6]; </syntaxhighlight>
define the primorial:
<syntaxhighlight lang="mathematica">primorial[n_]:= Times @@ primes[[;;n]]</syntaxhighlight>
The lengths of selected primorial numbers are:
<syntaxhighlight lang="mathematica">Grid@Table[{"primorial(10^" <> ToString[n] <> ") has ",
{timing,answer}=AbsoluteTiming[IntegerLength@primorial[10^n]];answer,
" digits in "<>ToString@timing<>" seconds"}, {n,6}]</syntaxhighlight>
{{out}}
<pre>
primorial(10^1) has 10 digits in 0.000055 seconds
primorial(10^2) has 220
primorial(10^3) has 3393 digits in 0.000425 seconds
primorial(10^4) has 45337 digits in 0.006795 seconds
primorial(10^5) has 563921 digits in 0.076371 seconds
primorial(10^6) has 6722809 digits in 1.29307 seconds
</pre>
=={{header|Nickle}}==
<
# For 1 million primes
Line 1,671 ⟶ 2,051:
int digits = floor(Math::log10(pn)) + 1;
printf("primorial(%d) has %d digits, in %dms\n", p, digits, millis() - start);
}</
{{out}}
Line 1,691 ⟶ 2,071:
primorial(10000) has 45337 digits, in 128ms
primorial(100000) has 563921 digits, in 12304ms</pre>
=={{header|Nim}}==
===Single thread===
{{libheader|bignum}}
We use a sieve of Erathosthenes to generate the primes, but with only the odd numbers to reduce memory usage. Even for one millions primes, the execution time is negligible (0.12s)
To compute the primorial numbers, we use an iterator. Performance is good with 1.1s for primorial(10000). But for one million, this takes much more time.
<syntaxhighlight lang="nim">import times
let t0 = cpuTime()
####################################################################################################
# Build list of primes.
const
NPrimes = 1_000_000
N = 16 * NPrimes
var sieve: array[(N - 1) div 2 + 1, bool] # False (default) means prime.
for i, composite in sieve:
if not composite:
let n = 2 * i + 3
for k in countup(n * n, N, 2 * n):
sieve[(k - 3) div 2] = true
var primes = @[2]
for i, composite in sieve:
if not composite:
primes.add 2 * i + 3
if primes.len < NPrimes:
quit "Not enough primes. Please, increase value of N."
####################################################################################################
# Compute primorial.
import strformat
import bignum
const LastToPrint = NPrimes
iterator primorials(): Int =
## Yield successive primorial numbers.
var prim = newInt(1)
yield prim
for p in primes:
prim *= p
yield prim
var n = 0
for prim in primorials():
echo &"primorial({n}) = {prim}"
inc n
if n == 10: break
n = 0
var nextToPrint = 10
for prim in primorials():
if n == nextToPrint:
echo &"primorial({n}) has {($prim).len} digits"
if nextToPrint == LastToPrint: break
nextToPrint *= 10
inc n
echo ""
echo &"Total time: {cpuTime() - t0:.2f} s"</syntaxhighlight>
{{out}}
<pre>primorial(0) = 1
primorial(1) = 2
primorial(2) = 6
primorial(3) = 30
primorial(4) = 210
primorial(5) = 2310
primorial(6) = 30030
primorial(7) = 510510
primorial(8) = 9699690
primorial(9) = 223092870
primorial(10) has 10 digits
primorial(100) has 220 digits
primorial(1000) has 3393 digits
primorial(10000) has 45337 digits
primorial(100000) has 563921 digits
primorial(1000000) has 6722809 digits
Total time: 127.65 s</pre>
CPU: Intel(R) Core(TM) i5-8250U CPU @ 1.60GHz, 2607 MHz with 8GB RAM.
===Multiple threads===
With several threads, we cannot use an iterator anymore. For N threads (workers), we split the list of primes in N sublists and let each worker compute a product. We terminate with a final multiplication of the N results. With four workers, we get the result in about 10 seconds. With eight workers, we get it in about five seconds.
Note that to get execution time, we can no longer use “cpuTime” as it returns only the CPU time used by the main thread. So, we use “getMonoTime” instead.
<syntaxhighlight lang="nim">import std/monotimes
let t0 = getMonoTime()
####################################################################################################
# Build list of primes.
const
NPrimes = 1_000_000
N = 16 * NPrimes
var sieve: array[(N - 1) div 2 + 1, bool] # False (default) means prime.
for i, composite in sieve:
if not composite:
let n = 2 * i + 3
for k in countup(n * n, N, 2 * n):
sieve[(k - 3) div 2] = true
var primes = @[2]
for i, composite in sieve:
if not composite:
primes.add 2 * i + 3
if primes.len < NPrimes:
quit "Not enough primes. Please, increase value of N."
####################################################################################################
# Compute primorial.
import strformat, threadpool
import bignum
const NWorkers = 8
proc computeProduct(a: openArray[int]): Int =
result = newInt(1)
for n in a: result *= n
proc primorial(n: int): Int =
if n == 0: return newInt(1)
# Prepare sublists.
var input: array[NWorkers, seq[int]]
for i in 0..<n:
input[i mod NWorkers].add primes[i]
# Spawn workers and get partial products.
var responses: array[NWorkers, FlowVar[Int]]
for i in 0..<NWorkers:
responses[i] = spawn computeProduct(input[i])
# Compute final product.
result = ^responses[0]
for i in 1..<NWorkers:
result *= ^responses[i]
for n in 0..9:
echo &"primorial({n}) = {primorial(n)}"
for n in [10, 100, 1_000, 10_000, 1_000_000]:
echo &"primorial({n}) has {len($primorial(n))} digits"
echo ""
echo &"Total time: {(getMonoTime() - t0)}"</syntaxhighlight>
{{out}}
<pre>primorial(0) = 1
primorial(1) = 2
primorial(2) = 6
primorial(3) = 30
primorial(4) = 210
primorial(5) = 2310
primorial(6) = 30030
primorial(7) = 510510
primorial(8) = 9699690
primorial(9) = 223092870
primorial(10) has 10 digits
primorial(100) has 220 digits
primorial(1000) has 3393 digits
primorial(10000) has 45337 digits
primorial(1000000) has 6722809 digits
Total time: (seconds: 5, nanosecond: 270238339)</pre>
=={{header|PARI/GP}}==
<
vector(10,i,nthprimorial(i-1))
vector(5,n,#Str(nthprimorial(10^n)))
#Str(nthprimorial(10^6))</
{{out}}
<pre>%1 = [1, 2, 6, 30, 210, 2310, 30030, 510510, 9699690, 223092870]
Line 1,704 ⟶ 2,267:
===With vecprod===
Pari/GP 2.11 added the <code>vecprod</code> command, which makes a significantly faster version possible. We use <code>primes(n)</code> to get a vector of the first n primes, which <code>vecprod</code> multiplies using a product tree.
<
vector(6,n,#Str(nthprimorial(10^n)))</
{{out}}
<pre>[10, 220, 3393, 45337, 563921, 6722809]
Line 1,715 ⟶ 2,278:
mp_primorial {-Primorial of n; a = n# = product of primes <= n.}
so i sieve to get the right n
<
uses
sysutils,mp_types,mp_base,mp_prime,mp_numth;
Line 1,746 ⟶ 2,309:
Writeln((t1-t0)*86400.0:10:3,' s');
end.
</syntaxhighlight>
{{Out}}
<pre>MaxPrime 29 10 digits
Line 1,767 ⟶ 2,330:
Obviously GMP will do it by far better.
<
{$IFDEF FPC} {$MODE DELPHI} {$ENDIF}
uses
Line 1,876 ⟶ 2,439:
i := i*10;
until i> 100000;
end.</
{{out}}
<pre>Primorial (0->9) 1,2,6,30,210,2310,30030,510510,9699690,223092870
Line 1,903 ⟶ 2,466:
{{libheader|ntheory}}
<
say "First ten primorials: ", join ", ", map { pn_primorial($_) } 0..9;
say "primorial(10^$_) has ".(length pn_primorial(10**$_))." digits" for 1..6;</
The <code>pn_primorial</code> function is smart enough to return a <code>Math::BigInt</code> object if the result won't fit into a native integer, so it all works out.
Line 1,923 ⟶ 2,486:
Still using the library for the core activities, we can do the same in two steps. <code>primes($n)</code> returns a reference to a list of primes up to n, <code>nth_prime($n)</code> returns the nth prime, and <code>vecprod</code> does an efficient product tree. So for 10^6 we can do:
<
say length( vecprod( @{primes( nth_prime(10**6) )} ) );</
returning the same result in only slightly more time. Both examples take under 4 seconds.
Line 1,932 ⟶ 2,495:
Multiplying the vector elements in pairs is much faster for essentially the same reason that merge sort is faster than insertion sort.<br>
You could probably optimise the number of mpz_init() this invokes a fair bit, if you really wanted to.
<!--<syntaxhighlight lang="phix">(phixonline)-->
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
<span style="color: #008080;">include</span> <span style="color: #004080;">mpfr</span><span style="color: #0000FF;">.</span><span style="color: #000000;">e</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">vecprod</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">={}</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">s</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #7060A8;">mpz_init</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)}</span>
<span style="color: #008080;">else</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: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
<span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">mpz_init</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</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: #008080;">while</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: #000000;">1</span> <span style="color: #008080;">do</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: #7060A8;">floor</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: #000000;">2</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
<span style="color: #7060A8;">mpz_mul</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">],</span><span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">],</span><span style="color: #000000;">s</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: #000000;">s</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">..</span><span style="color: #7060A8;">ceil</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: #000000;">2</span><span style="color: #0000FF;">)]</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">return</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">constant</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;">max10</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;">4</span><span style="color: #0000FF;">:</span><span style="color: #000000;">6</span><span style="color: #0000FF;">),</span>
<span style="color: #000000;">tests</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">tagset</span><span style="color: #0000FF;">(</span><span style="color: #000000;">9</span><span style="color: #0000FF;">,</span><span style="color: #000000;">0</span><span style="color: #0000FF;">)&</span><span style="color: #7060A8;">sq_power</span><span style="color: #0000FF;">(</span><span style="color: #000000;">10</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">tagset</span><span style="color: #0000FF;">(</span><span style="color: #000000;">max10</span><span style="color: #0000FF;">)),</span>
<span style="color: #000000;">primes</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">get_primes</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1_000_000</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: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">tests</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">ti</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">tests</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span>
<span style="color: #004080;">mpz</span> <span style="color: #000000;">primorial</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">vecprod</span><span style="color: #0000FF;">(</span><span style="color: #000000;">primes</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">..</span><span style="color: #000000;">ti</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;">ti</span><span style="color: #0000FF;"><</span><span style="color: #000000;">10</span><span style="color: #0000FF;">?</span><span style="color: #7060A8;">sprintf</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"= %s"</span><span style="color: #0000FF;">,{</span><span style="color: #7060A8;">mpz_get_str</span><span style="color: #0000FF;">(</span><span style="color: #000000;">primorial</span><span style="color: #0000FF;">,</span><span style="color: #000000;">comma_fill</span><span style="color: #0000FF;">:=</span><span style="color: #004600;">true</span><span style="color: #0000FF;">)})</span>
<span style="color: #0000FF;">:</span><span style="color: #7060A8;">sprintf</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"has %,d digits"</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">mpz_sizeinbase</span><span style="color: #0000FF;">(</span><span style="color: #000000;">primorial</span><span style="color: #0000FF;">,</span><span style="color: #000000;">10</span><span style="color: #0000FF;">)))</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;">"Primorial(%,d) %s\n"</span><span style="color: #0000FF;">,</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">ti</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">ps</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>
<!--</syntaxhighlight>-->
{{out}}
<pre>
Line 1,983 ⟶ 2,550:
"6.2s"
</pre>
Under pwa/p2js Primorial(10,000) is obtained in 2s but 10^5 appears to be well beyond reach.
=={{header|PicoLisp}}==
This code uses '''prime?''' and '''take''' functions from [http://www.rosettacode.org/wiki/Extensible_prime_generator#PicoLisp Extensible Prime Generator(PicoLisp)]
<syntaxhighlight lang="picolisp">
(de prime? (N Lst)
(let S (sqrt N)
Line 2,014 ⟶ 2,582:
[prinl (length (primorial (** 10 4)]
#The last one takes a very long time to compute.
[prinl (length (primorial (** 10 5)]</
{{out}}
Line 2,039 ⟶ 2,607:
Uses the pure python library [https://pypi.python.org/pypi/pyprimes/0.1.1a pyprimes ].
<
from functools import reduce
Line 2,052 ⟶ 2,620:
for e in range(7):
n = 10**e
print('primorial(%i) has %i digits' % (n, len(str(primorial(n)))))</
{{out}}
Line 2,063 ⟶ 2,631:
primorial(100000) has 563921 digits
primorial(1000000) has 6722809 digits</pre>
=={{header|Quackery}}==
<code>eratosthenes</code> and <code>isprime</code> are defined at [[Sieve of Eratosthenes#Quackery]].
<syntaxhighlight lang="Quackery"> [ 0 swap
[ dip 1+
10 /
dup 0 = until ]
drop ] is digits ( n --> n )
[ stack ] is primorials ( --> s )
1299710 eratosthenes
' [ 1 ]
1299710 times
[ i^ isprime if
[ i^ over -1 peek * join ] ]
primorials put
primorials share 10 split drop echo
cr
[] 6 times
[ primorials share
10 i^ ** peek
digits join ]
echo
</syntaxhighlight>
{{out}}
<pre>[ 1 2 6 30 210 2310 30030 510510 9699690 223092870 ]
[ 1 10 220 3393 45337 563921 ]
</pre>
=={{header|Racket}}==
We have to reimplement <code>nth-prime</code> and replace it with a memorized version, to make it faster. But we can't memorize <code>primorial</code> because it would use too much memory.
<
(require (except-in math/number-theory nth-prime))
Line 2,102 ⟶ 2,705:
(printf "Primorial(10^~a) has ~a digits.\n"
i
(num-length (primorial (expt 10 i)))))</
{{out}}
<pre>(1 2 6 30 210 2310 30030 510510 9699690 223092870)
Line 2,116 ⟶ 2,719:
With the module <code>Math::Primesieve</code>, this runs in about 1/3 the time vs the built in prime generator.
{{works with|Rakudo|2018.09}}
<syntaxhighlight lang="raku"
my $sieve = Math::Primesieve.new;
Line 2,124 ⟶ 2,727:
say "First ten primorials: {(primorial $_ for ^10)}";
say "primorial(10^$_) has {primorial(10**$_).chars} digits" for 1..5;</
{{out}}
<pre>
Line 2,136 ⟶ 2,739:
===Imported library===
For a real speed boost, load the Perl 5 ntheory library.
{{libheader|ntheory}}
<syntaxhighlight lang="raku" line>use Lingua::EN::Numbers;
use ntheory:from<Perl5> <pn_primorial>;
Line 2,146 ⟶ 2,750:
comma(pn_primorial(10**$_).Str.chars),
"Elapsed seconds: {(now - $now).round: .001}";
}</
<pre>First ten primorials: 1, 2, 6, 30, 210, 2310, 30030, 510510, 9699690, 223092870
primorial(10^1) has 10 digits - Elapsed seconds: 0.002
Line 2,158 ⟶ 2,762:
=={{header|REXX}}==
<
parse arg N H . /*get optional arguments: N, L, H */
if N=='' | N==',' then N= 10
if H=='' | H==',' then H= 100000 /*
numeric digits 600000
w= length( commas( digits() ) ) /*W: width of the largest commatized #*/
@.=.; @.0= 1;
#= 6
say right(j, length(N))th(j) " primorial is: " right(commas(primorial(j) ), N+2)
end /*j*/
say
iw= length( commas(H) ) +
p= 1
if
if L\==1 then iterate /* " left─most " " \==1, " */
if strip(k, , 0)\==1 then iterate /*Not a power of 10? Then skip this K.*/
say right( commas(k), iw)th(k) ' primorial number length in decimal digits is:' ,
right( commas( length(p) ), w)
end /*k*/
exit /*stick a fork in it, we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
th: parse arg th; return word('th st nd rd', 1+ (th//10)*(th//100%10\==1)*(th//10<4))
/*──────────────────────────────────────────────────────────────────────────────────────*/
primorial: procedure expose @. s. #; parse arg y; != 1 /*obtain the arg Y. */
do p=0 to y; != ! * prime(p) /*calculate product. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
prime: procedure expose @. s. #; parse arg n; if @.n\==. then return @.n
do j=@.#+2 by 2 /*start looking at #*/
parse var j '' -1 _; if _==5 then iterate /*right─most dig≡5? */
do k=6 while s.k<=j; if j//@.k==0 then iterate j /*divide by primes. */
end /*k*/
#= # + 1; @.#= j; s.#= j * j; return j /*next prime; return*/
end /*j*/</syntaxhighlight>
{{out|output|text= when using the default inputs:}}
<pre>
</pre>
=={{header|Ring}}==
<
# Project: Primorial numbers
load "bignumber.ring"
Line 2,271 ⟶ 2,882:
see "primorial(" + string(pr-1) + ") " + "has " + len(pro) + " digits"+ nl
ok
</syntaxhighlight>
<pre>
working...
Line 2,295 ⟶ 2,906:
=={{header|Ruby}}==
<
def primorial_number(n)
Line 2,306 ⟶ 2,917:
(1..5).each do |n|
puts "primorial(10**#{n}) has #{primorial_number(10**n).to_s.size} digits"
end</
{{out}}
Line 2,318 ⟶ 2,929:
=={{header|Rust}}==
<syntaxhighlight lang="rust">
extern crate primal;
extern crate rayon;
Line 2,360 ⟶ 2,971:
println!("Digits of primorial 1_000_000 : {}",result);
}
</syntaxhighlight>
using Intel(R) Core(TM) i7-5500U CPU @ 2.40GHz
{{out}}
Line 2,389 ⟶ 3,000:
This example uses Spire's SafeLong for arbitrarily large integers and parallel vectors to accelerate bulk operations on large collections. The primorial is calculated by simply building a list of primes and taking the product. The prime generator here is relatively inefficient, but as it isn't the focus of this task the priority is brevity while retaining acceptable performance.
<
import spire.implicits._
Line 2,407 ⟶ 3,018:
def primorial(num: Int): SafeLong = if(num == 0) 1 else primesSL.take(num).to(ParVector).reduce(_*_)
lazy val primesSL: Vector[SafeLong] = 2 +: ParVector.range(3, 20000000, 2).filter(n => !Iterator.range(3, math.sqrt(n).toInt + 1, 2).exists(n%_ == 0)).toVector.sorted.map(SafeLong(_))
}</
{{out}}
Line 2,432 ⟶ 3,043:
=={{header|Sidef}}==
{{trans|Perl}}
<
'First ten primorials: ',
{|i| pn_primorial(i) }.map(^10).join(', ')
Line 2,439 ⟶ 3,050:
{ |i|
say ("primorial(10^#{i}) has " + pn_primorial(10**i).len + ' digits')
} << 1..6</
{{out}}
<pre>
Line 2,449 ⟶ 3,060:
primorial(10^5) has 563921 digits
primorial(10^6) has 6722809 digits
</pre>
=={{header|Wren}}==
===Wren CLI===
{{libheader|Wren-big}}
{{libheader|Wren-math}}
{{libheader|Wren-fmt}}
It takes very little time to sieve for the first 100,000 primes (< 0.2 seconds) but, despite using the 'binary splitting' algorithm and a trick of my own, multiplying them all together is very slow compared to the GMP-based solutions taking more than 4 minutes on my machine.
<syntaxhighlight lang="wren">import "./big" for BigInt
import "./math" for Int
import "./fmt" for Fmt
var vecprod = Fn.new { |primes|
var le = primes.count
if (le == 0) return BigInt.one
var s = List.filled(le, null)
for (i in 0...le) s[i] = BigInt.new(primes[i])
while (le > 1) {
var c = (le/2).floor
for(i in 0...c) s[i] = s[i] * s[le-i-1]
if (le & 1 == 1) c = c + 1
le = c
}
return s[0]
}
var primes = Int.primeSieve(1.3e6) // enough to generate first 100,000 primes
var prod = 1
System.print("The first ten primorial numbers are:")
for (i in 0..9) {
System.print("%(i): %(prod)")
prod = prod * primes[i]
}
System.print("\nThe following primorials have the lengths shown:")
// first multiply the first 100,000 primes together in pairs to reduce BigInt conversions needed
var primes2 = List.filled(50000, 0)
for (i in 0...50000) primes2[i] = primes[2*i] * primes[2*i+1]
for (i in [10, 100, 1000, 10000, 100000]) {
Fmt.print("$6d: $d", i, vecprod.call(primes2[0...i/2]).toString.count)
}</syntaxhighlight>
{{out}}
<pre>
The first ten primorial numbers are:
0: 1
1: 2
2: 6
3: 30
4: 210
5: 2310
6: 30030
7: 510510
8: 9699690
9: 223092870
The following primorials have the lengths shown:
10: 10
100: 220
1000: 3393
10000: 45337
100000: 563921
</pre>
===Embedded===
{{libheader|Wren-gmp}}
Far quicker, of course than the CLI version, completing in around 2.0 seconds.
<syntaxhighlight lang="wren">import "./math" for Int
import "./gmp" for Mpz
import "./fmt" for Fmt
var limit = 16 * 1e6 // more than enough to find first million primes
var primes = Int.primeSieve(limit-1)
primes.insert(0, 1)
System.print("The first ten primorial numbers are:")
var z = Mpz.new()
for (i in 0..9) System.print("%(i): %(z.primorial(primes[i]))")
System.print("\nThe following primorials have the lengths shown:")
for (i in [1e1, 1e2, 1e3, 1e4, 1e5, 1e6]) {
Fmt.print("$7d: $d", i, z.primorial(primes[i]).digitsInBase(10))
}</syntaxhighlight>
{{out}}
<pre>
The first ten primorial numbers are:
0: 1
1: 2
2: 6
3: 30
4: 210
5: 2310
6: 30030
7: 510510
8: 9699690
9: 223092870
The following primorials have the lengths shown:
10: 10
100: 220
1000: 3393
10000: 45337
100000: 563921
1000000: 6722809
</pre>
=={{header|zkl}}==
Using [[Extensible prime generator#zkl]] and the GMP big int library.
<
primes:=Utils.Generator(sieve).walk(0d10); // first 10 primes
foreach n in (10)
Line 2,463 ⟶ 3,176:
primes[0,n].pump(BN(1).mul)
:println("primorial(%,d)=%,d digits".fmt(n,_.numDigits));
}</
Big int multiplication is done in place to minimize garbage. Also, subsets of read only lists (which the list of primes is) are not copies (ie they are a small header that points into the original list).
|