;;; -*- Mode:Common-Lisp; Base:10 -*-
;;;
;;; This small collection of code simulates the Monty Hall problem.
;;;
;;; As you very quickly realize, the best choice is to change.
;;;
;;; pz, 1 December 1989.


(defvar *prize-list* '())
(defvar *prize-position* 0)

(defun create-prize (n)
  (let ((position (random n))
	(prize-list (loop repeat n collecting '())))
    (setf (nth position prize-list) 'prize)
    (setq *prize-position* position)
    prize-list))


(defvar *selection* '())

(defun select-prize (n)
  (setq *selection* '())
  (loop while (or (null *selection*)
		  (and (numberp *selection*)
		       (< (1- n) *selection*)
		       (< *selection* 0))) do
	(format t "~&Which door do you select (0-~d) ? " n)
	(setq *selection* (read)))
  )


(defun monty (iters n)
  (loop repeat iters do
	(let ((position (loop for x = (random n)
			      while (or (not (null (nth x *prize-list*)))
					(= x *selection*))
			      finally (return x))))
	  (setf (nth position *prize-list*) 'x))))

(defun report ()
  (format t "~&")
  (format t "~&You chose ~d: ~a" *selection* (nth *selection* *prize-list*))
  (format t "~&Prize was ~d: ~a" *prize-position* (nth *prize-position* *prize-list*)))

(defun try ()
  (loop do
	(setq *prize-list* (create-prize 100))
	(select-prize 100)
	(monty 98 100)
;	(report)
	(if (eq 'prize (nth *selection* *prize-list*))
	    (format t "~&You Win (~d) !" *selection*)
	    (format t "~&You Lose (~d)." *selection*)
	    )
	)
  )