数値リストのコンパクトな表現

ネットを徘徊してどこぞから拾ってきたお題です。

(define nil '())

;;    '(1 3 4 5 6 12 13 15)
;; => '(1 (3 . 6) (12 . 13) 15)
(define (compact-number-list sorted-number-list)
  (define (iter lis prev start end result)
    (if (null? lis)
        (append result (list (if (null? end) start (cons start end))))
        (if (= (+ prev 1) (car lis))
            (if (null? start)
                (iter (cdr lis) (car lis) (car lis) end result)
                (iter (cdr lis) (car lis) start (car lis) result))
            (iter (cdr lis) (car lis) (car lis) nil (append result (list (if (null? end) start (cons start end))))))))
  (if (null? sorted-number-list)
      nil
      (iter sorted-number-list (- (car sorted-number-list) 1) nil nil nil)))

特にひねりもなく普通に実装しました。普通が一番!(たぶん
実行してみます。

gosh> (compact-number-list '(1 3 4 5 6 12 13 15))
(1 (3 . 6) (12 . 13) 15)