Here is an algorithm expressed as operations on lazy sequences:
- Generate random positions separating the columns including bounds to the left and right.
- Sort all the positions
- Form pairs of every position and the next one
- Map the pairs to maps with
:left
and :width
.
Here's the code doing that.
(defn random-cols [total col-count]
(->> #(rand-int (inc total))
(repeatedly (dec col-count))
(into [0 total])
sort
(partition 2 1)
(map (fn [[left right]] {:left left :width (- right left)}))))
(random-cols 100 3)
;; => ({:left 0, :width 21} {:left 21, :width 24} {:left 45, :width 55})
This can generate columns that have a width as small as 0, but constraining the columns to some minimum width is likely something you might want to do although the question does not say anything about that:
(defn random-cols-constrained [total col-count min-width]
(let [widths (map #(+ min-width (:width %))
(random-cols (- total (* col-count min-width))
col-count))]
(map (fn [w l] {:width w :left l})
widths
(reductions + 0 widths))))
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…