トップページに戻る    次のC#のサンプルへ    前のC#のサンプルへ

8-20 同じところを2度通らない道順の数

問題

同じところを2度通らない道順の数を求めます。
5*5を対象とします。


ソース

using System;
using System.Collections.Generic;

class Program
{
    internal struct JyoutaiDef
    {
        internal int X;
        internal int Y;
        internal string Path;
    }

    static internal Stack<JyoutaiDef> stk = new Stack<JyoutaiDef>();

    static void Main()
    {
        var sw = System.Diagnostics.Stopwatch.StartNew();

        const int MaxHaba = 5;
        JyoutaiDef WillPush;
        WillPush.X = 0; WillPush.Y = 0; WillPush.Path = "(0,0)";
        stk.Push(WillPush);

        int AnsCnt = 0;
        while (stk.Count > 0) {
            JyoutaiDef Popped = stk.Pop();

            if (Popped.X == MaxHaba && Popped.Y == MaxHaba) {
                AnsCnt++;
                if (AnsCnt % 20000 == 1) {
                    Console.WriteLine("{0}番目の解を発見。経過時間={1}", AnsCnt, sw.Elapsed);
                }
                //Console.WriteLine("解{0,2}={1}", AnsCnt, Popped.Path);
                continue;
            }

            Action<int, int> WillAct = (pX, pY) =>
            {
                string wk = string.Format("({0},{1})", pX, pY);
                if (Popped.Path.Contains(wk) == false) {
                    WillPush.X = pX; WillPush.Y = pY;
                    WillPush.Path = Popped.Path + wk;
                    stk.Push(WillPush);
                }
            };

            //右に移動
            if (Popped.X < MaxHaba) WillAct(Popped.X + 1, Popped.Y);
            //左に移動
            if (Popped.X > 0) WillAct(Popped.X - 1, Popped.Y);
            //上に移動
            if (Popped.Y > 0) WillAct(Popped.X, Popped.Y - 1);
            //下に移動
            if (Popped.Y < MaxHaba) WillAct(Popped.X, Popped.Y + 1);
        }
        Console.WriteLine("解は{0}通り", AnsCnt);
    }
}


実行結果

省略
1100001番目の解を発見。経過時間=00:02:47.5337818
1120001番目の解を発見。経過時間=00:02:50.7611193
1140001番目の解を発見。経過時間=00:02:53.8056680
1160001番目の解を発見。経過時間=00:02:56.8356774
1180001番目の解を発見。経過時間=00:02:59.8056778
1200001番目の解を発見。経過時間=00:03:03.2683332
1220001番目の解を発見。経過時間=00:03:05.6223771
1240001番目の解を発見。経過時間=00:03:08.5595325
1260001番目の解を発見。経過時間=00:03:11.0246958
解は1262816通り


解説

ローカル変数のActionデリゲートでサブルーチンを定義して、
複数回使用するのは、便利だと気付きました。

メソッドを作った場合は、変数を渡す必要があるのに対して、
ラムダ式だと上位の変数のキャプチャ機能もありますし