Reputation: 13
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.
Upvotes: 0
Views: 159
Reputation: 6509
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.
Upvotes: 0
Reputation: 13175
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])
Upvotes: 2