gumuz
gumuz

Reputation: 295

Is this idiomatic Clojure?

I've started doing Project Euler using Clojure, as a first stab at learning Clojure. I've solved the first assignment:

Find the sum of all the multiples of 3 or 5 below 1000.

I've previously solved it in Python:

sum(i for i in xrange(1000) if i%3==0 or i%5==0)

This is my first Clojure attempt:

(reduce +
  (filter 
    (fn [x]
      (or 
        (= 0 (mod x 3)) 
        (= 0 (mod x 5))))
    (range 1000)))

I'm actually suprised about how verbose it got, but I'm pretty sure it's because of my style and ignorance of Clojure idioms.

What would an idiomatic version of this Clojure code look like?

Upvotes: 7

Views: 291

Answers (3)

Samiur
Samiur

Reputation: 76

I like trying to solve a general solution for things Project Euler, so here's my generic solution:

(defn sum-multiples [nums lim]
  (reduce
   +
   (filter
    (fn [x]
      (some identity
            (map #(zero? (mod x %)) nums)))
    (range lim))))

and then just call:

(sum-multiples [3 5] 1000)

Upvotes: 0

Kyle
Kyle

Reputation: 22268

This is how I did it:

(apply +
  (filter #(or (zero? (mod % 3))
               (zero? (mod % 5)))
    (range 1000)))

What makes my solution slightly more idiomatic is the use of the anonymous function reader macro, #(...) and the zero? fn

Your solution is different but just as good!

BTW - solving euler problems is a great way to learn a new language - you can't get everything from a book.

Edit:

I decided to provide a different solution more inline with your Python version (not very pretty IMO)

(apply +
  (for [i (range 1000) :when (or (zero? (mod i 3))
                                 (zero? (mod i 5)))]
    i))

Upvotes: 9

mishadoff
mishadoff

Reputation: 10789

Just another version:

(defn sum-of [n]
  (reduce + (range n 1000 n)))

(+ (sum-of 3) (sum-of 5) (- (sum-of 15)))

Upvotes: 9

Related Questions