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

Reply via email to