在clojure中合并不同大小的列表

时间:2017-03-30 19:13:32

标签: clojure

我有2个列表

s = [1 2 3 4 5]

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

我想从p中取N个元素,其中N是1到K之间的随机数,并从p创建从s到这N个元素的映射。

生成的映射可能类似于

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

表示K = 3。

如果没有使用p中的所有元素,但是有足够的元素来覆盖s中所有元素的N是最大值的情况,那就没问题了。

我想出了这个,但它缺少随机N元素部分,并为s中的每个元素分配(几乎)相同数量的元素

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

这导致

((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))

更新 让我为这个问题增加一些背景,以便更好地理解。 我正试图生成一个星系,每个恒星在它的系统中都有1到N个行星。 s列表包含星星的id,p列表包含行星的id。我想将行星ID映射到星ids,因此每个系统在系统中都有1到N个随机行星。

2 个答案:

答案 0 :(得分:2)

我希望我能正确理解你的问题:

(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)))

示例输出:

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

答案 1 :(得分:0)

每颗恒星必须有一个随机数的行星。这里至少有1但最多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))

每次运行它时,答案都会有所不同,但每颗恒星都包含在1到3个行星之间。示例输出:

;; ((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))

并非所有行星都被使用,行星永远不会重复 - 因为行星当然不能存在于多个太阳系中。