2015-09-03 14 views
5

Ho scritto il seguente codice per calcolare il più grande divisore comune di due numeri positivi. Ci sono alcune cose nel codice che non sono ottimali o abbastanza clojuriane, e in tal caso quale sarebbe il modo più cloujeriano di fare GCD?Greatest Common Divisor in 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 

risposta

5

usando manipolazione sequenza di operazioni numeriche (senza trasduttori) è un po 'pesante e questo sarebbe un grande caso recur invece:

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

Questo risparmia certo sforzo/tempo che andrebbe in costruzione sequenze che vengono poi scartate. In questo caso crea una secuenza di due sequenze di numeri, trasforma quella sequenza in due insiemi, poi la distrugge in un unico insieme dal quale il valore più grande è la risposta.
Inoltre, in generale, quando si definiscono i vars che contengono funzioni utilizzare defn (abbreviazione di define function) aggiunge automaticamente delle cose carine che aiutano molto l'utensileria, come la visualizzazione di tipi di argomenti e così via.

+0

Grazie. Dato che sono un principiante, potresti spiegare quale manipolazione di sequenza per operazioni numeriche nel mio codice è? E sarei grato se potessi presentarmi una fonte per saperne di più sui trasduttori – amirteymuri

+0

E l'algoritmo è stato utilizzato l'algoritmo Euclideo? – amirteymuri

+0

Modificherò con altre sequenze e sì, questo è euclids –

0

Questo è quello che ho fatto, è un po 'più corto e non fa uso di ricorsione:

(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))))