How to generate repeatable random sequences with rand-int

前端 未结 7 1590
你的背包
你的背包 2021-02-08 18:22

I want to be able to generate repeatable numbers using rand in Clojure. (Specifically, I want results of calls to rand-nth or Incanter\'s sample

7条回答
  •  悲&欢浪女
    2021-02-08 18:33

    A clean way:

    (ns designed.ly.rand)
    
    (def ^:dynamic *rand* clojure.core/rand)
    
    (defn rand-1
     ([]
       (*rand* 1))
     ([n]
       (*rand* n)))
    
    (defmacro with-rand-seed
     "Sets seed for calls to random in body. Beware of lazy seqs!"
     [seed & body]
      `(let [g# (java.util.Random. ~seed)]
         (binding [*rand* #(* % (.nextFloat g#))]
          (with-redefs [rand rand-1]
            ~@body))))
    

    It redefines rand within the scope. Example:

    (with-rand-seed 9
      (rand 4)       ; => 2.9206461906433105
      (rand-int 10)) ; => 2
    

    BTW. Beware of lazy seqs: http://kotka.de/blog/2009/11/Taming_the_Bound_Seq.html (Apparently, this link redirects to https without a trusted certificate so here's a link to a version at Web Archive: https://web.archive.org/web/20120505012701/http://kotka.de/blog/2009/11/Taming_the_Bound_Seq.html).

提交回复
热议问题