My earlier function 'primeFactorz' had a bug! returning the wrong results
for actual prime numbers :(
: (primeFactorz 17)
-> (3 5) # WRONG!
I have to be more careful with integer arithmetic. The corrected function
is:
(de primeFactorz (N)
(use Result
(recur (N)
(let (Root (inc (sqrt N)) X 2)
(when (gt0 (% N X))
(setq X 3)
(while
(and
(gt0 (% N X))
(<= (inc 'X 2) Root) ) ) )
(setq X (if (<= X Root) X N)
Result (cons X Result))
(unless (= X N) (recurse (/ N X))) ) )
Result ) )
: (primeFactorz 17)
-> (17)
/Lindsay
Addum: I have to say I am impressed with how straightforward it is to
parallelize code in picolisp!
I found my bug while playing with Joh-Tob's Check function and the
discussion on this thread really helped me to understand how to use 'later'.
: (bench (CheckPrimeFactors 10000 CheckP1))
1.287 sec
-> NIL
: (bench (CheckPrimeFactors 10000 CheckP2))
1.310 sec
-> NIL
: (bench (CheckPrimeFactors 10000 CheckP1=P2))
1.340 sec
-> NIL
: (bench (CheckPrimeFactors 32 CheckOdd))
(2 3 T 5 T 7 8 T)
(T 11 12 13 T T T 17)
(18 19 20 T T 23 T T)
(T 27 28 29 30 31 32 T)
0.006 sec
-> (T 27 28 29 30 31 32 T)
: (bench (CheckPrimeFactors 32 CheckEven))
(T T 4 T 6 T T 9)
(10 T T T 14 15 16 T)
(T T T 21 22 T 24 25)
(26 T T T T T T 33)
0.006 sec
-> (26 T T T T T T 33)
Definitions: Assuming 'prime-factors' 'primeFactorz':
: CheckP1
-> ((N) (ifn (= N (apply '* (prime-factors N))) N T))
: CheckP2
-> ((N) (ifn (= N (apply '* (primeFactorz N))) N T))
: CheckP1=P2
-> ((N) (ifn (= (sort (prime-factors N)) (sort (primeFactorz N))) N T))
: CheckOdd
-> ((N) (if (bit? 1 (length (prime-factors N))) N T))
: CheckEven
-> ((N) (ifn (bit? 1 (length (prime-factors N))) N T))
(de CheckPrimeFactors (Limit Checkit)
(let Lst (need 8)
(for (N 2 (>= Limit N))
(map
'((L)
(set L NIL)
(later L (Checkit N))
(inc 'N) )
Lst )
(wait NIL (full Lst))
(ifn (fully flg? Lst) (println Lst)) ) ) )