Emacs Lispでfold
elispでfold-rightとかfold-leftとかを定義して、上の問題を解いてみました。
fold-rightを使った場合
(defun fold-right (f e seq) (if seq (funcall f (car seq) (fold-right f e (cdr seq))) e)) (defun compact-number-list (seq) (fold-right (lambda (n r) (let ((m (car r))) (if (eq (or (car-safe m) m) (1+ n)) (cons (cons n (or (cdr-safe m) m)) (cdr r)) (cons n r)))) nil seq))
fold-leftを使った場合
(defun fold-left (f e seq) (if seq (fold-left f (funcall f e (car seq)) (cdr seq)) e)) (defun compact-number-list (seq) (fold-left (lambda (r n) (let ((m (car r))) (if (eq (or (car-safe m) m) (1+ n)) (cons (cons n (or (cdr-safe m) m)) (cdr r)) (cons n r)))) nil (reverse seq)))
すっきりしたような気が。でもfold-leftの方はreverseがかっこ悪いなぁ。
追記:どうもfold-rightの引数の順序がSchemeと違っていたので直しました。
追記2(9/30):ちなみに再帰を使った元のコードはこれ↓
(defun compact-number-list (seq) (if seq (let ((1st (car seq)) (2nd (cadr seq))) (if (eq (1+ (or (cdr-safe 1st) 1st)) 2nd) (compact-number-list (cons (cons (or (car-safe 1st) 1st) 2nd) (cddr seq))) (cons 1st (compact-number-list (cdr seq)))))))