How to resolve the algorithm Primorial numbers step by step in the Clojure programming language
Published on 12 May 2024 09:40 PM
How to resolve the algorithm Primorial numbers step by step in the Clojure programming language
Table of Contents
Problem Statement
Primorial numbers are those formed by multiplying successive prime numbers.
The primorial number series is: To express this mathematically, primorialn is the product of the first n (successive) primes:
In some sense, generating primorial numbers is similar to factorials. As with factorials, primorial numbers get large quickly.
By length (above), it is meant the number of decimal digits in the numbers.
Let's start with the solution:
Step by Step solution about How to resolve the algorithm Primorial numbers step by step in the Clojure programming language
Source code in the clojure programming language
(ns example
(:gen-class))
; Generate Prime Numbers (Implementation from RosettaCode--link above)
(defn primes-hashmap
"Infinite sequence of primes using an incremental Sieve or Eratosthenes with a Hashmap"
[]
(letfn [(nxtoddprm [c q bsprms cmpsts]
(if (>= c q) ;; only ever equal
; Update cmpsts with primes up to sqrt c
(let [p2 (* (first bsprms) 2),
nbps (next bsprms),
nbp (first nbps)]
(recur (+ c 2) (* nbp nbp) nbps (assoc cmpsts (+ q p2) p2)))
(if (contains? cmpsts c)
; Not prime
(recur (+ c 2) q bsprms
(let [adv (cmpsts c), ncmps (dissoc cmpsts c)]
(assoc ncmps
(loop [try (+ c adv)] ;; ensure map entry is unique
(if (contains? ncmps try)
(recur (+ try adv))
try))
adv)))
; prime
(cons c (lazy-seq (nxtoddprm (+ c 2) q bsprms cmpsts))))))]
(do (def baseoddprms (cons 3 (lazy-seq (nxtoddprm 5 9 baseoddprms {}))))
(cons 2 (lazy-seq (nxtoddprm 3 9 baseoddprms {}))))))
;; Generate Primorial Numbers
(defn primorial [n]
" Function produces the nth primorial number"
(if (= n 0)
1 ; by definition
(reduce *' (take n (primes-hashmap))))) ; multiply first n primes (retrieving primes from lazy-seq which generates primes as needed)
;; Show Results
(let [start (System/nanoTime)
elapsed-secs (fn [] (/ (- (System/nanoTime) start) 1e9))] ; System start time
(doseq [i (concat (range 10) [1e2 1e3 1e4 1e5 1e6])
:let [p (primorial i)]] ; Generate ith primorial number
(if (< i 10)
(println (format "primorial ( %7d ) = %10d" i (biginteger p))) ; Output for first 10
(println (format "primorial ( %7d ) has %8d digits\tafter %.3f secs" ; Output with time since starting for remainder
(long i) (count (str p)) (elapsed-secs))))))
(ns example
(:gen-class))
(defn primes-hashmap
"Infinite sequence of primes using an incremental Sieve or Eratosthenes with a Hashmap"
[]
(letfn [(nxtoddprm [c q bsprms cmpsts]
(if (>= c q) ;; only ever equal
; Update cmpsts with primes up to sqrt c
(let [p2 (* (first bsprms) 2),
nbps (next bsprms),
nbp (first nbps)]
(recur (+ c 2) (* nbp nbp) nbps (assoc cmpsts (+ q p2) p2)))
(if (contains? cmpsts c)
; Not prime
(recur (+ c 2) q bsprms
(let [adv (cmpsts c), ncmps (dissoc cmpsts c)]
(assoc ncmps
(loop [try (+ c adv)] ;; ensure map entry is unique
(if (contains? ncmps try)
(recur (+ try adv))
try))
adv)))
; prime
(cons c (lazy-seq (nxtoddprm (+ c 2) q bsprms cmpsts))))))]
(do (def baseoddprms (cons 3 (lazy-seq (nxtoddprm 5 9 baseoddprms {}))))
(cons 2 (lazy-seq (nxtoddprm 3 9 baseoddprms {}))))))
;; Number of workers (threads) based upon number of available processors
(def workers
(+ 2 (.. Runtime getRuntime availableProcessors)))
;; Generate of primorial numbers (using multiple processors)
(defn primorial [n]
(if (= n 0)
1
;(reduce mul+ (pmap #(reduce *' %) (partition-all (max workers (long (/ n workers))) (take n (primes-hashmap)))))));(*' allows for big integer arithmetic as needed)
(->> ; Threads (i.e. pipes) sequence of expressions
(take n (primes-hashmap) ) ; generate primes
(partition-all (max workers (long (/ n workers)))) ; partition primes amongst workers
(pmap #(reduce *' %)) ; Multiply primes in each worker in parallel
(reduce *')))) ; multiply results of all workers together
;; Generate and Time Output
(let [start (System/nanoTime)
elapsed-secs (fn [] (/ (- (System/nanoTime) start) 1e9))] ; System start time
(doseq [i (concat (range 10) [1e2 1e3 1e4 1e5 1e6])
:let [p (primorial i)]] ; Generate ith primorial number
(if (< i 10)
(println (format "primorial ( %7d ) = %10d" i (biginteger p))) ; Output for first 10
(println (format "primorial ( %7d ) has %8d digits\tafter %.3f secs" ; Output with time since starting for remainder
(long i) (count (str p)) (elapsed-secs))))))
You may also check:How to resolve the algorithm Cyclotomic polynomial step by step in the Raku programming language
You may also check:How to resolve the algorithm Determine if a string is squeezable step by step in the jq programming language
You may also check:How to resolve the algorithm Colour pinstripe/Display step by step in the Kotlin programming language
You may also check:How to resolve the algorithm Happy numbers step by step in the Mercury programming language
You may also check:How to resolve the algorithm Magic squares of odd order step by step in the D programming language