dolist もいいけど、もうちょっと lispっぽく行きたい。
そういうことなら、まずは再帰だ。そもそも体が再帰を考えることに慣れてないと自覚したので、ココを見て練習してみる。
1. まずは恒例の n! を求めるやつ。n! = 1 * 2 * 3 * ... n 。
(defun my-fact (n) (if (= n 0) 1 (* n (my-fact (1- n))))) ;; test (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))))) ;; test (my-expt 2 10) 1024
OK。どんどん行こう。
3. リストの要素数を求める。
(defun my-length (lst) (if (eq lst '()) 0 (1+ (my-length (cdr lst))))) ;; test (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))))) ;; test (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))))) ;; test (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)))) ;; test (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)))))
を基本パターンとして書いてみて、それをちょこっと変更することを考えてみるって感じだろうか。
そんなのしなくても、慣れればズババーと書けるんだろうけど、いっぺんにそこまで到達するのは無理っぽい。
「これは再帰でいけるかな?」と考える癖だけでもつけておくことにしよう。
0 コメント :
コメントを投稿