tristan a écrit : > Hi All, > > I've been trying to learn clojure lately by solving the project euler > problems with it, and I think the distinct function is broken (or it > doesn't quite work as I assume it would). > > here is the code i'm running > > > (defn pow [nbr pwr] > (if (< pwr 2) > nbr > (* nbr (pow nbr (dec pwr))))) > > (count (sort (distinct (apply concat (map (fn [i] (map (fn [j] (pow i > j)) (range 2 101))) (range 2 101)))))) > > for which the result shows 9188, but should be 9183. > distinct uses a hash-set (which relies on .hashCode): user=> (vector (-> "4294967296" BigInteger. .hashCode) (-> "4294967296" Long. .hashCode)) [31 1]
But: user=> (compare (-> "4294967296" BigInteger.) (-> "4294967296" Long.)) 0 Since sorted-sets relies on compare you could rewrite distinict to use a sorted-set: (defn distinct1 "Returns a lazy sequence of the elements of coll with duplicates removed" [coll] (let [step (fn step [[f & r :as xs] seen] (when xs (if (seen f) (recur r seen) (lazy-cons f (step r (conj seen f))))))] (step (seq coll) (sorted-set)))) user=> (-> (for [i (range 2 101) j (range 2 101)] (pow i j)) distinct1 count) 9183 or, without rewriting distinct: user=> (count (into (sorted-set) (for [i (range 2 101) j (range 2 101)] (pow i j)))) 9183 I don't know how to fix distinct per se (short of documenting this case). Maybe by adding a distinct-by function which would take a comparator as its first arg. Christophe > I wrote my own distinct function which gives the correct result but > runs a LOT slower > > (defn in? [lst n] > (if (nil? lst) > false > (if (= (first lst) n) > true > (in? (rest lst) n)))) > > (defn unique [lst] > (loop [l lst n (list)] > (if (nil? l) > (sort n) > (if (in? n (first l)) > (recur (rest l) n) > (recur (rest l) (cons (first l) n)))))) > > i'm using revision 1185. > is this a bug or am i doing something wrong? > > thanks > -Tristan > > > > > --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~----------~----~----~----~------~----~------~--~---