如何生成在Clojure中编写的循环中循环的旋转序列

如何生成在Clojure中编写的循环中循环的旋转序列,clojure,Clojure,在计划晚餐菜单时,用户希望先轮换3天肉,然后再轮换一道素食主菜。肉的轮换是牛肉、鸡肉、鱼、猪肉。蔬菜的轮换方式是先搅拌,然后是豆腐。有没有比我下面介绍的更好(更优雅、更简洁、更可读)的方法来生成用餐顺序 (defn menu [n] (let [meat (cycle '[:beef :chicken :fish :pork]) veg (cycle '[:stirfry :tofu])] (take n (mapcat

在计划晚餐菜单时,用户希望先轮换3天肉,然后再轮换一道素食主菜。肉的轮换是牛肉、鸡肉、鱼、猪肉。蔬菜的轮换方式是先搅拌,然后是豆腐。有没有比我下面介绍的更好(更优雅、更简洁、更可读)的方法来生成用餐顺序

(defn menu [n] (let [meat (cycle '[:beef :chicken :fish :pork])
                     veg (cycle '[:stirfry :tofu])]
                 (take n (mapcat seq (interleave (partition 3 meat) (partition 1 veg))))))

我想这本书略短,更容易阅读(可能更快):

答复:

user> (menu 10)
(:beef :chicken :fish :tofu :pork :beef :chicken :stirfry :fish :pork)
由于
mapcat
可以进行大量的收集,因此就可以了

(conj(:牛肉:鸡肉:鱼):奶油)

(conj(:猪肉:牛肉:鸡肉):豆腐)
等等

您只需要删除第一个值,因为
conj
with list会在开头添加一个元素

如果可以从素食餐开始,那么你也可以减少休息时间,缩短时间


(以n(mapcat conj(分区3肉)蔬菜)为例)
我很想概括一下这个问题:

  • 接受任意比例的任意数量的主菜
  • 生成整个延迟序列,将客户端作为 需要多少就有多少
您可以将数据作为备用盘号和顺序提供。以你为例,我们有

(def dishes [3 [:beef :chicken :fish :pork]
             1 [:stirfry :tofu]])
我们可以调整您的解决方案以生成无休止的菜式序列:

(defn rotate [nlist-pairs]
  (let [pairs (partition 2 nlist-pairs)
        sources (map (fn [[n xs]] (partition n (cycle xs)))
                     pairs)]
    (apply concat (apply interleave sources))))
要获得前十名

(take 10 (rotate dishes))
;(:beef :chicken :fish :stirfry :pork :beef :chicken :tofu :fish :pork)

不完全是。你的第一道菜是豆腐。应该是斯蒂弗利。在
mapcat
中将
veg
替换为
(缺点:扔掉veg)
?这真是聪明。我喜欢一个人如何添加许多集合和控制比例,以及你将菜肴定义和比例与选择分开的方式。我这样做的动机并不是真正的菜谱,而是一种在许多团队中共享的职责表,一些大的,一些小的,我希望尽可能少地给他们增加负担。
(take 10 (rotate dishes))
;(:beef :chicken :fish :stirfry :pork :beef :chicken :tofu :fish :pork)