Pythonでズンドコキヨシ(ジェネレータ)

  • 4
    いいね
  • 3
    コメント
この記事は最終更新日から1年以上が経過しています。

概要

流行っているようなのでN番煎じとしてPythonでやってみました。

コード(version1)

# -*- coding: utf-8 -*-
from collections import deque
import random


z = u'ズン'
d = u'ドコ'
zzzzd = (z, z, z, z, d, )
kys = u'キ・ヨ・シ!'


# 無限ズンドコジェネレータ
def zd():
    while True:
        w = random.choice((z, d, ))
        print w
        yield w


def zndkkys():
    q = deque()
    # 絶対に一致しない4文字目まで読み飛ばす
    for i, w in enumerate(zd()):
        q.append(w)
        if i == 3:
            break

    # 5文字目以降は都度チェックしつつ不要な文字は捨てる
    for w in zd():
        q.append(w)
        if all((zzzzd[i] == p for i, p in enumerate(q))):
            print kys
            return
        q.popleft()


if __name__ == '__main__':
    zndkkys()

特徴

  • listを延々伸ばすコードが多かったのであえてdequeで5文字分のみチェック
  • 無限ズンドコジェネレータ

しかし

これジェネレータだけで行けるんじゃね?というのが下のversion2です

コード(version2)

# -*- coding: utf-8 -*-
from collections import deque
import random


z = u'ズン'
d = u'ドコ'
kys = u'キ・ヨ・シ!'

def zndkkys2():
    state = 0
    while True:
        num = random.choice((0, 1, ))
        # ズンならカウントアップ
        if num:
            yield z
            state += 1
        else:
            yield d
            # ドコの前に4回以上ズンが連続していたらキ・ヨ・シ!
            if state >= 4:
                yield kys
                return
            # ドコの前のズンが3回以下ならカウントを初期化
            else:
                state = 0

if __name__ == '__main__':
    print ''.join(zndkkys2())

概要

  • リストを使わない
  • 全部ジェネレータ

まとめ

  • version1は無限ズンドコジェネレータと言いたかっただけのコードだった
  • ジェネレータは内部に状態を持てるのでこういう処理をするときには便利