Вопрос

just for fun I wrote a simulation of the "monty hall problem" in Python. Later I experimented with Lua and decided to write it again in Lua to see how it will look in comparison. It was a quite interesting experience even though the programs looked very similar (the Lua version was slightly shorter). Lately I started to exeriment with CL and wanted to do the same thing again. However when I run it, it does not behave as expected. For some reason the erratic player (who should get a 66% chance to win) has almost the same score as the naive player (with 50 % chance to win).

Can someone please give me a hint what is going wrong? This is not a homework or something like that, just my first try to write a larger program with CL. Besides hints regarding the problem described above I would also welcome suggestions on how to improve my style. I guess that it's still pretty Python-ish (it's more or less a direct translation).

(defun choose-one (l)
  "Ramdomly chooses one element of the given list"
  (nth (random (length l)) l))

(defun remove-one (l)
  "Randomly removes one element of the given list"
  (remove (choose-one l) l))

(defun naive-player (initial-choice possible-choices)
  "The naive player randomly picks one choice. Should have a 50% chance to win."
  initial-choice ;keep compiler happy
  (choose-one possible-choices))

(defun stubborn-player (initial-choice possible-choices)
  "The stubborn player sticks with his initial choice. Should have a 33% chance to win."
  possible-choices ;keep compiler happy
  initial-choice)

(defun erratic-player (initial-choice possible-choices)
  "The erratic player will always change his choice. Should have a 66% chance to win."
  (choose-one (remove initial-choice possible-choices)))

(defun host-offer (prize possible-choices)
  "The host reveals one wrong choice."
  (let ((remaining (remove prize possible-choices)))
    (remove (choose-one remaining) possible-choices)))

(defun one-game (playerfn choices)
  "Simulates a single game with the given player. Evaluates to T if the player won."
  (let ((prize (choose-one choices))
        (player-choice (choose-one choices)))
    (eq (funcall playerfn player-choice (host-offer prize choices)) prize)))


(defun multiple-games (num-games)
  "Simulates the given number of games with all players. Evaluates to a result list."
  (let ((choices '(door_a door_b door_c))
        (naive-score 0)
        (stubborn-score 0)
        (erratic-score 0))
    ;(progn
      (dotimes (i num-games)
        ;(progn
          (if (one-game #'naive-player choices)
              (incf naive-score))
          (if (one-game #'stubborn-player choices)
              (incf stubborn-score)) 
          (if (one-game #'erratic-player choices)
              (incf erratic-score)));)
      (list 
       (list 'naive-player naive-score) 
       (list 'stubborn-player stubborn-score)
       (list 'erratic-player erratic-score))));)

;; Run simulation and display results
(defparameter *num-games* 10000)
(format *standard-output* "--- Monty Hall ---~%")
(format *standard-output* "Simulating ~D games...~%" *num-games*)
(let ((result (multiple-games *num-games*)))
  (format *standard-output* "~{~{~A score: ~D~}~%~}" result))

Output (for example):

--- Monty Hall ---
Simulating 10000 games...
NAIVE-PLAYER score: 5014
STUBBORN-PLAYER score: 3333
ERRATIC-PLAYER score: 4968
Это было полезно?

Решение

The host offer function is wrong. In the Monty Hall problem as defined the host will never open the door the player has chosen, but your program doesn't take that into account. If that is fixed the program returns expected results.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top