Primorial numbers: Difference between revisions

m
m (→‎{{header|Phix}}: added syntax colouring the hard way)
 
(24 intermediate revisions by 13 users not shown)
Line 1:
{{task|Prime Numbers}}
Primorial numbers are those formed by multiplying successive prime numbers. <br>
 
Primorial numbers are those formed by multiplying successive prime numbers.
 
The primorial number series is:
 
The primorial number series is:
::* &nbsp; primorial(0) = &nbsp; &nbsp; &nbsp; &nbsp; 1 &nbsp; &nbsp; &nbsp; (by definition)
::* &nbsp; primorial(1) = &nbsp; &nbsp; &nbsp; &nbsp; 2 &nbsp; &nbsp; &nbsp; (2)
Line 15:
 
To express this mathematically, &nbsp; '''primorial<sub><big>''n''</big></sub>''' &nbsp; is &nbsp;
the product of the first &nbsp; <big>''n''</big> &nbsp; (successive) primes: <br>
 
<big><big><big>
: &nbsp; <math>primorial_n = \prod_{k=1}^n prime_k</math>
Line 28 ⟶ 29:
 
 
;Task:
'''task requirements:'''
 
* &nbsp; Show the first ten primorial numbers &nbsp; (0 ──► 9, &nbsp; inclusive).
* &nbsp; Show the length of primorial numbers whose index is: &nbsp; 10 &nbsp; 100 &nbsp; 1,000 &nbsp; 10,000 &nbsp; and &nbsp; 100,000.
Line 39:
 
;Related tasks:
'''links:'''
* &nbsp; [[Sequence of primorial primes]]
* &nbsp; [[Factorial]]
* &nbsp; [[Fortunate_numbers]]
 
See the MathWorld webpage: &nbsp; [http://mathworld.wolfram.com/Primorial.html primorial]
 
See the Wikipedia &nbsp; webpage: &nbsp; [[wp:Primorial|primorial]].
 
See the &nbsp; OEIS &nbsp; webpage: &nbsp; [[oeis:A002110|A002110]].
 
 
'''Related tasks:'''
*[[Factorial]]
*[[Sequence of primorial primes]]
 
;See also:
* &nbsp; the MathWorld webpage: &nbsp; [http://mathworld.wolfram.com/Primorial.html primorial]
* &nbsp; the Wikipedia &nbsp; webpage: &nbsp; [[wp:Primorial|primorial]].
* &nbsp; the &nbsp; OEIS &nbsp; webpage: &nbsp; [[oeis:A002110|A002110]].
<br><br>
 
Line 57 ⟶ 54:
{{trans|Python}}
 
<langsyntaxhighlight lang="11l">F get_primes(primes_count)
V limit = 17 * primes_count
V is_prime = [0B] * 2 [+] [1B] * (limit - 1)
Line 84 ⟶ 81:
L(e) 6
V n = 10 ^ e
print(‘primorial(#.) has #. digits’.format(n, String(primorial(n)).len))</langsyntaxhighlight>
 
{{out}}
Line 96 ⟶ 93:
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">
<lang c>
#include <inttypes.h>
#include <math.h>
Line 176 ⟶ 209:
return 0;
}
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 197 ⟶ 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}}
<lang cpp>#include <cstdint>
<syntaxhighlight lang="cpp">#include <gmpxx.h>
#include <primesieve.hpp>
 
#include <cstdint>
#include <iomanip>
#include <iostream>
#include <sstream>
#include <gmpxx.h>
#include "prime_sieve.hpp"
 
size_t digits(const mpz_class& n) { return n.get_str().length(); }
typedef mpz_class integer;
 
mpz_class primorial(unsigned int n) {
size_t count_digits(const integer& n) {
std::ostringstreammpz_class outp;
mpz_primorial_ui(p.get_mpz_t(), n);
out << n;
return out.str().length()p;
}
 
int main() {
constuint64_t size_t max_primeindex = 200000000;
primesieve::iterator pi;
const size_t max_index = 1000000;
std::cout << "First 10 primorial numbers:\n";
prime_sieve sieve(max_prime);
for (mpz_class pn = 1; index < 10; ++index) {
integer primorial = 1;
unsigned int prime = pi.next_prime();
for (size_t p = 0, index = 0, power = 10; p < max_prime && index <= max_index; ++p) {
std::cout << index << ": " << pn << '\n';
if (!sieve.is_prime(p))
pn *= continueprime;
}
if (index < 10)
std::cout << "primorial("\nLength <<of indexprimorial <<number ")whose =index " << primorial << 'is:\n'";
for (uint64_t power = else10; if (indexpower =<= 1000000; power *= 10) {
uint64_t prime = primesieve::nth_prime(power);
std::cout << "primorial(" << index << ") has length "
std::cout << count_digitsstd::setw(primorial7) << '\n';power << ": "
power *= 10 << digits(primorial(prime)) << '\n';
}
++index;
primorial *= p;
}
return 0;
}</langsyntaxhighlight>
 
Contents of prime_sieve.hpp:
<lang cpp>#ifndef PRIME_SIEVE_HPP
#define PRIME_SIEVE_HPP
 
#include <algorithm>
#include <vector>
 
/**
* A simple implementation of the Sieve of Eratosthenes.
* See https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes.
*/
class prime_sieve {
public:
explicit prime_sieve(size_t);
bool is_prime(size_t) const;
private:
std::vector<bool> is_prime_;
};
 
/**
* Constructs a sieve with the given limit.
*
* @param limit the maximum integer that can be tested for primality
*/
inline prime_sieve::prime_sieve(size_t limit) {
limit = std::max(size_t(3), limit);
is_prime_.resize(limit/2, true);
for (size_t p = 3; p * p <= limit; p += 2) {
if (is_prime_[p/2 - 1]) {
size_t inc = 2 * p;
for (size_t q = p * p; q <= limit; q += inc)
is_prime_[q/2 - 1] = false;
}
}
}
 
/**
* Returns true if the given integer is a prime number. The integer
* must be less than or equal to the limit passed to the constructor.
*
* @param n an integer less than or equal to the limit passed to the
* constructor
* @return true if the integer is prime
*/
inline bool prime_sieve::is_prime(size_t n) const {
if (n == 2)
return true;
if (n < 2 || n % 2 == 0)
return false;
return is_prime_.at(n/2 - 1);
}
 
#endif</lang>
 
{{out}}
<pre>
First 10 primorial numbers:
primorial(0) = 1
0: 1
primorial(1) = 2
1: 2
primorial(2) = 6
2: 6
primorial(3) = 30
3: 30
primorial(4) = 210
4: 210
primorial(5) = 2310
5: 2310
primorial(6) = 30030
6: 30030
primorial(7) = 510510
7: 510510
primorial(8) = 9699690
8: 9699690
primorial(9) = 223092870
9: 223092870
primorial(10) has length 10
 
primorial(100) has length 220
Length of primorial(1000) hasnumber whose lengthindex 3393is:
10: 10
primorial(10000) has length 45337
100: 220
primorial(100000) has length 563921
1000: 3393
primorial(1000000) has length 6722809
10000: 45337
100000: 563921
1000000: 6722809
</pre>
 
Line 311 ⟶ 351:
===Single Process===
Using HashMap prime number generation from https://rosettacode.org/wiki/Sieve_of_Eratosthenes#Unbounded_Versions
<langsyntaxhighlight lang="lisp">(ns example
(:gen-class))
Line 357 ⟶ 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>
</lang>
{{Output}}
<pre>
Line 380 ⟶ 420:
===Parallel Process===
Using HashMap prime number generation from https://rosettacode.org/wiki/Sieve_of_Eratosthenes#Unbounded_Versions
<langsyntaxhighlight lang="lisp">(ns example
(:gen-class))
(defn primes-hashmap
Line 432 ⟶ 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>
</lang>
{{Output}}
<pre>
Line 452 ⟶ 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}}==
<langsyntaxhighlight lang="lisp">
(defun primorial-number-length (n w)
(values (primorial-number n) (primorial-length w)))
Line 469 ⟶ 620:
(defun primep (n)
(loop for a from 2 to (isqrt n) never (zerop (mod n a))))
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 479 ⟶ 630:
=={{header|D}}==
{{trans|Java}}
<syntaxhighlight lang="d">
<lang d>
import std.stdio;
import std.format;
Line 538 ⟶ 689:
}
 
</syntaxhighlight>
</lang>
 
{{out}}
Line 565 ⟶ 716:
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">
<lang Elixir>
defmodule SieveofEratosthenes do
def init(lim) do
Line 579 ⟶ 730:
end
end
</syntaxhighlight>
</lang>
 
<syntaxhighlight lang="elixir">
<lang Elixir>
defmodule Primorial do
def first(n,primes) do
Line 617 ⟶ 768:
defp str_fr(pri,i), do: IO.puts("Primorial #{i} has length: #{pri}")
end
</syntaxhighlight>
</lang>
 
<syntaxhighlight lang="elixir">
<lang Elixir>
Primorial.first(10,SieveofEratosthenes.init(50))
Primorial.numbers([10,100,1_000,10_000,100_000],SieveofEratosthenes.init(1_300_000))
</syntaxhighlight>
</lang>
 
{{out}}
Line 642 ⟶ 793:
 
=={{header|F_Sharp|F#}}==
This task uses [http://www.rosettacode.org/wiki/Extensible_prime_generator#The_functionThe_functions Extensible Prime Generator (F#)]
<syntaxhighlight lang="fsharp">
===The function to generate a sequence of Primorial Numbers===
// Primorial Numbers. Nigel Galloway: August 3rd., 2021
<lang fsharp>
primes32()|>Seq.scan((*)) 1|>Seq.take 10|>Seq.iter(printf "%d "); printfn "\n"
// Primorial Numbers. Nigel Galloway: November 28th., 2017
[10;100;1000;10000;100000]|>List.iter(fun n->printfn "%d" ((int)(System.Numerics.BigInteger.Log10 (Seq.item n (primesI()|>Seq.scan((*)) 1I)))+1))
let primorialNumbers = seq{
</syntaxhighlight>
let N = let N = ref 1I
(fun (n:int) -> N := !N*(bigint n); !N)
yield 1I; yield! Seq.map N primes}
</lang>
===The Task===
<lang fsharp>
primorialNumbers |> Seq.take 10 |> Seq.iter(fun n->printfn "%A" n)
</lang>
{{out}}
<pre>
1
2
6
30
210
2310
30030
510510
9699690
223092870
</pre>
<lang fsharp>
[10;100;1000;10000;100000]|>List.iter(fun n->printfn "%d" ((int)(System.Numerics.BigInteger.Log10 (Seq.item n primorialNumbers))+1))
</lang>
{{out}}
<pre>
1 2 6 30 210 2310 30030 510510 9699690 223092870
 
10
220
Line 681 ⟶ 811:
 
=={{header|Factor}}==
<syntaxhighlight lang="text">USING: formatting kernel literals math math.functions
math.primes sequences ;
IN: rosetta-code.primorial-numbers
Line 704 ⟶ 834:
: main ( -- ) part1 part2 ;
 
MAIN: main</langsyntaxhighlight>
{{out}}
<pre>
Line 744 ⟶ 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 <langsyntaxhighlight Fortranlang="fortran"> B.DIGIT(I) = MOD(D,BIGBASE)
C = D/BIGBASE</langsyntaxhighlight> and avoid performing two divisions. When an integer division is performed, the quotient appears in one register and the remainder in another and when writing in assembler with access to such registers there is no need for the two divisions as is forced by the use of high-level languages.
 
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<langsyntaxhighlight Fortranlang="fortran"> INTEGER*4 D !A 32-bit product.
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.</langsyntaxhighlight>
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 761 ⟶ 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">
<lang Fortran>
MODULE BIGNUMBERS !Limited services: decimal integers, no negative numbers.
INTEGER BIGORDER !A limit attempt at generality.
Line 956 ⟶ 1,086:
IF (MARK.LE.LASTP) GO TO 112 !Are we there yet?
END !So much for that.
</syntaxhighlight>
</lang>
 
===Results===
Line 999 ⟶ 1,129:
 
=={{header|FreeBASIC}}==
<langsyntaxhighlight lang="freebasic">' version 22-09-2015
' compile with: fbc -s console
 
Line 1,095 ⟶ 1,225:
Print : Print "hit any key to end program"
Sleep
End</langsyntaxhighlight>
{{out}}
<pre> primorial(0) = 1
Line 1,116 ⟶ 1,246:
=={{header|Frink}}==
===Simple version===
<langsyntaxhighlight lang="frink">primorial[n] := product[first[primes[], n]]
 
for n = 0 to 9
Line 1,123 ⟶ 1,253:
for n = [10, 100, 1000, 10000, 100000, million]
println["Length of primorial $n is " + length[toString[primorial[n]]] + " decimal digits."]
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 1,147 ⟶ 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?)
 
<langsyntaxhighlight lang="frink">/** Calculate the primes and set up for the recursive call. */
primorialSplitting[n] :=
{
Line 1,178 ⟶ 1,308:
for n = [10, 100, 1000, 10000, 100000, million]
println["Length of primorial $n is " + length[toString[primorialSplitting[n]]] + " decimal digits."]
</syntaxhighlight>
</lang>
 
=={{header|Go}}==
Line 1,185 ⟶ 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.
<langsyntaxhighlight lang="go">package main
 
import (
Line 1,214 ⟶ 1,344:
fmt.Printf("\t(after %v)\n", time.Since(start))
}
}</langsyntaxhighlight>
{{out}}
<pre>
Line 1,244 ⟶ 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.
<langsyntaxhighlight lang="go">package main
 
import (
Line 1,291 ⟶ 1,421:
}
fmt.Printf("\nTook %s\n", time.Since(start))
}</langsyntaxhighlight>
 
{{out}}
Line 1,319 ⟶ 1,449:
=={{header|Haskell}}==
 
<syntaxhighlight lang="haskell">
<lang Haskell>
import Control.Arrow ((&&&))
import Data.List (scanl1, foldl1')
Line 1,352 ⟶ 1,482:
calculate primorialTens
 
</syntaxhighlight>
</lang>
 
{{out}}
Line 1,370 ⟶ 1,500:
Implementation:
 
<langsyntaxhighlight Jlang="j">primorial=:*/@:p:@i."0</langsyntaxhighlight>
 
Task examples:
 
<langsyntaxhighlight Jlang="j"> primorial i. 10 NB. first 10 primorial numbers
1 2 6 30 210 2310 30030 510510 9699690 223092870
#":primorial 10x NB. lengths (of decimal representations)...
Line 1,387 ⟶ 1,517:
563921
#":primorial 1000000x
6722809</langsyntaxhighlight>
 
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}}==
<langsyntaxhighlight lang="java">import java.math.BigInteger;
 
public class PrimorialNumbers {
Line 1,436 ⟶ 1,566:
return composite;
}
}</langsyntaxhighlight>
 
<pre>primorial(0): 1
Line 1,453 ⟶ 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}}
<langsyntaxhighlight lang="julia">
using Primes
 
Line 1,471 ⟶ 1,799:
println("primorial($n) has length $plen digits in base 10.")
end
</syntaxhighlight>
</lang>
{{output}}
<pre>The first ten primorials are: BigInt[2, 6, 30, 210, 2310, 30030, 510510, 9699690, 223092870, 6469693230]
Line 1,483 ⟶ 1,811:
 
=={{header|Kotlin}}==
<langsyntaxhighlight lang="scala">// version 1.0.6
 
import java.math.BigInteger
Line 1,528 ⟶ 1,856:
p += 2
}
}</langsyntaxhighlight>
 
{{out}}
Line 1,553 ⟶ 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).
<langsyntaxhighlight Lingolang="lingo">-- libs
sieve = script("math.primes").new()
bigint = script("bigint").new()
Line 1,574 ⟶ 1,902:
pow10 = pow10 * 10
end if
end repeat</langsyntaxhighlight>
{{out}}
<pre>
Line 1,595 ⟶ 1,923:
 
=={{header|Maple}}==
<syntaxhighlight lang="maple">
<lang Maple>
with(NumberTheory):
 
Line 1,626 ⟶ 1,954:
end;
 
</syntaxhighlight>
</lang>
{{out}}<pre>
"The first 10 primorial numbers"
Line 1,662 ⟶ 1,990:
</pre>
 
=={{header|Mathematica}}/{{header|Wolfram Language}}==
The first 10 primorial numbers are:
<langsyntaxhighlight Mathematicalang="mathematica">FoldList[Times, 1, Prime @ Range @ 9]</langsyntaxhighlight>
{{out}}
<pre>
Line 1,671 ⟶ 1,999:
From the first million primes:
 
<langsyntaxhighlight Mathematicalang="mathematica">primes = Prime @ Range[10^6]; </langsyntaxhighlight>
 
define the primorial:
 
<langsyntaxhighlight Mathematicalang="mathematica">primorial[n_]:= Times @@ primes[[;;n]]</langsyntaxhighlight>
 
The lengths of selected primorial numbers are:
<langsyntaxhighlight Mathematicalang="mathematica">Grid@Table[{"primorial(10^" <> ToString[n] <> ") has ",
{timing,answer}=AbsoluteTiming[IntegerLength@primorial[10^n]];answer,
" digits in "<>ToString@timing<>" seconds"}, {n,6}]</langsyntaxhighlight>
{{out}}
<pre>
Line 1,692 ⟶ 2,020:
 
=={{header|Nickle}}==
<langsyntaxhighlight lang="c">library "prime_sieve.5c"
 
# For 1 million primes
Line 1,723 ⟶ 2,051:
int digits = floor(Math::log10(pn)) + 1;
printf("primorial(%d) has %d digits, in %dms\n", p, digits, millis() - start);
}</langsyntaxhighlight>
 
{{out}}
Line 1,751 ⟶ 2,079:
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.
 
<langsyntaxhighlight Nimlang="nim">import times
 
let t0 = cpuTime()
Line 1,811 ⟶ 2,139:
 
echo ""
echo &"Total time: {cpuTime() - t0:.2f} s"</langsyntaxhighlight>
 
{{out}}
Line 1,838 ⟶ 2,166:
 
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.
<langsyntaxhighlight Nimlang="nim">import std/monotimes
 
let t0 = getMonoTime()
Line 1,906 ⟶ 2,234:
 
echo ""
echo &"Total time: {(getMonoTime() - t0)}"</langsyntaxhighlight>
 
{{out}}
Line 1,928 ⟶ 2,256:
 
=={{header|PARI/GP}}==
<langsyntaxhighlight lang="parigp">nthprimorial(n)=prod(i=1,n,prime(i));
vector(10,i,nthprimorial(i-1))
vector(5,n,#Str(nthprimorial(10^n)))
#Str(nthprimorial(10^6))</langsyntaxhighlight>
{{out}}
<pre>%1 = [1, 2, 6, 30, 210, 2310, 30030, 510510, 9699690, 223092870]
Line 1,939 ⟶ 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.
<langsyntaxhighlight lang="parigp">nthprimorial(n)=vecprod(primes(n));
vector(6,n,#Str(nthprimorial(10^n)))</langsyntaxhighlight>
{{out}}
<pre>[10, 220, 3393, 45337, 563921, 6722809]
Line 1,950 ⟶ 2,278:
mp_primorial {-Primorial of n; a = n# = product of primes <= n.}
so i sieve to get the right n
<langsyntaxhighlight lang="pascal">{$H+}
uses
sysutils,mp_types,mp_base,mp_prime,mp_numth;
Line 1,981 ⟶ 2,309:
Writeln((t1-t0)*86400.0:10:3,' s');
end.
</syntaxhighlight>
</lang>
{{Out}}
<pre>MaxPrime 29 10 digits
Line 2,002 ⟶ 2,330:
Obviously GMP will do it by far better.
 
<langsyntaxhighlight lang="pascal">program Primorial;
{$IFDEF FPC} {$MODE DELPHI} {$ENDIF}
uses
Line 2,111 ⟶ 2,439:
i := i*10;
until i> 100000;
end.</langsyntaxhighlight>
{{out}}
<pre>Primorial (0->9) 1,2,6,30,210,2310,30030,510510,9699690,223092870
Line 2,138 ⟶ 2,466:
{{libheader|ntheory}}
 
<langsyntaxhighlight lang="perl">use ntheory qw(pn_primorial);
 
say "First ten primorials: ", join ", ", map { pn_primorial($_) } 0..9;
 
say "primorial(10^$_) has ".(length pn_primorial(10**$_))." digits" for 1..6;</langsyntaxhighlight>
 
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 2,158 ⟶ 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:
<langsyntaxhighlight lang="perl">use ntheory ":all";
say length( vecprod( @{primes( nth_prime(10**6) )} ) );</langsyntaxhighlight>
 
returning the same result in only slightly more time. Both examples take under 4 seconds.
Line 2,167 ⟶ 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.
<!--<langsyntaxhighlight Phixlang="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>
Line 2,201 ⟶ 2,529:
<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>
<!--</langsyntaxhighlight>-->
{{out}}
<pre>
Line 2,226 ⟶ 2,554:
=={{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">
<lang PicoLisp>
(de prime? (N Lst)
(let S (sqrt N)
Line 2,254 ⟶ 2,582:
[prinl (length (primorial (** 10 4)]
#The last one takes a very long time to compute.
[prinl (length (primorial (** 10 5)]</langsyntaxhighlight>
 
{{out}}
Line 2,279 ⟶ 2,607:
Uses the pure python library [https://pypi.python.org/pypi/pyprimes/0.1.1a pyprimes ].
 
<langsyntaxhighlight lang="python">from pyprimes import nprimes
from functools import reduce
 
Line 2,292 ⟶ 2,620:
for e in range(7):
n = 10**e
print('primorial(%i) has %i digits' % (n, len(str(primorial(n)))))</langsyntaxhighlight>
 
{{out}}
Line 2,303 ⟶ 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.
<langsyntaxhighlight Racketlang="racket">#lang racket
 
(require (except-in math/number-theory nth-prime))
Line 2,342 ⟶ 2,705:
(printf "Primorial(10^~a) has ~a digits.\n"
i
(num-length (primorial (expt 10 i)))))</langsyntaxhighlight>
{{out}}
<pre>(1 2 6 30 210 2310 30030 510510 9699690 223092870)
Line 2,356 ⟶ 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" perl6line>use Math::Primesieve;
 
my $sieve = Math::Primesieve.new;
Line 2,364 ⟶ 2,727:
 
say "First ten primorials: {(primorial $_ for ^10)}";
say "primorial(10^$_) has {primorial(10**$_).chars} digits" for 1..5;</langsyntaxhighlight>
{{out}}
<pre>
Line 2,376 ⟶ 2,739:
===Imported library===
For a real speed boost, load the Perl 5 ntheory library.
{{libheader|ntheory}}
<lang perl6>use Lingua::EN::Numbers;
<syntaxhighlight lang="raku" line>use Lingua::EN::Numbers;
use ntheory:from<Perl5> <pn_primorial>;
 
Line 2,386 ⟶ 2,750:
comma(pn_primorial(10**$_).Str.chars),
"Elapsed seconds: {(now - $now).round: .001}";
}</langsyntaxhighlight>
<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,398 ⟶ 2,762:
 
=={{header|REXX}}==
<langsyntaxhighlight lang="rexx">/*REXX program computes some primorial numbers for low numbers, and for various 10^n.*/
parse arg N H . /*get optional arguments: N, L, H */
if N=='' | N==',' then N= 10 /*Not specified? Then use the default.*/
Line 2,440 ⟶ 2,804:
end /*k*/
#= # + 1; @.#= j; s.#= j * j; return j /*next prime; return*/
end /*j*/</langsyntaxhighlight>
{{out|output|text=&nbsp; when using the default inputs:}}
<pre>
Line 2,462 ⟶ 2,826:
 
=={{header|Ring}}==
<langsyntaxhighlight lang="ring">
# Project: Primorial numbers
load "bignumber.ring"
Line 2,518 ⟶ 2,882:
see "primorial(" + string(pr-1) + ") " + "has " + len(pro) + " digits"+ nl
ok
</syntaxhighlight>
</lang>
<pre>
working...
Line 2,542 ⟶ 2,906:
=={{header|Ruby}}==
 
<langsyntaxhighlight lang="ruby">require 'prime'
def primorial_number(n)
Line 2,553 ⟶ 2,917:
(1..5).each do |n|
puts "primorial(10**#{n}) has #{primorial_number(10**n).to_s.size} digits"
end</langsyntaxhighlight>
 
{{out}}
Line 2,565 ⟶ 2,929:
 
=={{header|Rust}}==
<syntaxhighlight lang="rust">
<lang Rust>
extern crate primal;
extern crate rayon;
Line 2,607 ⟶ 2,971:
println!("Digits of primorial 1_000_000 : {}",result);
}
</syntaxhighlight>
</lang>
using Intel(R) Core(TM) i7-5500U CPU @ 2.40GHz
{{out}}
Line 2,636 ⟶ 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.
 
<langsyntaxhighlight lang="scala">import spire.math.SafeLong
import spire.implicits._
 
Line 2,654 ⟶ 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(_))
}</langsyntaxhighlight>
 
{{out}}
Line 2,679 ⟶ 3,043:
=={{header|Sidef}}==
{{trans|Perl}}
<langsyntaxhighlight lang="ruby">say (
'First ten primorials: ',
{|i| pn_primorial(i) }.map(^10).join(', ')
Line 2,686 ⟶ 3,050:
{ |i|
say ("primorial(10^#{i}) has " + pn_primorial(10**i).len + ' digits')
} << 1..6</langsyntaxhighlight>
{{out}}
<pre>
Line 2,697 ⟶ 3,061:
primorial(10^6) has 6722809 digits
</pre>
=={{header|Smalltalk}}==
<lang Smalltalk></lang>
 
=={{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.
<langsyntaxhighlight ecmascriptlang="wren">import "./big" for BigInt
import "./math" for Int
import "./fmt" for Fmt
 
var vecprod = Fn.new { |primes|
Line 2,737 ⟶ 3,100:
for (i in [10, 100, 1000, 10000, 100000]) {
Fmt.print("$6d: $d", i, vecprod.call(primes2[0...i/2]).toString.count)
}</langsyntaxhighlight>
 
{{out}}
Line 2,759 ⟶ 3,122:
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.
<langsyntaxhighlight lang="zkl">sieve:=Import("sieve.zkl",False,False,False).postponed_sieve;
primes:=Utils.Generator(sieve).walk(0d10); // first 10 primes
foreach n in (10)
Line 2,773 ⟶ 3,176:
primes[0,n].pump(BN(1).mul)
:println("primorial(%,d)=%,d digits".fmt(n,_.numDigits));
}</langsyntaxhighlight>
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).
 
3,026

edits