Advertisement
triclops200

fast Project-euler 7

Aug 27th, 2013
235
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lisp 2.84 KB | None | 0 0
  1. ;; Using the lambert w-function left-branch in order to approximate a pi-¹(x)
  2. ;; function which allows a sieve to be used to generate a target number of primes.
  3. ;; Since the pi-¹(x) function overestimates, it can be guaranteed to always generate enough
  4. (defmacro while (test &body body)
  5.   `(do ()
  6.        ((not ,test))
  7.      ,@body))
  8.  
  9. (defmacro with-gensyms (syms &body body)
  10.   `(let ,(mapcar #'(lambda (x) `(,x (gensym))) syms)
  11.      ,@body))
  12.  
  13.  
  14. (defmacro collect-list (end-condition next-value var)
  15.   "Generates a list based on the next-value provided."
  16.   (with-gensyms (acc)
  17.     `(let ((,acc nil))
  18.        (while (not ,end-condition)
  19.          (push ,var ,acc)
  20.          (setq ,var ,next-value))
  21.        (nreverse (cons ,var ,acc)))))
  22.  
  23. (defun divisible (n x)
  24.   (zerop (rem n x)))
  25.  
  26. (defun take (n xs)
  27.   (labels ((rec (n xs acc)
  28.              (cond ((= n 0) (nreverse acc))
  29.                    ((null xs) nil)
  30.                    (t (rec (1- n) (cdr xs) (cons (car xs) acc))))))
  31.     (rec n xs nil)))
  32.  
  33. (defun range (x y &optional (step 1))
  34.   "Generates a range with an optional step parameter. It is non-inclusive."
  35.     (if (> (abs (- y (+ step x))) (abs (- y x)))
  36.           nil
  37.               (nbutlast (collect-list (= x y) (+ x step) x))))
  38. (defun square (x) (* x x))
  39. (defun primes<n (n)
  40.   (let ((upb (isqrt n)))
  41.     (labels ((rec (p xs acc)
  42.                (if (> p  upb)
  43.                    (nconc (nreverse acc) xs)
  44.                    (let ((nl (remove-if (lambda (x) (divisible x p)) xs)))
  45.                      (rec (car nl) nl (cons p acc))))))
  46.       (rec 2 (range 2 (1+ n)) nil))))
  47. (defun W-1 (z)
  48.   "SEE 'Numerical evaluation of the lambert w function and application
  49. to generation of generalized gaussian noise with exponent 1/2'"
  50.   (cond
  51.     ((and (< z -0.333) (>= z (/ -1 (exp 1))))
  52.      (let ((p (- (sqrt (* 2 (1+ (* (exp 1) z)))))))
  53.        (+
  54.         -1
  55.         p
  56.         (- (* 1/3 (expt p 2)))
  57.         (* 11/72 (expt p 3))
  58.         (- (* 43/540 (expt p 4)))
  59.         (* 769/17280 (expt p 5))
  60.         (- (* 221/8505 (expt p 6))))))
  61.     ((and (<= -0.333 z) (<= z -0.033))
  62.      (/
  63.       (+
  64.        -8.0960
  65.        (* 391.0025 z)
  66.        (- (* 47.4252 (square z)))
  67.        (- (* 4877.6330 (expt z 3)))
  68.        (- (* 5532.7760 (expt z 4))))
  69.       (+
  70.        1
  71.        (- (* 82.9423 z))
  72.        (* 433.8688 (square z))
  73.        (* 1515.3060 (expt z 3)))))
  74.     ((and (< -0.033 z) (< z 0))
  75.      (let ((l1 (log (- z))) (l2 (log (- (log (- z))))))
  76.        (+
  77.         l1
  78.         (- l2)
  79.         (/ l2 l1)
  80.         (/ (* (+ -2 l2) l2)
  81.            (* 2 (square l1)))
  82.         (/ (* l2 (+ 6 (* -9 l2) (* 2 (square l2))))
  83.            (* 6 (expt l1 3)))
  84.         (/ (* l2 (+ -12 (* 36 l2) (* -22 (square l2)) (* 3 (expt l2 3))))
  85.            (* 12 (expt l1 4)))
  86.         (/ (* l2 (+ 60 (* -300 l2) (* 350 (square l2)) (* -125 (expt l2 3)) (* 12 (expt l2 4))))
  87.            (* 60 (expt l1 5))))))))
  88.  
  89. (defun pi-1 (n)
  90.   (round (exp (- (w-1 (/ -1 n))))))
  91.  
  92. (defun n-primes (n)
  93.   (if (< n 15)
  94.       (take n '(2 3 5 7 11 13 17 19 23 29 31 37 41 47))
  95.       (let ((pl (primes<n (pi-1 n))))
  96.         (take n pl))))
  97.  
  98. (princ (car (last (n-primes 10001))))
  99. (princ "
  100. ")
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement