MATT THOMPSON


Solving the Monty Hall problem in Clojure

At this week's Bristol Clojurians meetup we decided to give the Monty Hall problem a go as described in the cyber dojo problem set. Here's the solution I (eventually) came up with:

(defn choose [n change]
  (let [car (rand-int 3)
        world (assoc [":goat:" ":goat:" ":goat:"] car ":car:")
        choice (nth world n)
        others (remove #(= n %) (range 3))
        other-choice (if (= ":goat:" (nth world (first others)))
                       (last others) (first others))]
    (if-not change
      (if (= ":car:" choice) true false)
      (if (= ":car:" (nth world other-choice)) true false))))

(defn play [times]
  (let [stick (take times (repeatedly #(choose (rand-int 3) false)))
        change (take times (repeatedly #(choose (rand-int 3) true)))
        s-count (count (filter true? stick))
        c-count (count (filter true? change))]
    (hash-map :stick s-count :change c-count)))

(play 1000)

This turned out to be a lot trickier than it looks. I ended up spending way more time than necessary hacking emoji support into Emacs to display little car and goat icons. Important things first, right?


Home