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