(def monkey-positions-2 "This implementations takes advantage of symmentry, allowing it to concentrate its efforts on quadrant 1, where x and y are both non-negative." (letfn [(neighbors [[x y]] [[(inc x) y] [x (inc y)]]) (digit-value [d] (Character/digit d 10)) (sum-of-digits [n] (reduce + 0 (map digit-value (pr-str n)))) (accessible? [[x y]] (>= 19 (+ (sum-of-digits (Math/abs x)) (sum-of-digits (Math/abs y))))) (mirrors [[x y]] (if (zero? x) (if (zero? y) [[x y]] [[x y] [x (- y)]]) (if (zero? y) [[x y] [(- x) y]] [[x y] [(- x) y] [x (- y)] [(- x) (- y)]])))] (let [sum-of-digits (memoize sum-of-digits) accessible? (memoize accessible?)] (fn monkey-positions ([] (monkey-positions [0 0])) ([origin] (monkey-positions #{} #{origin})) ([visited candidates] (lazy-seq (when (seq candidates) (->> candidates (mapcat neighbors) set (filter (every-pred (complement candidates) (complement visited) accessible?)) set (monkey-positions (into visited candidates)) (concat (mapcat mirrors candidates)))))))))) (defn monkey-count [] (count (monkey-positions-2)))