Memoize

Euler problem 14.1.2

.

(defun range (max &key (min 0) (step 1))
  (loop :for n :from min :below max :by step
        collect n))

(defun max-item (lst)
  (loop :for item :in lst
        :maximize item))

(defmacro r-nth (n lst)
  `(nth (- (length ,lst) ,n) ,lst))

(defun collatz-length (n c)
  (cond ((= n 1) c) 
        ((evenp n) (collatz-length (/ n 2) (1+ c)))
        ('t (collatz-length (1+ (* 3 n)) (1+ c)))))

(defun memoize (fn)
  (let ((cache (make-hash-table :test #'equal)))
    #'(lambda (&rest args)
        (multiple-value-bind (val win)
            (gethash args cache)
          (if win
              val
              (setf (gethash args cache)
                    (apply fn args)))))))

(setf (fdefinition 'collatz-length)
      (memoize #'collatz-length))

(time (max-item (mapcar #'(lambda (x)
                            (collatz-length x 1))
                        (range 1000001 :min 1))))

;; Heap exhausted (no more space for allocation).
;; 109314048 bytes available, 171127632 requested.

;; PROCEED WITH CAUTION.
;;    [Condition of type
;;       SB-KERNEL::HEAP-EXHAUSTED-ERROR]

(time (max-item (mapcar #'(lambda (x)
                            (collatz-length x 1))
                        (range 250001 :min 1))))

;; Evaluation took:
;; 1.380 seconds of real time

(time (max-item (mapcar #'(lambda (x)
                            (collatz-length x 1))
                        (range 250001 :min 1))))

;; Evaluation took:
;; 0.068 seconds of real time

— Me@2023-07-14 02:54:38 PM

.

.

2023.07.14 Friday (c) All rights reserved by ACHK