Thanks for the explanation Christophe. I really need to try use (for) more often. I seem to forget about it all the time.
On Dec 27, 10:42 pm, Christophe Grand <christo...@cgrand.net> wrote: > 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 -~----------~----~----~----~------~----~------~--~---