我实现了一个简单的解决方案,用于打印 N 深度的帕斯卡三角形,我将在下面介绍。我的问题是,可以通过哪些方式改进它以使其更惯用?我觉得有很多东西看起来过于冗长或笨拙,例如这个if
块感觉不自然:(if (zero? (+ a b)) 1 (+ a b))
.任何反馈表示赞赏,谢谢!
(defn add-row [cnt acc]
(let [prev (last acc)]
(loop [n 0 row []]
(if (= n cnt)
row
(let [a (nth prev (- n 1) 0)
b (nth prev n 0)]
(recur (inc n) (conj row (if (zero? (+ a b)) 1 (+ a b)))))))))
(defn pascals-triangle [n]
(loop [cnt 1 acc []]
(if (> cnt n)
acc
(recur (inc cnt) (conj acc (add-row cnt acc))))))
最佳答案
(defn pascal []
(iterate (fn [row]
(map +' `(0 ~@row) `(~@row 0)))
[1]))
或者,如果您想要最大程度的简洁:
(defn pascal []
(->> [1] (iterate #(map +' `(0 ~@%) `(~@% 0)))))
对此进行扩展:高阶函数的观点是查看您的原始定义并实现如下内容:“我实际上只是在初始值上计算函数
f
,然后再次调用 f
,并且然后 f
再次...”。这是一个常见的模式,因此定义了一个函数来为您覆盖无聊的细节,让您只需指定 f
和初始值。并且因为它返回一个惰性序列,所以您不必指定 n
现在:您可以推迟它,并使用完整的无限序列,以及您想要的任何终止条件。例如,也许我不想要第一个
n
行,我只想找到总和是完美平方的第一行。那我就可以 (first (filter (comp perfect-square? sum) (pascal)))
,而不必担心 n
有多大我需要预先选择(假设 perfect-square?
和 sum
的明显定义)。感谢fogus 的改进:我需要使用
+'
而不仅仅是 +
以便在它过去时不会溢出 Long/MAX_VALUE
.
关于clojure - 用 Clojure 编写帕斯卡三角形的更惯用和简洁的方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17356924/