(ns lychrel.core (require [clojure.string :as s]) (require [clojure.set :as set-op]) (:gen-class)) (defn palindrome? "Returns true if given number is a palindrome (number on base 10)" [number] (let [number-str (str number)] (= number-str (s/reverse number-str)))) (defn delete-leading-zeros "Delete leading zeros so that you can read the string" [number-str] (read-string (re-find (re-pattern "[1-9]\\d*") number-str)) ) (defn lychrel "Returns T if number is a candidate Lychrel (up to max iterations), and a second value with the sequence of sums" ([number] (lychrel number 500)) ([number depth] (let [next-number (+' number (delete-leading-zeros (s/reverse (str number)))) depth (- depth 1)] (if (palindrome? next-number) (conj [next-number] number) (if (not= depth 0) (conj (lychrel next-number depth) number) (conj [] nil)) ) ))) (defn lychrel? "Test if number is a possible lychrel number" [number] (= nil (first (lychrel number 500)))) (defn lychrel-up-to-n "Get all lychrels up to N" [N] (filter lychrel? (range 1 N))) (defn make-kin "Removes the starting number of the list, the starting number" [kin] (rest (butlast kin))) (defn calc-seed "The seeding" [] (let [kin-set (atom #{}) seed-set (atom #{})] (fn [n] (let [lychrel-seed (set #{(last n)}) kins (set (butlast n))] (if (= kins (clojure.set/difference kins @kin-set)) (do (swap! kin-set clojure.set/union kins) (swap! seed-set clojure.set/union lychrel-seed) @kin-set)) @seed-set )))) (defn filter-seeds "Filtering the seed through the paths" [] (let [calc-f (calc-seed) all-lychrels (for [lychrel-list (filter lychrel? (range 1 10000))] (filter (fn [x] (> 1000001 x)) (rest (lychrel lychrel-list))))] (last (for [ll all-lychrels] (do (calc-f ll)))))) (defn -main "Here we do the three tasks: Get all possible Lychrel numbers up to 10000 Count them Reduce all possible numbers to seed" [& args] (let [lychrels-n (filter-seeds) count-lychrels (count lychrels-n) related-n (- (count (filter lychrel? (range 1 10000))) count-lychrels) palindrom-n (filter palindrome? (filter lychrel? (range 1 10000))) count-palindromes (count palindrom-n) ] (println count-lychrels "Lychrel seeds:" lychrels-n) (println related-n "Lychrel related.") (println count-palindromes "Lychrel palindromes found:" palindrom-n)) )