fork download
  1. (ns example-one.core)
  2.  
  3. (def suits [:hearts :spades :clubs :diamonds])
  4. (def ranks [:2 :3 :4 :5 :6 :7 :8 :9 :10 :jack :queen :king :ace])
  5.  
  6. (def deck (vec (for [s suits, r ranks] [s r])))
  7.  
  8. (set! *warn-on-reflection* true)
  9.  
  10. (defprotocol ImmutableRandomNumberGenerator
  11. (next-long [self])
  12. (next-state [self]))
  13.  
  14. (defrecord LaggedFibonacciGenerator [
  15. ^long low-backref
  16. ^long high-backref
  17. ^long current-index
  18. ^longs state
  19. ]
  20. ImmutableRandomNumberGenerator
  21. (next-long ^long [self]
  22. (aget ^longs (:state self) (:current-index self)))
  23. (next-state ^LaggedFibonacciGenerator [self]
  24. (let [next-index (inc (:current-index self))
  25. low-backref (:low-backref self)
  26. high-backref (:high-backref self)
  27. low-index (mod (- next-index low-backref) high-backref)
  28. high-index (mod (- next-index high-backref) high-backref)
  29. old-state (:state self)
  30. low-value (aget old-state low-index)
  31. high-value (aget old-state high-index)
  32. new-state (aclone old-state)]
  33. (aset-long new-state next-index (unchecked-add ^long low-value ^long high-value))
  34. (LaggedFibonacciGenerator. low-backref high-backref next-index new-state))))
  35.  
  36. (defn- make-rng ^LaggedFibonacciGenerator []
  37. (let [seed-prng (java.security.SecureRandom.)
  38. init-state (long-array (repeatedly 55 #(.nextLong seed-prng)))]
  39. (LaggedFibonacciGenerator. 24 55 0 init-state)))
  40.  
  41. (defn shuffle-deck
  42. "Creates a shuffled deck of cards"
  43. []
  44. (loop [deck (transient deck), i (dec (count deck)), rng (make-rng)]
  45. (if (zero? i)
  46. (persistent! deck)
  47. (let [j (mod (next-long rng) i)]
  48. (recur (assoc! deck i (deck j) j (deck i))
  49. (dec i)
  50. (next-state rng))))))
  51.  
  52. (let [shuffled (shuffle-deck)]
  53. (println (count shuffled))
  54. (println shuffled))
Success #stdin #stdout #stderr 2.13s 335104KB
stdin
Standard input is empty
stdout
52
[[:diamonds :2] [:hearts :jack] [:spades :2] [:diamonds :7] [:hearts :2] [:spades :9] [:spades :8] [:spades :10] [:hearts :6] [:spades :5] [:clubs :king] [:clubs :5] [:diamonds :10] [:hearts :9] [:clubs :3] [:hearts :4] [:hearts :king] [:diamonds :queen] [:diamonds :jack] [:spades :jack] [:clubs :8] [:hearts :8] [:hearts :5] [:diamonds :4] [:spades :queen] [:clubs :10] [:clubs :jack] [:diamonds :5] [:spades :king] [:spades :6] [:diamonds :3] [:spades :7] [:spades :ace] [:diamonds :ace] [:clubs :ace] [:diamonds :6] [:hearts :7] [:diamonds :9] [:diamonds :king] [:hearts :ace] [:hearts :3] [:hearts :queen] [:clubs :9] [:diamonds :8] [:spades :3] [:clubs :4] [:clubs :6] [:spades :4] [:hearts :10] [:clubs :7] [:clubs :2] [:clubs :queen]]
stderr
Reflection warning, /home/HaHT0L/prog.clj:30:21 - call to static method aget on clojure.lang.RT can't be resolved (argument types: unknown, int).
Reflection warning, /home/HaHT0L/prog.clj:31:22 - call to static method aget on clojure.lang.RT can't be resolved (argument types: unknown, int).
Reflection warning, /home/HaHT0L/prog.clj:32:21 - call to static method aclone on clojure.lang.RT can't be resolved (argument types: unknown).