Basically, I am trying to generate n
number of random number and use them as indices to return elements in the the sequence (range n)
and I also want to keep adding them up on the fly by using reduce
. The first 2 expressions return results relatively quickly. However, the 3rd expression takes forever to run, which I have no idea why. Does this have anything to with laziness , which is a concept that I never understand. If it does, please also elaborate on what laziness really means.
(reduce + (map #(nth (range 1000) %) (repeatedly 1000 #(rand-int 1000))))
504750
(reduce + (map #(nth (range 10000) %) (repeatedly 10000 #(rand-int 10000))))
50334424
(reduce + (map #(nth (range 100000) %) (repeatedly 100000 #(rand-int 100000))))
;; this takes forever
And is there way to make sure the third line of expression return a definite answer without hanging in there forever ?
Few mistakes here.
(range n)
returns a sequence, nth
function gives indexed access to collection. Of course sequence doesn't know anything about index, so your nth
works in O(n)
time To make nth
a linear solution, transform seq to vector (vec (range n))
Every time to access an item in a collection you create a new range, what is not optimal.
Your 2nd case:
(time (reduce + (map #(nth (range 10000) %) (repeatedly 10000 #(rand-int 10000)))))
"Elapsed time: 4055.15506 msecs"
Improved version:
(time(reduce + (let [array (vec (range 10000))]
(repeatedly 10000 #(nth array (rand-int 10000))))))
"Elapsed time: 5.134413 msecs"
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.