debian lennyでCommon Lisp(clisp)
※実際には11/22のネタです。 ■インストール $ 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 ■黄金比 以下のページが分かりやすかった。
SICPの問題をCommon Lispで解いていく(25) 問題1.35~36
★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