From: LuisGLopez
Subject: Four "bagatelles": calculating PI and E randomly
Date: 
Message-ID: <1125196183.744079.324320@g47g2000cwa.googlegroups.com>
Hi!!!

I have a problem: when I should be reading the books and tutorials I
have, "ideas" (lets call them like that...) pop up in my memory and I
can't help trying to code them in lisp. Of course, then they become
*your* problem, because I can't help posting them here. But that's
*your* fault: after all, you spoiled me with your critics, comments,
suggestions and corrections to my newbie codes :-)

These are four little pieces: three for calculating the value of PI and
one for E, using the so called "Monte Carlo technics". In other terms:
by random :-) They aren't "the great thing", but I post them for two
reasons: a) I love the fact that one can calculate such fundamental
numbers by random, and b) There's no problem so small that a newbie can
 code it bad :-)

(defun imprimir (valor-calculado valor-real)
  "Prints the value calculated and its error"
  (format t "Valor calculado: ~,5f ~5t Error: ~,3f%~%"
	  valor-calculado (abs (* (/ (- valor-calculado valor-real)
valor-real) 100))))

(defun charco (&key (maximo 314159))
  "Calculates the value of PI via the probability of 'hitting' inside a
circle
inscribed in a square"
  (let ((valor-pi 0)
	(acierto  0))
    (dotimes (tiro maximo)
      (let ((x (- (random 2.0) 1))
	    (y (- (random 2.0) 1)))
	(when (<= (+ (* x x) (* y y)) 1)
	  (incf acierto))
	(setf valor-pi (* 4.0 (/ acierto (1+ tiro))))
	(imprimir valor-pi pi)))))

(defun Buffon (&key (maximo 314159))
  "Calculates the value of PI with a method proposed by Buffon"
  (let ((valor-pi 0)
	(sobre    0))
    (dotimes (tiro maximo)
      (let* ((y0    (random 2.0))
	     (theta (random (* 2 pi)))
	     (y1    (+ y0 (sin theta))))
	(when (or (<= y1 0) (>= y1 2))
	  (incf sobre))
	(when (plusp sobre)
	  (setf valor-pi (/ (+ 1.0 tiro) sobre))
	  (imprimir valor-pi pi))))))

(defun co-primosp (n m)
  "Tests is n and m are co-primes (they don't have factors in common)"
  (when (< m n)
    (rotatef n m))
  (when (zerop (rem m n))
    (return-from co-primosp nil))
  (do ((i 2 (1+ i)))
      ((> i (sqrt n)) t)
    (when (and (zerop (rem n i)) (zerop (rem m i)))
      (return-from co-primosp nil))))

(defun co-primos (&key (maximo 314159) (max-n 31415))
  "Calculates the value of PI on this: The probability that two random
positive integers are co-primes is 6/PI^2"
  (let ((valor-pi 0)
	(c        0))
    (dotimes (i maximo)
      (let ((n (1+ (random max-n)))
	    (m (1+ (random max-n))))
	(when (co-primosp n m)
	  (incf c)
	  (setf valor-pi (sqrt (/ (* 6 (1+ i)) c)))
	  (imprimir valor-pi pi))))))

(defun e (&key (maximo 271828))
  "Calculates the value of E on this: if you take random numbers
between 0 and 1 (X0...Xn), then (X0 * ... * Xn)^(1/n) converges to 1/e"
  (let ((valor-e  1)
	(e        (exp 1)))
    (dotimes (i maximo)
      (let ((x (random 1.0))
	    (j (1+ i)))
	(setf valor-e (/ (* (expt valor-e (/ i j)) (expt x (/ j)))))
	(imprimir valor-e e)))))