Project Euler in Clojure – Problem 2

In trying to learn Clojure and wrap my head around good functional programming, and hoping to learn more idiomatic Clojure, I have started working through the Project Euler problems. In doing this, I have also setup a repository on github.com to keep track of my progress, which can be found at https://github.com/stevenproctor/project-euler-clojure.  My approach to Problem 1 can be found here.

Problem 2 of Project Euler is described as:

By considering the terms in the Fibonacci sequence whose values do
not exceed four million, find the sum of the even-valued terms.

The solution I came up with is:

(defn skip-n [n s]
  (cond
    (<= n 0) s
    :else (recur (dec n) (rest s))))

(defn fib
  ([] (concat [0N 1N] (fib 0N 1N)))
  ([a b] (let [c (+ a b)]
          (lazy-seq
            (cons c (fib b c))))))

(defn problem2 []
  (reduce + (filter #(even? %) (take-while #(< % 4000000N) (skip-n 2 (fib))))))

As a didn’t see a skip function, which would keep a sequence, but skip over a given number of inputs, I created the function skip-n. The skip function calls the function rest on the sequence n number of times by using recur, and decrementing n.

The function fib generates the Fibonacci sequence lazily by using the function lazy-seq to create a lazily evaluated sequence, as I want the numbers generated until the time that I decide I do not need them anymore. Instead of trying to determine how many that will be before I generate them, I just decided to make them generated lazily.

The previous two functions were a helper function, and the function to generate the Fibonacci sequence (huh, sequence is even in the name). The work to determine the results of the problem are found in the function problem2. This function uses the skip-n function to skip the first two results, as Project Euler shows the Fibonacci sequence starting as 1, 2, 3, … instead of the starting as 0, 1, 1, 2, 3, … so I skip the first two in the sequence. I then use the take-while function to take only those items which are less than 4 million, which I then feed to the filter function to take only those items from the Fibonacci sequence that are even. The last step is to use the reduce function to sum all of those items together to get the final result.

I would love comments and suggestions on my solution to this problem, and if there are tweaks to make it more Clojure-ish.

**Updated**
Here is my approach to Problem 3 in Clojure.

–Proctor

Advertisements

, ,

    • #2 by Proctor on May 30, 2012 - 08:35

      Thanks.

      I thought I saw that clojure.core had that, but could not remember what it was called, and my search-foo wound up failing me. I will have to go update my solution to use drop.

      –Proctor

      • #3 by Adam Rulli-Gibbs on June 1, 2012 - 05:44

        Although the nature of the question means there is no difference to the answer whether you start the sequence “0,1”, “1,1” or “1,2”.

        The 1s aren’t even, and 0 won’t affect the total.

  1. Project Euler in Clojure – Problem 3 « Proctor It
  2. Project Euler in Clojure – Problem 1 « Proctor It

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: