[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [bep] learning lisp: while



Reiko TAKAHASHI  (高橋玲子)writes:

> } (defun sigma (n)
> }   (let ((i 1) (s 0))
> }     (while (<= i n)
> }       (setq s (+ s i))
> }       (setq i (1+ i)))
> }     s))

>  n を 4 にして実際の数字を入れてみました。
(中略)
> s)) ; 10

はい、合ってますね。

>  sはこれまでの結果を覚えていてくれて、iは1から順に1ずつ増えて行く役割な
> んですね……?

そうです。

>  fact をwhile で書くと、

> (defun fact (n)
>   (setq s 1)
>   (when (and (integerp n) (>= n 1))
>     (while (>= n 1)
>       (setq s (* s n))
>       (setq n (- n 1)))
>     s))

全体的には合ってますが、これだとグローバル変数の s に値を代入してしま
いますから、全体を let で囲んで s をローカルにした方がいいでしょう。あ
と掛算だから変数名は s よりも p の方がわかりやすいかもしれません。また
細かいことですが、ある数に1をかけても同じですから、(>= n 1) は (> n 1)
とするとループを一回減らせます。

(defun fact (n)
  (when (and (integerp n) (>= n 1))
    (let ((p 1))
      (while (> n 1) 
	(setq p (* p n)
	      n (1- n)))
      p)))

今までだまっていましたが、

(setq a 1)
(setq b 2)

は

(setq a 1 b 2)

とまとめられます。まとめなくても構いません。読みやすさが優先です。

> でしょうか? (setq s 1) が最初思いつけなくて、ちょっと悩みました。

そうですね。sigma をまねして (setq s 0) とやっちゃうと、何回ループを回っ
ても0のままですからね。

>  sigma を再帰で書くと、

> (defun sigma (n)
>   (when (and (integerp n) (>= n 1))
>     (if (= n 1)
>         1
>       (+ n (sigma (- n 1))))))

> ですか?

はい、これも合っているようです。かなり慣れてきましたね。

-- 
TAKAHASHI Naoto
ntakahas@...
http://www.m17n.org/ntakahas/