ふと SICP をやろう! と思い立って LISP / Scheme にふれる機会が増えたので、練習で ズンドコ してみました。
まず、若干は慣れているLISPから。Emacs の Scratch バッファ上で動かしながら書きましたが、Common Lisp でも動作しました。
;; 検出パターン
(setq zdk-list '("ズン" "ズン" "ズン" "ズン" "ドコ"))
;; "ズン" "ドコ" のリストを生成
(defun zd-gen (zd-list count)
(defun zd ()
(cond ((= (random 2) 0) '("ズン"))
(t '("ドコ"))))
(cond ((< count 1)
zd-list)
(t (zd-gen (append zd-list (zd)) (- count 1)))))
;; 与えられたズンドコリストが zdk-list にマッチしたら "キ☆ヨ☆シ!" を加えて返却して終了
(defun zdk (src carry)
(cond ((equal (list (car src) (cadr src) (caddr src) (cadddr src) (car (cddddr src)))
zdk-list)
(append carry zdk-list (list "キ☆ヨ☆シ!")))
((cdr src) (zdk (cdr src) (append carry (list (car src)))))))
;; 実行
(zdk (zd-gen '() 100) '())
実行すると、こんな感じです。
[4]> (zdk (zd-gen '() 100) '())
("ズン" "ズン" "ドコ" "ズン" "ズン" "ドコ" "ズン" "ズン" "ズン" "ドコ" "ドコ" "ドコ" "ドコ"
"ズン" "ドコ" "ズン" "ドコ" "ドコ" "ドコ" "ドコ" "ドコ" "ズン" "ドコ" "ズン" "ズン" "ドコ"
"ドコ" "ズン" "ズン" "ズン" "ズン" "ドコ" "キ☆ヨ☆シ!")
[5]>
無限ループの方法がわからず最大回数を初期値で与えたり、無理矢理なマッチ判定や出力リスト生成など初心者っぽさ全開ですが、ご笑納ください!
# そして本題の Scheme 版で行き詰まってます。。