;; Prablem 101
;;"Elapsed time: 14.696085 msecs"

;; 準備
(defn exp [x n]
  (reduce * (repeat n x)))

;; 題意の式の数列を返す関数
(defn un-seq []
  (let [un (fn [n]
             (reduce +
                     (map #(* (exp -1 %)
                              (exp n %))
                          (range 11))))]
    (map un (iterate inc 1))))


(defn x [i]
  (inc i))

;; Lagrange係数多項式
(defn lagrange [xt k num]
  (reduce *
          (for [i (range num) :when (not= i k)]
            (/ (- xt (x i))
               (- (x k) (x i))))))

;; Lagrange補間多項式を使って解を出す
;; もう一段関数を使ってもよかったか
(defn next-val [vals]
  (let [x-range (count vals)
        next-x (inc x-range)]
    (reduce +
            (for [k (range x-range)]
              (* (nth vals k)
                 (lagrange next-x k x-range))))))

;; もうちょっとclojureらしい書きかたもできそうだったが、
;; 元の式の形を残すことにこだわってみた。

(defn pe-101 []
  (reduce +
          (for [turn (range 1 11)]
            (next-val (take turn (un-seq))))))