縦書き

結構前の飲み会であんどちんさんと話してたときに、どういう経緯だったか忘れたのですが「与えられた文字列をできるだけ短い文で縦書きにするのなんて C# があれば余裕ですよ」みたいなことを自分が言った気がするので、今更ながらやってみました。

using System;
using System.Collections.Generic;
using System.Linq;
namespace Tategaki
{
    class Program
    {
        static void Main(string[] args)
        {
            args.Select(s => (IEnumerable<char>)s.PadRight(strs.Max(cs => cs.Length), ' '))
                .Aggregate(Enumerable.Empty<IEnumerable<char>>(),
                    (xss, ys) => ys.Select((yc, n) => Enumerable.Repeat(yc, 1)
                        .Concat(n < xss.Count() ? xss.ElementAt(n) : Enumerable.Empty<char>())))
                .Select(s=>new string(s.ToArray())).ToList().ForEach(Console.WriteLine);
        }
    }
}

1文で全部書きました。繋げるとこんな風に。

args.Select(s => (IEnumerable<char>)s.PadRight(strs.Max(cs => cs.Length), ' ')).Aggregate(Enumerable.Empty<IEnumerable<char>>(), (xss, ys) => ys.Select((yc, n) => Enumerable.Repeat(yc, 1).Concat(n < xss.Count() ? xss.ElementAt(n) : Enumerable.Empty<char>()))).Select(s=>new string(s.ToArray())).ToList().ForEach(Console.WriteLine);

ファイルから読まないといけない場合は args の部分が File.ReadAllLines(args[0]) になるだけのはず。


実行結果。

Tategaki.exe あいうえお かきくけ さしす たちつてと

たさかあ
ちしきい
つすくう
て けえ
と  お

いやもう全然余裕じゃなかったです・・・。


中身は、文字列の最大長に合わせて文字をパディングして、縦横入れ替えて、表示するってやってるだけなのですが、パディングするために一度ループさせてたりインデックスアクセスしてたり微妙な感じ。
自分の探した感じだと zipWith に相当する機能が見つからないんですよね。不思議な・・・。
あと何で string は拡張メソッド見えないんでしょうかね。キャストするのが面倒でした。


追記:
.NET Framework 4.0 には Enumerable.Zip があったりして大分便利になってるようです。
4.0 は存在すら忘れてた・・・。