Project Euler Problem 25

Ivar Thorson bio photo By Ivar Thorson

Problem 25 asks us to find the index of the first Fibonacci number to have more than 1000 digits. Here’s my first solution, which boils down to making a single, human-readable line at the end.

(def fibonacci (map first (iterate (fn [[a b]] (vector b (+ a b))) [1 1])))

(defn num-digits [n] (count (str n)))

(defn first-where [condition seq]
  "Returns index of the first item in seq that satisfies condition."
  (loop [n 0
         r seq]
    (if (or (nil? r)
            (condition (first r)))
      n
      (recur (inc n) (next r)))))

(defn euler-25 []
  (inc (first-where #(>= (num-digits %) 1000) fibonacci)))

But nearly equivalent performance can be achieved using clojure-contrib.seq-utils, and if we do so we need even fewer lines of code:

(use '[clojure.contrib.seq-utils :only (indexed find-first)])

(def fibonacci (map first (iterate (fn [[a b]] (vector b (+ a b))) [1 1])))

(defn euler-25-seq-utils []
  (inc (first (find-first #(>= (count (str (second %))) 1000)
                      (indexed fibonacci)))))

As usual, proper exploitation of Clojure’s sequence abstraction gives us the shortest solution. Because first-where may be useful in the future, we could also redefine it as:

(defn first-where [condition seq]
  "Returns index of the first item in seq that satisfies condition."
  (first (find-first #(condition (second %)) (indexed seq))))

See you tomorrow!