简体   繁体   中英

Merging lists of different sizes in clojure

I have 2 lists

s = [1 2 3 4 5]

and

p = [:a :b :c :d :e :f :h :i :j :k :l :m]

I would like to take N elements from p where N is a random number between 1 to K and create a mapping from s to these N elements from p.

the resulting mapping could be something like

((1 :a) (1 :b) (1 :c) (2 :d) (2 :e) (3 :f) (4 :h) (4 :i) (5 :j) (5 :k) (5 :l))

for K=3.

it's fine if not all the elements in p are used but there are enough elements to cover the case where N is max for all elements in s.

I've come up with this but it's missing the take random N elements part and assigns an (almost) equal number of elements to each element in s

(partition 2 (interleave (cycle s) (shuffle p))))

this results in

((1 :d) (2 :f) (3 :h) (4 :e) (5 :l) (1 :b) (2 :k) (3 :a) (4 :j) (5 :g) (1 :i) (2 :c) (3 :m))

UPDATE: Let me add some more context to the question for a better understanding. I'm trying to generate a galaxy where each star will have 1 to N planets in it's system. The s list contains the ids of the stars, and the p list contains the ids of planets. I would like to map planet ids to star ids so each system has 1 to N random planets in the system.

I hope I understood your question correctly:

(def s [1 2 3 4 5])
(def p [:a :b :c :d :e :f :h :i :j :k :l :m])
(def k 3)

;; concatenate corresponding elements from two sequences into 2-element vectors
(map vector
     ;; generate a sequence of elements from s each duplicated 1 to k times
     (mapcat #(repeat (inc (rand-int k)) %) s)
     ;; generate infinite shuffled seq of elements from p
     (cycle (shuffle p)))

Example output:

([1 :f] [2 :j] [2 :b] [3 :m] [3 :a] [4 :i] [5 :l] [5 :c] [5 :e])

Each star must have a random number of planets. Here at least 1 but maximum of 3:

(def stars [1 2 3 4 5])
(def planets [:a :b :c :d :e :f :h :i :j :k :l :m])

(let [max-num-planets 3
      solar-systems (mapcat #(repeat (inc (rand-int max-num-planets)) %) stars)]
  (map #(list %1 %2) solar-systems (shuffle planets))

Every time you run it the answer will be different, but each star will be included as each star has between 1 and 3 planets. Example outputs:

;; ((1 :a) (1 :b) (1 :c) (2 :d) (2 :e) (3 :f) (4 :h) (4 :i) (4 :j) (5 :k) (5:l) (5 :m))
;; ((1 :a) (1 :b) (1 :c) (2 :d) (3 :e) (3 :f) (4 :h) (5 :i))

Not all the planets are always used, and a planet is never repeated - because of course a planet can't exist in more than one solar system.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM