2016-03-22 6 views
1

İki (potansiyel olarak) sıralanmamış set arasında kesişen bir özyinelemeli lambda işlevi (iki argümanın kabul edilmesi) yazmayı deniyorum. İşte en çok inanıyorum kodu, yalındır bulacaksınız geçerli:4clojure: set-intersection, yinelemeli lambda

(fn intersection [a b] 
(fn inner [x y out] 
    (if (empty? x) out 
    (if (nil? (some ((set (first x)) y))) 
    (inner (rest x) y out)))) 
    (inner (rest x) y (cons (first x) out)) 
    (inner a b '[]) 
) 

Ben çizgi yerine bu lambda fonksiyonu kavşak kullanmak için umut _ izlemeleri Ancak

(= (__ #{0 1 2 3} #{2 3 4 5}) #{2 3})

Bu kod, Java'nın Unable to resolve symbol: inner in this context ...

herhangi bir öneride bulunmadığı konusunda ısrar edemez.

kaynak: http://www.4clojure.com/problem/81

+0

Hata açıklaması biraz gergindeyse kusura bakmayın, ama bu problemi çözmek için iyi bir süre içinde uğraştığımızı düşünüyoruz :( –

+0

kesişim iki parametre alıyor ve başka bir set döndürüyor mu? O zaman neden bunun yerine bir işlev mi döndürüyorsun? – nha

cevap

3

Sen deneyebilirsiniz:

#(set (filter %1 %2)) 

setleri fonksiyonlar olduğundan (başka yararlı bir örnek there bakınız).

(fn [s1 s2] (set (filter s1 s2))) 

Hatta daha özlü: %1 ve %2 ile sözdizimi yazma aynıdır

(comp set filter) 

inner hatası ile ilgili olarak, sadece parens yanlış (ama gerçekten görmüyorum mantık aksi):

(fn intersection [a b] 
    (fn inner [x y out] 
    (if (empty? x) out 
     (if (nil? (some ((set (first x)) y))) 
      (inner (rest x) y out))) 
    (inner (rest x) y (cons (first x) out)) 
    (inner a b '[]))) 

siz) O kadar uzun zaman önce yoktu ki (el seti bina ısrar, bunu ile bitebileceğini Bunun gibi bir şekilde:

(fn [s1 s2] 
    (reduce #(if (contains? s2 %2) (conj %1 %2) %1) #{} s1)) 

Ama gerçekten ilk çözüm en zarif olanıdır.