Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.0k views
in Technique[技术] by (71.8m points)

clojure - Split 100% in a given number of columns width random width

i want to split 100% in a given number of columns. but the width of the columns should be random. here is my first try. but it's static to 5 columns. any ideas to make it dynamic?

(defn create-columns []

  (let [col1 (int (random/number 14 26))
        col2 (int (random/number 14 26))
        col3 (int (random/number 14 26))
        col4 (int (random/number 14 26))
        col5 (- 100 (+ col1 col2 col3 col4))]

    [{:width col1, :left 0}
     {:width col2, :left (int col1)}
     {:width col3, :left (+ col1 col2)}
     {:width col4, :left (+ col1 col2 col3)}
     {:width col5, :left (+ col1 col2 col3 col4)}]))

result should be like

[{:width 23, :left 0} {:width 24, :left 23} {:width 23, :left 47} {:width 14, :left 70} {:width 16, :left 84}]

and ideas?

question from:https://stackoverflow.com/questions/65892066/split-100-in-a-given-number-of-columns-width-random-width

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Here is an algorithm expressed as operations on lazy sequences:

  1. Generate random positions separating the columns including bounds to the left and right.
  2. Sort all the positions
  3. Form pairs of every position and the next one
  4. 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))))

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...