ここ数日(というほどでもないが)「ズンドコキヨシ」なるブームが到来しているそうです。せっかくなので、ミーハー気分で参加してみようと思います。ちなみに「ズンドコキヨシ」の存在は以下の記事を見て知りました:「ズンドコキヨシまとめ」。ブームの経緯や詳しいレギュレーションなどは当該記事をご参照のほどお願いします。
というわけで意気込んでコーディングを始めたわけですが――結論から先に述べると、はじめのうちは問題文を読み間違っておりました(´・ω・`)。すなわち__「『ズン』もしくは『ドコ』のどちらかをランダムに出力し続けるが、その際ズン⇒ズン⇒ズン⇒ドコという並びが現れた瞬間『キ・ヨ・シ!』を出力して、ループを脱出する」__というように問題を誤解しており、その結果次のようなソースコードが出来上がりました。
(use srfi-27)
(define (zun-doko-stream)
(let loop ((ls '())
(logging 0)
(i (random-integer 2)))
(if (= logging 1110)
(reverse (cons "キ・ヨ・シ!" ls))
(loop (cons (if (zero? i) "ドコ" "ズン") ls)
(modulo (+ i (* logging 10)) 10000)
(random-integer 2)))))
(for-each
(lambda (s) (begin (display s) (newline)))
(zun-doko-stream))
実行結果は以下の通り。もちろん乱数を使っているので、実行するたびに結果が少しずつ変わります。
ズン
ドコ
ズン
ズン
ドコ
ズン
ズン
ドコ
ズン
ドコ
ドコ
ズン
ドコ
ドコ
ズン
ズン
ズン
ズン
ズン
ズン
ドコ
キ・ヨ・シ!
改めてながめてみると、なかなかのハードコーディングですね。ちょっと反省(´・ω・`)。もっとも本問について再利用しやすいコードを書くのは結構難しそうですが……。
さて以上のコードを作り終え、ある程度テストも済ませたあと、問題文を読み間違っていることに気がつきました。以下が題意通りの結果を示すコードです。
(use srfi-1)
(use srfi-13)
(use srfi-27)
; "ズン"と"ドコ"をランダムに並べて、大きさ4のリストを作る
; ex. (list "ズン" "ドコ" "ドコ" "ズン")
(define (make-zun-doko)
(let loop ((ls '()) (cnt 4))
(if (zero? cnt)
ls
(loop (cons (if (zero? (random-integer 2)) "ズン" "ドコ") ls)
(- cnt 1)))))
(define (zun-doko-list)
(let ((last-zundoko (list "ズン" "ズン" "ズン" "ドコ")))
(let loop ((ls (list (make-zun-doko))))
(if (list= string=? (car ls) last-zundoko)
(reverse (cons "キ・ヨ・シ!" ls))
(loop (cons (make-zun-doko) ls))))))
(for-each
(lambda (ls) (begin (display ls) (newline)))
(zun-doko-list))
実行結果は以下の通り。こちらも実行のたびに結果が少しずつ変わります。
(ドコ ドコ ズン ドコ)
(ズン ドコ ドコ ズン)
(ドコ ズン ズン ドコ)
(ドコ ドコ ズン ズン)
(ドコ ドコ ドコ ドコ)
(ドコ ドコ ドコ ズン)
(ドコ ズン ズン ドコ)
(ズン ズン ズン ドコ)
キ・ヨ・シ!