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
-~----------~----~----~----~------~----~------~--~---

Reply via email to