■インストール
$ apt-cache search ^clisp\$
clisp - Common Lisp の実装 GNU CLISP
$ sudo apt-get install clisp
■「Hello World」
インタプリタは面倒なので標準入力から。
$ echo '(format t "Hello World")' | clisp -q -
Hello, World
$ echo '(format t "Hello, World")' | clisp -q
[1]> Hello, World
NIL
■1から100までの数を足し算する
$ echo "(+ `seq 1 100`)" | clisp -q
[1]>
5050
■1から1000までなら?
$ echo "(+ `seq 1 1000`)" | clisp -q
[1]>
500500
■1から10000までなら?
$ echo "(+ `seq 1 10000`)" | clisp -q
[1]>
50005000
■ガウス
★1から100までの場合、
1+99,2+98,3+97...とすると、50が余るので、
100*50+50=5050、これは以下のように書ける。
$ echo "(+ (* 100 50) 50)" | clisp -q
⇒つまり1からnまでの和は、n*n/2+n/2で解ける。
★1から100までの一般化
$ echo '(setq n 100) (+ (* n (/ n 2)) (/ n 2))' | clisp -q
[1]>
100
[2]>
5050
★1から1000までの一般化
$ echo '(setq n 100) (+ (* n (/ n 2)) (/ n 2))' | sed s/"100"/"1000"/ | clisp -q
[1]>
1000
[2]>
500500
★以下のようにも書ける
$ num=100000;echo '(setq n '$num') (+ (* n (/ n 2)) (/ n 2))' | clisp -q
[1]>
100000
[2]>
5000050000
■黄金比
以下のページが分かりやすかった。
http://semweb.sakura.ne.jp/2011/02/12/sicp%E3%81%AE%E5%95%8F%E9%A1%8C%E3%82%92common-lisp%E3%81%A7%E8%A7%A3%E3%81%84%E3%81%A6%E3%81%84%E3%81%8F24-%E5%95%8F%E9%A1%8C1-34/
★fai.lispの準備
$ echo '(defvar tolerance 0.00001)
(defun fixed-point (f first-guess)
(labels ((close-enough-p (v1 v2)
(< (abs (- v1 v2)) tolerance))
(try (guess)
(let ((next (funcall f guess)))
(if (close-enough-p guess next)
next
(try next)))))
(try first-guess)))' > fai.lisp
★入力側を準備
$ echo '(fixed-point (lambda (x) (+ 1 (/ 1 x))) 1.0)' > fai.input
★実行する
$ cat fai.input | clisp -q -i fai.lisp
;; Loading file fai.lisp ...
;; Loaded file fai.lisp
[1]>
1.6180328
■フィボナッチ数列
以下が分かりやすい
http://d.hatena.ne.jp/sirocco/20100825/1282714226
★fib.lispを作成
$ echo '(defun mk-list (x max)
(if (= x max)
(list max)
(cons x (mk-list (+ x 1) max))))
;; 二重再帰
(defun fib (x)
(cond
((= x 1) 1)
((= x 2) 1)
(t (+ (fib (- x 1))(fib (- x 2))))))' > fib.lisp
★「'」があるので、「""」で囲うかちょっと変な方法でエスケープ「\'」する
$ echo "(mapcar #'fib (mk-list 1 10))" | clisp -q -i fib.lisp
;; Loading file fib.lisp ...
;; Loaded file fib.lisp
[1]>
(1 1 2 3 5 8 13 21 34 55)
$ echo '(mapcar #'\''fib (mk-list 1 10))' | clisp -q -i fib.lisp
;; Loading file fib.lisp ...
;; Loaded file fib.lisp
[1]>
(1 1 2 3 5 8 13 21 34 55)
★再帰はメモリを食うけど、いくつ数列を出したいか明確にしたい。
$ num=15;echo '(mapcar #'\''fib (mk-list 1 '$num'))' | clisp -q -i fib.lisp
;; Loading file fib.lisp ...
;; Loaded file fib.lisp
[1]>
(1 1 2 3 5 8 13 21 34 55 89 144 233 377 610)
■今日のまとめ
for/whileでも足し算は出来るがlispの関数や再帰を使うと更に直感的。
bashでも何でもshellを使うとlispインタプリタをコマンドと同等に扱えて更に楽出来る。
「lispって簡単だよ。」という説明(のつもり)。。。w