2012-02-09 25 views
6

Örneğin, aşağıdaki sorunuClojure'da, anonim bir işlev içinde anonim bir işlev tanımlamak mümkün mü?

http://projecteuler.net/problem=5

çözme ben

(defn div [n] (= 0 (reduce + (map #(mod n %) (range 1 21))))) 
(take 1 (filter #(= true (div %)) (range 20 1e11 20))) 

İçine anonim fonksiyon olarak ilk satırı birleştirmek isteyen bazı golf eğlence için varsayalım aşağıdaki çözüm geldi ikinci çizgi. Dil bunu destekliyor mu?

+0

Çözümünüzü daha etkili bir şekilde yeniden yazabilirsiniz. Cevabımı aşağıya bakın. – viebel

cevap

17

Evet öyle, ancak #() okuyucu-makro formlarını yerleştiremezsiniz, (fn) formunu kullanmanız gerekir. Örneğin

: Dış anonim fonksiyonların argüman başvurmak için hiçbir yolu yoktur, çünkü

(#(#(+ %1 %2) 1) 2) 

, çalışmıyor. Bu, iki argüman alan dış fonksiyon ve sıfır argümanları alan iç fonksiyon olarak okunur.

Ama (fn...) s ile aynı şeyi yazabilirsiniz:

user=> (#((fn [x] (+ x %)) 1) 2) 
3 

Yani satır içine alabilirsiniz: Ayrıca, örneğin iki anonim işlevlerinden biri için #() formu kullanabilirsiniz

user=> (((fn [x] (fn [y] (+ x y))) 1) 2) 
3 

div bu şekilde çalışır (#() formunu map formuna geçirmemiz gerektiğine dikkat edin).

#(= true (= 0 (reduce + (map (fn [x] (mod % x)) (range 1 21))))) 
+7

Başparmak kuralı olarak: 'fn', anonim bir işlev tanımlamak için '#()' değil. '#()' sadece 'fn' gibi çok sayıda ses ekleyeceği basit işlev çağrıları için kolaylık sağlar. Daha uzun bedelli fonksiyonlar için 'fn' tercih edilmelidir. – kotarak

0

Sen (daha hızlı x2!) Çok daha basit ve daha verimli bir şekilde çözüm yazabilirsiniz

(defn div [n] (every? #(= 0 (mod n %)) (range 1 21))) 
(take 1 (filter div (range 20 1e11 20))) 

o every? tüm listeyi çapraz ziyade durdurmaz çünkü daha verimli olmasının nedenini Listenin elemanlarından biri yanlış olduğunda.

+0

Ya da kaba kuvvetleri tamamen ortadan kaldırarak yaklaşık 10 kat daha hızlı çözebilirsiniz. . . – ruakh

+0

Gerçekten. Ama ben matematiksel olmayan herhangi bir 'clojure' ile ilgili geliştirmeler düşünmekteydim. – viebel

İlgili konular