clojure - 用 Clojure 编写帕斯卡三角形的更惯用和简洁的方法是什么?

标签 clojure idioms pascals-triangle

我实现了一个简单的解决方案,用于打印 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/

相关文章:

java - 如何在 Clojure 中捕获多个异常?

python - 如何有条件地从元组列表中删除元素?

assembly - x86 汇编语言

c++ - 在 C++ 中居中 Pascal 的三角形输出

tcp - 如何将 (Clojure) Aleph TCP 服务器绑定(bind)到 TCP v4 端口?

clojure - 枚举命名空间并在 ClojureScript 中动态加载它们

java - 帕斯卡三角形的格式

c++ - 为什么我在计算 Pascal 三角形的元素时在递归 C 程序中出现堆栈溢出错误?

regex - 将集合转换为 clojure 中的正则表达式模式

ruby - "nil or zero"的最佳 ruby​​ 习语