ようこそ。睡眠不足なプログラマのチラ裏です。

ケブンッリジ関数でどう書く?orgデビューしてみた

微妙に風化したお題ではありますが、どう書く?orgデビューしてみました。

using System;
using System.Linq;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main()
        {
            var str = @"こんにちは みなさん おげんき ですか? わたしは げんき です。
この ぶんしょう は いぎりす の ケンブリッジ だいがく の けんきゅう の けっか
にんげん は もじ を にんしき する とき その さいしょ と さいご の もじさえ あっていれば
じゅんばん は めちゃくちゃ でも ちゃんと よめる という けんきゅう に もとづいて
わざと もじの じゅんばん を いれかえて あります。
どうです? ちゃんと よめちゃう でしょ?
ちゃんと よめたら はんのう よろしく";

            Console.WriteLine(str.ToCambridge());
            Console.ReadKey();
        }
    }

    static class StringExtensions
    {
        static readonly Random rand = new Random();
        static public string ToCambridge(this string self)
        {
            var tokenize = from line in self.Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries)
                         from token in line.Split(' ')
                           select token;

            Func<string, string> convert = x =>
            {
                if (x.Length <= 3) return x;
                var items = x.ToCharArray();
                var middle = (from c in items.Select((v, i) => new { Value = v, Index = i })
                              where c.Index != 0
                              where c.Index != items.Length - 1
                              select c.Value.ToString()).ToList();
                var shuffle = middle;
                while (shuffle.SequenceEqual(middle))
                      shuffle = middle.OrderBy(s => rand.NextDouble()).ToList();
                return items.First() + shuffle.Aggregate((l, r) => l + r) + items.Last();
            };
            return tokenize.Select(x => convert(x)).Aggregate((x, y) => x + ' ' + y);
        }
    }
}

わざわざLINQとラムダ式と拡張メソッドを使ってC#3.0らしくしてみました*1
なんかもっとイケそうな気がするけど、まあいいや。

*1:なにこの無理矢理感w