tags:

views:

201

answers:

4

I want to return a list/collection of all numbers in a range that are a multiple of 3 or 5.

In Ruby, I would do

(1..1000).select {|e| e % 3 == 0 || e % 5 == 0}

In Clojure, I'm thinking I might do something like...

(select (mod 5 ...x?) (range 0 1000))
+5  A: 
(filter #(or (zero? (mod % 3)) (zero? (mod % 5))) (range 1000))
dbyrne
You are a kind and noble genius, I thank you
Blaine LaFreniere
No problem :) Project Euler is a great way to learn clojure!
dbyrne
(zero? (* (mod % 3) (mod % 5)) would be better
nickik
@nickik I guess it depends on what you mean by "better"? Its more concise, but its also less efficient. Your code will evaluate the entire form every time. Using `or` allows the form to short-circuit for numbers divisible by 3. Also, while your code is more concise, I'm not convinced its also more readable. Interesting idea though, thanks for the input.
dbyrne
@dbyrne your right. In production I would do the (or ...) to but in the easy euler stuff i go for the shortes code :)
nickik
That is also a weird math trick. I don't like weird math tricks.
Rayne
+3  A: 
(filter #(or (= (mod % 5) 0) (= (mod % 3) 0)) (range 1 100))

is the most direct translation.

(for [x (range 1 100) :when (or (= (mod x 5) 0) (= (mod x 3) 0))] x)

is another way to do it.

Instead of doing (= .. 0), you can use the zero? function instead. Here is the amended solution:

(filter #(or (zero? (mod % 5)) (zero? (mod % 3))) (range 1 100))
Rayne
+1  A: 

how about this: http://gist.github.com/456486

Jed Schneider
+5  A: 

A different way is to generate the solution, rather than to filter for it:

(set (concat (range 0 1000 3) (range 0 1000 5)))
bOR_
You might want to use `(into (sorted-set) ...)` instead of `(set ...)` to preserve the ordering. There's also `sorted-set-by` for user-defined orderings.
Michał Marczyk
Brilliant! I like it. I wish I could give out more than one correct answer.
Blaine LaFreniere