clojure-europe

ray 2025-12-13T09:14:09.968169Z

Good dog morning

๐Ÿถ 4
Ben Sless 2025-12-13T10:03:54.050929Z

I got that dog in me

๐Ÿ‘๐Ÿผ 1
pez 2025-12-13T10:15:03.267789Z

God morning. Anyone want a badly distributed random integer 1..100?

bb -e '(with-open [r (java.io.FileInputStream. "/dev/urandom")] (mod (int (+ (.read r) (.read r))) 100))'

๐ŸŽฒ 1
slipset 2025-12-14T14:27:02.250159Z

Why not use the facilities in test.whatever to generate random things? Of course, that would not be as interesting, but could get you to somewhere both faster and more correctly

teodorlu 2025-12-14T15:00:02.395799Z

My purpose for engaging with small snippets like this is to learn and to practice, not to solve it quickly. I'd welcome a test.whatever-solution too, I would probably learn more!

pez 2025-12-14T15:01:25.694359Z

I have no clue what test.whatever refers to ๐Ÿ˜ƒ

pez 2025-12-14T16:09:21.396999Z

If thereโ€™s any somewhere in this case, itโ€™s to a random number. (rand-int 100) seems like the most obvious competitor?

slipset 2025-12-14T16:11:28.682309Z

:)

teodorlu 2025-12-13T11:49:12.465079Z

exactly what I was hoping for this morning! ๐Ÿ™

teodorlu 2025-12-13T12:00:30.689559Z

I fail to explain if this is badly distributed!

(defn get-number []
  (with-open [r (java.io.FileInputStream. "/dev/urandom")]
    (mod (int (+ (.read r) (.read r))) 100)))

(into (sorted-map)
      (update-vals (group-by identity
                             (repeatedly 10000 get-number))
                   count))
looks quite even to me?

pez 2025-12-13T12:43:43.211689Z

Haha. Iโ€™ll need to try. Was thinking that 512 isnโ€™t 500, so expected some skew.

teodorlu 2025-12-13T13:05:48.480039Z

aaah. urandom only gives 0 to 255.

(defn urandom []
  (with-open [r (java.io.FileInputStream. "/dev/urandom")]
    (.read r)))

(def nums (repeatedly 10000 urandom))

(def stats (into (sorted-map) (frequencies nums)))

((juxt first last) stats)
;; => [[0 42] [255 44]]

teodorlu 2025-12-13T13:08:55.647539Z

Your summation also introduces some skew! The sum of the two urandom picks will have 255 as the most likely pick (255 combinations) and 510 and 0 to be the least likely (each has one possible pick). Then the mod 100 does (something) afterwards.

pez 2025-12-13T13:11:18.413049Z

I think filtering for < 200 may be the way to go.

teodorlu 2025-12-13T13:17:46.498209Z

to what aim, if I may ask?

teodorlu 2025-12-13T13:23:33.064619Z

Ah, I believe I understand what you mean. Sample, cut "outside" values, mod the inside. Makes sense! The + is still a source of skew, though. I did a different, roundabout, worse thing: just sample more small urandom numbers to make big Clojure numbers. Then it's not such a big deal to get the "bad" values that could have been filtered.

(defn urandom [n]
  (with-open [r (java.io.FileInputStream. "/dev/urandom")]
    (doall (repeatedly n #(.read r)))))

(defn normalize-map-values [m]
  (let [total (reduce + (vals m))
        average (/ total (count m))
        avg-inverse (double (/ 1 average))]
    (update-vals m (partial * avg-inverse))))

(->> (urandom 100000)
     (partition 2)
     (map (fn [[x y]] (+ (* 256 x) y)))
     (map #(mod % 100))
     frequencies
     (into (sorted-map))
     normalize-map-values
     (take 10))
;; => ([0 1.046]
;;     [65 1.048]
;;     [70 1.028]
;;     [62 0.926]
;;     [74 0.9520000000000001]
;;     [7 1.012]
;;     [59 0.99]
;;     [86 1.018]
;;     [20 0.9540000000000001]
;;     [72 0.964])

teodorlu 2025-12-13T13:23:45.030669Z

off to get some sun. Have a nice day, Peter!

pez 2025-12-13T14:45:15.023619Z

I was a tad unclear. Filtering was instead of adding. ๐Ÿ˜€

๐ŸŽฏ 1
teodorlu 2025-12-13T16:56:40.786789Z

then we are in complete agreement, my Swedish friend!

pez 2025-12-13T17:10:20.805559Z

(with-open [r (java.io.FileInputStream. "/dev/urandom")]
    (mod (->> #(.read r)
              repeatedly
              (filter #(< % 200))
              (take 1)
              doall
              first)
         100))

teodorlu 2025-12-13T19:37:19.510979Z

exactly!