2015-09-03 7 views
5

Я написал следующий код для вычисления Величайшего общего делителя двух положительных чисел. Есть ли какие-то вопросы в коде, которые не являются оптимальными или достаточно сложными, и если да, то что будет более cloujerian способом делать GCD?Самый большой общий делитель в Clojure

(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 

ответ

5

с помощью манипуляции последовательности числовых операций (без датчиков) немного тяжеловес, и это будет отличный случай для recur вместо:

user> (defn gcd [a b] 
     (if (zero? b) 
      a 
      (recur b (mod a b)))) 
#'user/gcd 
user> (gcd 1023 858) 
33 

Это экономит усилия/время, которое будет идти в здание последовательности, которые затем отбрасываются. В этом случае он создает последовательность двух последовательностей чисел, превращает их в последовательность из двух наборов, а затем разбивает их на один набор, из которых наибольшим значением является ответ.
Кроме того, при определении варов, содержащих функции, используется defn (сокращение от функции определения), оно автоматически добавляет интересные вещи, которые помогают инструментам много, например, отображать типы аргументов и т. Д.

+0

Спасибо. Как я новичок, не могли бы вы объяснить, какие манипуляции с последовательностями для числовых операций в моем коде? И я был бы признателен, если бы вы могли представить мне источник для получения дополнительной информации о преобразователях. – amirteymuri

+0

И алгоритм, который вы использовали в евклидовом алгоритме? – amirteymuri

+0

Я буду редактировать больше о последовательностях и да, thats euclids –

0

Это то, что я сделал, это немного короче, и он не использует рекурсию:

(defn gcd 
    [a b] 
    (last 
    (filter 
     #(and (zero? (mod b %)) (zero? (mod a %))) 
     (range 1 (inc (min a b))) 
    ) 
    ) 
) 
-1
(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))))