;;; Google Billboard Advertising


;; some last digits are wrong
(defun calc-e (n)
  (do* ((one (expt 10 n))
	(y one)
	(d one)
	(i 1 (1+ i)))
    ((zerop d) y)
    (setf d (floor (* d (floor one i)) one))
    (setf y (+ y d))))


#+CMUCL
(defun primep (n)
  (system:primep n))


#-CMUCL
;; Steven E. Harris <seh@panix.com>
;; and Paul Foley
(defun primep (n)
  (loop for i from 2 to (isqrt n)
        never (zerop (mod n i))))


(defun run-1 (n)
  (do* ((str (write-to-string (calc-e n)))
        (k (- (length str) 9))
        (j 0 (1+ j)))
     ((= j k) nil)
     (let ((n (read-from-string (subseq str j (+ j 10)))))
       (when (and (> n 1000000000) (primep n))
         (format t "~&~4D: ~D" j n)))))


(defun run-2 (n)
  (do* ((str (write-to-string (calc-e n)))
        (k (- (length str) 9))
        (j 0 (1+ j)))
     ((= j k) nil)
     (let ((n (read-from-string (subseq str j (+ j 10)))))
       (when (or (= n 7182818284)
                 (= n 8182845904)
		 (= n 8747135266)
		 (= n 7427466391))
         (format t "~&~4D: ~D" j n)))))


(defun cross-sum (n)
  (cond
    ((< n 10) n)
    (t (multiple-value-bind (q r) (floor n 10)
        (+ (cross-sum q) r)))))


(defun run-3 (n)
  (do* ((str (write-to-string (calc-e n)))
        (k (- (length str) 9))
        (j 0 (1+ j)))
     ((= j k) nil)
     (let ((n (read-from-string (subseq str j (+ j 10)))))
       (when (= (cross-sum n) 49)
         (format t "~&~4D: ~D" j n)))))



;(load "google-ad.lisp")
;(compile-file "google-ad.lisp" :load t)
;(calc-e 12)
;(run-1 200) ==> 7427466391, in number e at position 99
;(run-2 200) ==> in number e at positions 1,5,23,99
;(run-3 200) ==> 5966290435, in number e at position 127

