進捗どうですかを遅ればせながらC#で(LINQ)


前回不本意にもC#感がなくなってしまったのでリベンジです。
C#といえばLINQが魅力的だと思っているので、LINQで 無理やり 挑みます。

using System;
using System.Collections.Generic;
using System.Linq;

namespace HowToTheProgressLinq
{
    class Program
    {
        static void Main(string[] args)
        {
            var words = new[] { "進捗", "どう", "です", "か" };
            var needle = string.Concat(words);

            string result = words.InfiniteRandom(new Random()).AggregateUntil(string.Empty, (added, word) => added + word, added => added.EndsWith(needle));
            Console.Write(string.Format(
@"{0} ???
 _人人人人人人人_
 >進捗どうですか<
  ̄Y^Y^Y^Y^Y^Y^Y ̄
{1}文字で煽られました",
                result,
                result.Length));
            Console.ReadLine();
        }
    }

    public static class EnumerableEx
    {
        // 要素がランダムに並び続ける無限シーケンスを作成する
        public static IEnumerable<TSource> InfiniteRandom<TSource>(this IEnumerable<TSource> source, Random rand)
        {
            var limit = source.Count();
            while (true)
            {
                yield return source.ElementAt(rand.Next(limit));
            }
        }

        // 条件に一致するまで集計関数を適用する
        public static TAccumulate AggregateUntil<TSource, TAccumulate>(this IEnumerable<TSource> source, TAccumulate seed, Func<TAccumulate, TSource, TAccumulate> func, Func<TAccumulate, bool> predicate)
        {
            TAccumulate result = seed;
            foreach (var element in source)
            {
                result = func(result, element);
                if (predicate(result))
                {
                    break;
                }
            }

            return result;
        }
    }
}

はいはい、YAGNI、YAGNI。