ピカチュウのセリフをマルコフ連鎖で生成する
ピカチュウのセリフがどういった構造かよく知らないが、想像の範囲でそれらしいものを生成してくれるジェネレータを作ってみた。生成には教科書的な単純なマルコフ連鎖を使っている。現在の状態から、既知の確率で次の状態に遷移する。それだけだと文の切れ目が分からないので、終端かどうかも出力する。
(setq pika-tb ; p1p2p3p4k1c1c2c3t1e1e2e3 (list (list "ピカ" nil 1 2 2 2 1 9 3 3 1 2 2 4) (list "ピッ" nil 4 1 1 1 1 0 0 0 1 1 1 1) (list "ピー" nil 4 4 0 4 8 0 0 0 3 1 1 1) (list "ピッカ" nil 2 2 2 2 1 4 2 2 1 2 2 2) (list "カー" nil 1 1 1 1 0 3 1 3 1 1 1 1) (list "チュウ" nil 1 1 1 1 0 0 0 0 0 3 2 9) (list "チュ〜ウ" nil 0 0 0 0 0 0 0 0 1 3 2 4) (list "チュー" nil 0 1 1 1 0 0 0 0 0 3 0 9) (list "、" nil 1 1 1 1) (list "。" t 1 1 1 1) (list "? " t 1 1 1 1) (list "! " t 1 1 1 1 ))) (defun gen-pika-langue () (let ((st 0)) (lambda () (let ((data (elt pika-tb st))) (setq st ; ルーレット選択で次の状態を選択 (let ((r (random (apply '+ (subseq data 2)))) (c 0) (d 0)) (dolist (arg (subseq data 2) c) (if (< r (incf d arg)) (return c) (incf c))))) (subseq data 0 2))))) ;生成してみる。 (let ((p (gen-pika-langue))) (dotimes (i 10) (loop (let ((arg (funcall p))) (format t "~A" (car arg)) (if (cadr arg) (return))))))
例では10の文を生成している。結果は次の通り。ピカチュウ! ピカチューピッカピーカーピー、ピッカチュウ! ピッピカチュウ! ピーカーチュー。ピッカチュウピッカ! ピッピー? ピッカー! ピカ! ピッピカ、ピッカ! ピカチュウ?