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 [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
-~----------~----~----~----~------~----~------~--~---