5
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Schemeでズンドコキヨシ

Last updated at Posted at 2016-03-18

遅きに失した感もあるけれど、世間ではズンドコキヨシというのが流行っているらしいので Scheme で書いてみた。処理系は Gauche を仮定しているが、他の R7RS 処理系に移植するのはそれほど難しくないと思う。

コードを書く前に考えてみると、下のような状態機械が思い浮かぶ。

          ズン    ズン    ズン    ズン    ドコ
 --> 0 -+-----> 1 ----> 2 ----> 3 ----> 4 ----> ((キ・ヨ・シ!))
     ^  |*      |*      |*      |*      |*
     |  |       |       |       |       |
     +--+-------+-------+-------+-------+

末尾呼び出し最適化のある言語の気持ちになると、状態は手続きであり、手続きの末尾呼び出しは状態遷移なので、こんな風に書いてみた。入力はストリームとして受け取るものとした。

(use srfi-27)
(use util.stream)

(define zun "ズン")

(define (zun? x)
  (equal? x zun))

(define doko "ドコ")

(define (doko? x)
  (equal? x doko))

(define (init strm)
  (cond ((zun? (stream-car strm))
         (zun1 (stream-cdr strm)))
        (else
         (init (stream-cdr strm)))))

(define (zun1 strm)
  (cond ((zun? (stream-car strm))
         (zun2 (stream-cdr strm)))
        (else
         (init (stream-cdr strm)))))

(define (zun2 strm)
  (cond ((zun? (stream-car strm))
         (zun3 (stream-cdr strm)))
        (else
         (init (stream-cdr strm)))))

(define (zun3 strm)
  (cond ((zun? (stream-car strm))
         (zun4 (stream-cdr strm)))
        (else
         (init (stream-cdr strm)))))

(define (zun4 strm)
  (cond ((doko? (stream-car strm))
         "キ・ヨ・シ!")
        (else
         (init (stream-cdr strm)))))

init から始めて、受理状態になったら "キ・ヨ・シ!" を返して停止することにする。

入力は、乱数生成器を使って、「ズン」と「ドコ」をランダムに並べたストリームを生成する。

(define (zundoko rng)
  (let ((rint (random-source-make-integers rng)))
    (stream-tabulate -1
                     (lambda (_)
                       (case (rint 2)
                         ((0) zun)
                         (else doko))))))

途中経過も見たいので、入力ストリームに値を表示する手続きを stream-map したものを渡しつつ、戻り値を print する(Gauche のストリーム、すなわち SRFI-41 のストリームは even ストリームで、 stream-car を取ったときに計算が実行されるのでこれでうまく行く)。

(define (d x)
  (display x)
  x)

(print (init (stream-map d (zundoko (make-random-source)))))

(exit 0)

こんな感じの結果が出力される。

ドコズンドコドコズンドコドコズンドコズンズンドコズンズンドコドコドコドコドコドコズンドコドコドコドコズンズンドコドコズンズンズンズンズンドコドコドコドコドコドコドコドコズンズンドコズンドコドコドコズンドコドコドコズンズンズンドコズンズンズンドコドコズンズンズンドコズンズンズンドコドコドコドコズンズンドコドコズンズンドコズンズンズンズンドコキ・ヨ・シ!

5
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?