[ prog / sol / mona ]

prog


LISP Puzzles

136 2020-05-21 07:05 *

>>130
I "compressed" the unused S values. Not much improvement in terms of order of growth though.

(define (sequence n)
  (let* ((rs 7)                         ; Smallest R value unused.
         (ss (let ((n (list 7)))        ; S skip queue.
               (cons n n)))
         (sl 5)                         ; Smalles S value unused.
         (r 7)                          ; Current R value.
         (s 5)                          ; Current S value.
         (negsum -7)                    ; Negative sum of unused R values.
         (pos 3)                        ; Smallest n in the queues.
         (n (- n 1)))                   ; Off by one.
    (let loop ((i 4))
      (when (<= (+ s r) (+ i n))
        (set! r (+ r s))
        (set! s (+ s 1))
        (set! negsum (- negsum r))
        (when (= s rs)
          (set! rs (+ rs sl))
          (set! sl (+ sl 1))
          (when (= sl (caar ss))
            (set! sl (+ sl 1))
            (set-car! ss (cdar ss)))
          (set! negsum (+ negsum s))
          (set! s (+ s 1))
          (set! pos (+ pos 1))
          (let ((n (list rs)))
            (set-cdr! (cdr ss) n)
            (set-cdr! ss n)))
        (loop (+ i 1))))
    (list pos negsum r s)))

(define (sum m n)
  (* (/ (- m n -1) 2) (+ m n)))

(define (jump n)
  (cond
   ((= n 1) 1)
   ((= n 2) 3)
   ((= n 3) 7)
   ((= n 4) 12)
   (else
    (let* ((seq (sequence n))
           (m   (list-ref seq 0))
           (ns  (list-ref seq 1))
           (rx  (list-ref seq 2))
           (sx  (list-ref seq 3))
           (nx  (+ m -1))
           (s   (+ sx (- n nx))))
      (+ rx (sum (- s 1) sx) ns)))))
157


VIP:

do not edit these