Search code examples
algorithmclojureround-robin

Round robin distribution in Clojure


I was wondering if anyone has any resources regarding round robin distribution in Clojure?

I have a function which splits the passed data into separate maps, like so:

(defn round-robin
  "Divides the dataset into distinct maps using 
round robin distribution"
  [data sets split]

  (partition split data)
 )

My problem is that I'm not certain how to distribute these maps into the amount of "sets" defined. I'm thinking I could create the maps before hand with something like this:

(defn create-map-set
  "Creates a set of (count) maps"
  [count set]
  (if(= count 0) set (recur (- count 1) (conj set 
'())))
 )

but as I can't reference indexes it becomes harder to merge data with the specific map.

Here's what I'm expecting:

Input: ((2 5) (3 2) (7 3) (1 4) (3 7) (4 2))
Output: ((2 5 1 4) (3 2 3 7) (7 3 4 2))

I'm essentially going 1 2 3, 1 2 3 when adding data to maps.


Solution

  • I will indicate how I go about such a problem. Clojure is quite conducive to this sort of experimentation. (leetwinski effectively gave this answer in his comment.)

    Start off with the data.

    '((2 5) (3 2) (7 3) (1 4) (3 7) (4 2))
    

    Drop that inside a thread macro

    (->> '((2 5) (3 2) (7 3) (1 4) (3 7) (4 2))) ===> ((2 5) (3 2) (7 3) (1 4) (3 7) (4 2))
    

    Partition halfway

    (->> '((2 5) (3 2) (7 3) (1 4) (3 7) (4 2))
         (partition 3)) ===> (((2 5) (3 2) (7 3)) ((1 4) (3 7) (4 2)))
    

    At this point, we get two elements (always). If we can pass these into map, and then concatenate each two elements, we are done. So,

    (->> '((2 5) (3 2) (7 3) (1 4) (3 7) (4 2))
         (partition 3)
         (apply map concat)) ===> ((2 5 1 4) (3 2 3 7) (7 3 4 2))
    

    Now, remove the hard-coded stuff:

    (defn round-robin [s]
      (let [half-len (quot (count s) 2)]
        (->> s
             (partition half-len)
             (apply map concat))))
    

    Note that if the input is odd-length, function disregards the last element.

    My experience is that any time you want to do some transformations on some data, it pays to just push the data into a thread-last macro (->>) and keep whacking at it. This problem is quite simple, but the method works for complex transformations also.