Amosapientiam

備忘録

C#でズンドコキヨシしてみた

n番煎じながらズンドコキヨシしてみた。

レギュレーション

qiita.com

実装

ソースはこちら

using System;
using System.Collections.Generic;
using System.Linq;
using static System.Console;
using static Zdk;

static class Program {
    static Random random = new Random();
    static IEnumerable<int> Infinite() { while (true) yield return 0; }
    static T AtRandom<T>(params T[] args) => args[random.Next(args.Length)];
    static Zdk[] pattern = { Zun, Zun, Zun, Zun, Doko };

    static void Main() =>
        Infinite().Select(_ => AtRandom(Zun, Doko))
        .Scan(new Queue<Zdk>(), (q, zd) => q.History(zd, 6))
        .TakeWhile(x => !x.Take(5).SequenceEqual(pattern))
        .Select(x => x.Last()).Cast<object>().ForEach(WriteLine);
}

enum Zdk { Zun, Doko, Kiyoshi }

static class QueueExtention {
    public static Queue<T> History<T>(this Queue<T> queue, T item, int size) {
        queue.Enqueue(item);
        if (queue.Count > size) queue.Dequeue();
        return queue;
    }
}

Interactive Extensionsを使っている。

解説

main関数は以下の通り。

    static void Main() =>
        Infinite().Select(_ => AtRandom(Zun, Doko))
        .Scan(new Queue<Zdk>(), (q, zd) => q.History(zd, 6))
        .TakeWhile(x => !x.Take(5).SequenceEqual(pattern))
        .Select(x => x.Last()).Cast<object>().ForEach(WriteLine);

行ごとに解説する。

Infinite().Select(_ => AtRandom(Zun, Doko))

ZunとDokoをランダムに返す無限列を生成している。

.Scan(new Queue<Zdk>(), (q, zd) => q.History(zd, 6))

上述の列を最大長さ6の履歴列に変換している。

.TakeWhile(x => !x.Take(5).SequenceEqual(pattern))

履歴の先頭5要素がZun Zun Zun Zun Dokoのpatternになったら終了。

.Select(x => x.Last()).Cast<object>().ForEach(WriteLine);

最新(最後)の履歴を取り出し出力。

感想

    static IEnumerable<int> Infinite() { while (true) yield return 0; }

無限イテレータ↑が標準で欲しい。

余談

yuchiki1000yen.hatenablog.com 12月31日の23時58分に完成した記事です。一年のシメをこの記事に費やした事実は私がズンドコクラスタであることのなによりの証拠です。