首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用Clojure编写Pascal's Triangle有什么更地道、更简洁的方法吗?

用Clojure编写Pascal's Triangle有什么更地道、更简洁的方法吗?
EN

Stack Overflow用户
提问于 2013-06-28 11:55:01
回答 3查看 305关注 0票数 3

我实现了一个简单的解决方案来打印N深度的Pascal's Triangle,我将在下面介绍它。我的问题是,在哪些方面可以改进这一点,使其更加地道?我觉得有很多东西看起来过于冗长或笨拙,例如,这个if代码块让人感觉不自然:(if (zero? (+ a b)) 1 (+ a b))。任何反馈都很感谢,谢谢!

代码语言:javascript
复制
(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))))))
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-06-28 12:15:09

代码语言:javascript
复制
(defn pascal []
  (iterate (fn [row]
             (map +' `(0 ~@row) `(~@row 0)))
           [1]))

或者,如果你要追求最大的简洁性:

代码语言:javascript
复制
(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时就不会溢出。

票数 8
EN

Stack Overflow用户

发布于 2013-06-28 12:04:54

代码语言:javascript
复制
(defn next-row [row]
  (concat [1] (map +' row (drop 1 row)) [1]))

(defn pascals-triangle [n]
  (take n  (iterate next-row '(1))))
票数 5
EN

Stack Overflow用户

发布于 2013-06-28 13:15:50

不像其他的那么简洁,但这是我的:)

代码语言:javascript
复制
(defn A [] 
  (iterate 
    (comp (partial map (partial reduce +)) 
      (partial partition-all 2 1) (partial cons 0))
        [1]))
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17356924

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档