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!