Clojure 中的最大公约数
Greatest Common Divisor in Clojure
我写了下面的代码来计算两个正数的最大公约数。代码中是否存在一些不够优化或不够 clojurian 的问题,如果是这样的话,执行 GCD 的更 cloujerian 方式是什么?
(def gcd (fn [a b] (->> (map (fn [x]
(filter #(zero? (mod x %)) (range 1 (inc x))))
[a b])
(map set)
(apply clojure.set/intersection)
(apply max))))
(gcd 1023 858)` => 33
使用序列操作进行数字运算(没有传感器)有点重量级,这将是 recur
的一个很好的例子:
user> (defn gcd [a b]
(if (zero? b)
a
(recur b (mod a b))))
#'user/gcd
user> (gcd 1023 858)
33
这节省了一些 effort/time 用于构建随后被丢弃的序列。在这种情况下,它创建了两个数字序列的序列,将其转换为两个集合的序列,然后将其分解为单个集合,其中最大值是答案。
此外,一般来说,当定义包含函数的变量时使用 defn
(define function 的缩写)它会自动添加对工具有很大帮助的好东西,比如显示参数类型等。
这是我做的,比较短,而且没有使用递归:
(defn gcd
[a b]
(last
(filter
#(and (zero? (mod b %)) (zero? (mod a %)))
(range 1 (inc (min a b)))
)
)
)
(loop [a (map #(Integer/parseInt %) (clojure.string/split (read-line) #" "))]
(cond
(reduce > a) (recur (list (reduce - a) (last a)))
(reduce < a) (recur (list (- (reduce - a)) (first a)))
(reduce = a) (println (first a))))
可能还应该提到 "just use Java" 方法:
(defn gcd [a b]
(.gcd (biginteger a) (biginteger b)))
我写了下面的代码来计算两个正数的最大公约数。代码中是否存在一些不够优化或不够 clojurian 的问题,如果是这样的话,执行 GCD 的更 cloujerian 方式是什么?
(def gcd (fn [a b] (->> (map (fn [x]
(filter #(zero? (mod x %)) (range 1 (inc x))))
[a b])
(map set)
(apply clojure.set/intersection)
(apply max))))
(gcd 1023 858)` => 33
使用序列操作进行数字运算(没有传感器)有点重量级,这将是 recur
的一个很好的例子:
user> (defn gcd [a b]
(if (zero? b)
a
(recur b (mod a b))))
#'user/gcd
user> (gcd 1023 858)
33
这节省了一些 effort/time 用于构建随后被丢弃的序列。在这种情况下,它创建了两个数字序列的序列,将其转换为两个集合的序列,然后将其分解为单个集合,其中最大值是答案。
此外,一般来说,当定义包含函数的变量时使用 defn
(define function 的缩写)它会自动添加对工具有很大帮助的好东西,比如显示参数类型等。
这是我做的,比较短,而且没有使用递归:
(defn gcd
[a b]
(last
(filter
#(and (zero? (mod b %)) (zero? (mod a %)))
(range 1 (inc (min a b)))
)
)
)
(loop [a (map #(Integer/parseInt %) (clojure.string/split (read-line) #" "))]
(cond
(reduce > a) (recur (list (reduce - a) (last a)))
(reduce < a) (recur (list (- (reduce - a)) (first a)))
(reduce = a) (println (first a))))
可能还应该提到 "just use Java" 方法:
(defn gcd [a b]
(.gcd (biginteger a) (biginteger b)))