【问题标题】:Monty Hall and Lazy Sequences (?)Monty Hall 和惰性序列 (?)
【发布时间】:2019-03-05 18:51:56
【问题描述】:

我刚开始学习 Clojure,我正在尝试模拟 Monty Hall 问题:

(defn create-contest
  "Creates a monty hall doors contest"
  [n]
  (do (def door-with-car (rand-int n))
      (map
       (fn [i] (if (= i door-with-car) :car :closed))
       (range n)))) 

(defn create-doors
  "Create a collection of monty hall contests"
  [doors contests]
  (doall
   (map
     (fn [i] (create-contest i))
     (repeat contests doors))))

但每次我执行create-doors 函数时,所有带汽车的门最终都处于相同的位置:

broker.core> (create-doors 4 10)
((:car :closed :closed :closed)
 (:car :closed :closed :closed)
 (:car :closed :closed :closed)
 (:car :closed :closed :closed)
 (:car :closed :closed :closed)
 (:car :closed :closed :closed)
 (:car :closed :closed :closed)
 (:car :closed :closed :closed)
 (:car :closed :closed :closed)
 (:car :closed :closed :closed))
broker.core> (create-doors 4 10)
((:closed :car :closed :closed)
 (:closed :car :closed :closed)
 (:closed :car :closed :closed)
 (:closed :car :closed :closed)
 (:closed :car :closed :closed)
 (:closed :car :closed :closed)
 (:closed :car :closed :closed)
 (:closed :car :closed :closed)
 (:closed :car :closed :closed)
 (:closed :car :closed :closed))
broker.core> (create-doors 4 10)
((:closed :car :closed :closed)
 (:closed :car :closed :closed)
 (:closed :car :closed :closed)
 (:closed :car :closed :closed)
 (:closed :car :closed :closed)
 (:closed :car :closed :closed)
 (:closed :car :closed :closed)
 (:closed :car :closed :closed)
 (:closed :car :closed :closed)
 (:closed :car :closed :closed))

我做错了什么?

【问题讨论】:

    标签: clojure functional-programming statistics


    【解决方案1】:

    您非常接近,您应该在这里使用let 表单而不是def

    (defn create-contest
      "Creates a monty hall doors contest"
      [n]
      (let [door-with-car (rand-int n)] ;; let instead of def
        (map
          (fn [i] (if (= i door-with-car) :car :closed))
          (range n))))
    

    def 会将某个值绑定到当前命名空间中的 var,但您想在此函数的范围内绑定一个值,而这正是 let 的优势所在。其他解释见this Q&A

    (defn create-doors
      "Create a collection of monty hall contests"
      [doors contests]
      (map
        create-contest ;; no need to wrap create-contest in another function here
        (repeat contests doors)))
    

    您无需将create-contest 包装在另一个函数中以与map 一起使用——您只需将该函数作为值直接传递给mapdoall 只需要强制实现来自map 的惰性序列,因此您可能不需要/不希望在create-doors 中使用它。

    (create-doors 4 10)
    =>
    ((:closed :closed :car :closed)
     (:closed :closed :closed :car)
     (:closed :car :closed :closed)
     (:closed :closed :closed :car)
     (:closed :car :closed :closed)
     (:closed :car :closed :closed)
     (:closed :car :closed :closed)
     (:closed :closed :closed :car)
     (:closed :closed :car :closed)
     (:closed :closed :car :closed))
    

    【讨论】:

      【解决方案2】:

      @TaylorWood's solution 开始,您可以更简洁地表达您的两个功能,但我不确定简洁版本是否清晰。

      您的create-contestmap 的函数会测试每个数字i 以查看它是否是那个。最好直接更改那个。为此,我们需要一个向量,我认为您在模拟游戏时无论如何都会想要查找它:

       (defn create-contest [n]
        (assoc (vec (repeat n :closed)) (rand-int n) :car))
      

      您的create-doors 函数反复将相同的参数传递给它的map 函数。您可以在闭包上使用 repeatedly 来获得相同的效果:

      (defn create-doors [doors contests]
        (repeatedly contests (partial create-contest doors)))
      

      或者

      (defn create-doors [doors contests]
        (repeatedly contests #(create-contest doors)))
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-05-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-05-15
        相关资源
        最近更新 更多