隣り合う二項の差

どう書く?orgで出題されていた,自分のLisp力でも解けそうな,それでいてLispで書きやすそうなお題をピックアップ


cdr再帰に凝っている自分としては,ループは再帰で書きたい.まさしくcdr再帰(笑)

(defun diff (lis)
  (cond ((> 2 (length lis)) nil)
	(t (cons (- (cadr lis) (car lis)) (diff (cdr lis))))))

(diff '(3 1 4 1 5 9 2 6 5))
(-2 3 -3 4 4 -7 4 -1)

意外にもレスしている人たちはloopとかdo使って処理してた.計算コストを考えたら計数反復ですが.
そしたらすごい人がもっと短いコード書いていた.

(defun diff (lis)
  (mapcar '- (cdr lis) lis))

あれ?なんでmapcarで引数ふたつ取っているんだ??一瞬よくわからなかったけれど,リファレンスを見てようやく思い出した.ふたつ以上のリストを受け取る場合は,一番短いリストに合わせるんだった.だから(cdr lis)の方がひとつ短いので,lisの最後の要素は無視されます.ほーかほーか.


mapcarの使い方については,後述します.