Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>I suggest doing some problems at <a href="http://www.4clojure.com/" rel="noreferrer">http://www.4clojure.com/</a> while learning Clojure. You can "follow" the top users and see how they solve problems.</p> <p>Here's a solution. It is again not the most efficient as I was aiming to keep it simple and not use more advanced ideas and constructs that you'll learn later.</p> <pre><code>user=&gt; (def colors {:white 1 :red 10 :blue 20 :green 1 :yellow 1}) #'user/colors user=&gt; (keys colors) (:white :red :blue :green :yellow) user=&gt; (vals colors) (1 10 20 1 1) </code></pre> <p>To turning the weights into intervals, we just do a cumulative sum:</p> <pre><code>user=&gt; (reductions #(+ % %2) (vals colors)) (1 11 31 32 33) </code></pre> <p>Finding the random interval: </p> <pre><code>user=&gt; (rand-int (last *1)) 13 user=&gt; (count (take-while #(&lt;= % *1 ) *2 )) 2 </code></pre> <p>Note <code>*1</code> in the REPL refers to the most recent value printed, <code>*2</code> to the next most recent, etc. So we asked for a random integer between 0 (inclusive) and 33 (exclusive). These 33 possible choices correspond to the total of the weights. Next we counted the number of intervals we would need to pass through to find that number. Here the random number was 13.</p> <pre><code>(1 11 31 32 33) ^ 13 belongs here, 2 numbers in </code></pre> <p>We find our random number 2 in. Note that in order to land here we had to have at least 11 but less than 31, so 20 possibilities, which is precisely the weight of...</p> <pre><code>user=&gt; (nth (keys colors) *1) :blue </code></pre> <p>So, putting this all together into a function:</p> <pre><code>(defn weighted-rand-choice [m] (let [w (reductions #(+ % %2) (vals m)) r (rand-int (last w))] (nth (keys m) (count (take-while #( &lt;= % r ) w))))) </code></pre> <p>Let's test it:</p> <pre><code>user=&gt; (-&gt;&gt; #(weighted-rand-choice colors) repeatedly (take 10000) frequencies) {:red 3008, :blue 6131, :white 280, :yellow 282, :green 299} </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload