Fixed (rev 1190) tristan a écrit : > 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 -~----------~----~----~----~------~----~------~--~---