隣り合う二項の差
どう書く?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の使い方については,後述します.