生成整数分区-将python代码转换为clojure
我试图为一个数字生成整数分区,但无意中发现了一个似乎非常简洁而优雅的分区:生成整数分区-将python代码转换为clojure,clojure,Clojure,我试图为一个数字生成整数分区,但无意中发现了一个似乎非常简洁而优雅的分区: def partitions(n): # base case of recursion: zero is the sum of the empty list if n == 0: yield [] return # modify partitions of n-1 to form partitions of n for p in partitions(n-
def partitions(n):
# base case of recursion: zero is the sum of the empty list
if n == 0:
yield []
return
# modify partitions of n-1 to form partitions of n
for p in partitions(n-1):
yield [1] + p
if p and (len(p) < 2 or p[1] > p[0]):
yield [p[0] + 1] + p[1:]
我应该考虑懒惰的序列吗
我很难对python代码进行推理,到目前为止,我转换python代码的尝试都失败了。非常感谢您为我提供的任何帮助。Tupelo库实现了Python的
yield
函数。以下是翻译:
(ns tst.demo.core
(:use tupelo.core )
(defn partitions [n]
(lazy-gen
(if (zero? n)
(yield [])
(doseq [p (partitions (dec n))]
(yield (glue [1] p))
(when (and (not-empty? p)
(or (< (count p) 2)
(< (first p) (second p))))
(yield (prepend (inc (first p))
(rest p))))))))
(partitions 4) =>
([1 1 1 1] [1 1 2] [2 2] [1 3] [4])
(ns tst.demo.core
(:使用tupelo.core)
(defn分区[n]
(懒将军
(如果(零?n)
(收益率[])
(doseq[p(分区(dec n))]
(屈服强度(胶水[1]p))
(何时(和(不为空?p)
(或(<(计数p)2)
(<(第一个p)(第二个p)))
(收益率(前置(包括第一个p))
(其余p(()()())(())))
(分区4)=>
([1 1 1 1] [1 1 2] [2 2] [1 3] [4])
由于分区的活动端位于前端,因此它最好是一个列表而不是一个向量。这简化了代码的指端
否则,按照你的结构,在Clojure,我们会得到类似于
(defn partitions [n]
(if (zero? n)
'(())
(apply concat
(for [p (partitions (dec n))]
(let [res [(cons 1 p)]]
(if (and (not (empty? p))
(or (< (count p) 2) (> (second p) (first p))))
(conj res (cons (inc (first p)) (rest p)))
res))))))
你哪里做错了?你没能正确地解开
收益率
for
返回一个或两个分区的向量序列
必须将它们连接成单个序列
- 您的基本情况也应该返回一系列分区,而不是
一个单独的空分区,算法将其视为
一个空序列,它在递归链中向上传播。
这就是你的结果
还有一些小的改进需要改进,但我放弃了它们,转而更贴近您的代码
(ns tst.demo.core
(:use tupelo.core )
(defn partitions [n]
(lazy-gen
(if (zero? n)
(yield [])
(doseq [p (partitions (dec n))]
(yield (glue [1] p))
(when (and (not-empty? p)
(or (< (count p) 2)
(< (first p) (second p))))
(yield (prepend (inc (first p))
(rest p))))))))
(partitions 4) =>
([1 1 1 1] [1 1 2] [2 2] [1 3] [4])
(defn partitions [n]
(if (zero? n)
'(())
(apply concat
(for [p (partitions (dec n))]
(let [res [(cons 1 p)]]
(if (and (not (empty? p))
(or (< (count p) 2) (> (second p) (first p))))
(conj res (cons (inc (first p)) (rest p)))
res))))))
=> (partitions 4)
((1 1 1 1) (1 1 2) (2 2) (1 3) (4))