(defparameter *memoization* (make-hash-table))

(defun digits (n &optional (l (list)))
 (if (= n 0)
  l
  (multiple-value-bind (a b) (floor n 10)
   (digits a (cons b l)))))

(defun square-digits (n &aux (hash (gethash n *memoization*)))
 (if hash
  hash
  (loop for i in (digits n) summing (expt i 2))))

(defun process (n)
 (loop
  for c = (square-digits n)
  until (or (= c 1) (= c 89))
  collect c into results
  do (setf n c)
  finally
   (loop for i in results do (setf (gethash i *memoization*) c))
   (return c)))

(loop
 with result = 0
 for i from 1 to 10000000
 do
  (if (= (process i) 89) (incf result))
 finally (print result))

;(loop for i being the hash-keys in *memoization* using (hash-value j)
; do (format t "~a ~a ~%" i j))

