dolist もいいけど、もうちょっと lispっぽく行きたい。
そういうことなら、まずは再帰だ。そもそも体が再帰を考えることに慣れてないと自覚したので、
ココを見て練習してみる。
1. まずは恒例の n! を求めるやつ。n! = 1 * 2 * 3 * ... n 。
(defun my-fact (n)
(if (= n 0)
1
(* n (my-fact (1- n)))))
(my-fact 3)
6
よし、つぎ。
2. m の n 乗を出す。m の n 乗 = m * m * m * ... m (m は n個)。
(defun my-expt (m n)
(if (= n 0) 1
(* m (my-expt m (1- n)))))
(my-expt 2 10)
1024
OK。どんどん行こう。
3. リストの要素数を求める。
(defun my-length (lst)
(if (eq lst '())
0
(1+ (my-length (cdr lst)))))
(my-length '(a b (x y z) c d))
5
ノッてきた。
4. 数値リストの要素の合計を求めるやつ。
(defun my-sum-list (lst)
(if (eq lst '())
0
(+ (car lst) (my-sum-list (cdr lst)))))
(my-sum-list '(1 2 3 4 5 6 7 8 9 10))
55
よしよし。これくらいなら行けるぞ。
5. リストから指定した要素を除いたリストを返すにはどうする?
(defun my-remove (lst e)
(if (eq lst '())
'()
(if (eq e (car lst))
(my-remove (cdr lst) e)
(cons (car lst) (my-remove (cdr lst) e)))))
(my-remove '(a x b c x x d x e f) 'x)
(a b c d e f)
・・・ちょっと苦しかったな。気を取り直して、つぎ。
6. リストの指定した要素の位置を返すやつ。 (位置はゼロ始まり)
(defun my-epos (lst e)
(if (eq lst '())
'()
(if (eq (car lst) e)
(append (my-epos (cdr lst) e) (list (1+ (length lst))))
(my-epos (cdr lst) e))))
(my-epos '(a b x c d x x e f x) 'x)
(2 5 6 9)
なんとかいけたけど結構 try and error を繰り返した。
まぁ、やるまえよりは再帰が身についたと思う。
今の自分にできるアプローチとしては、最初のやつ
(defun my-fact (n)
(if (= n 0) 1
(* n (my-fact (1- n)))))
を基本パターンとして書いてみて、それをちょこっと変更することを考えてみるって感じだろうか。
そんなのしなくても、慣れればズババーと書けるんだろうけど、いっぺんにそこまで到達するのは無理っぽい。
「これは再帰でいけるかな?」と考える癖だけでもつけておくことにしよう。