4匹のカエルが、左から番号の大きい順に葉の上に並んでいる。 このカエルを、番号の小さい順に並べ替えてほしい。 カエルは左右両隣の葉に飛び移ることができ、 また、もう1つ向こうの葉が空いている場合は、他のカエルを飛び越して移動することもできる。 ただし、1枚の葉に同時に2匹以上のカエルが乗ることはできない。 さて、カエルを指定した順に並び替えるにはどうすればよいだろうか? カエルの整列 : クイズ&パズルの部屋「Quizzical Days.」
using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
    private struct JyoutaiDef
    {
        internal int[] FrogArr;
        internal List<int[]> Log;
    }
    static void Main()
    {
        var que = new Queue<JyoutaiDef>();
        JyoutaiDef WillEnqueue;
        WillEnqueue.FrogArr = new int[5] { 4, 3, 2, 1, 0 };
        WillEnqueue.Log = new List<int[]>() { WillEnqueue.FrogArr };
        que.Enqueue(WillEnqueue);
        int MaxLevel = int.MaxValue;
        int AnswerCnt = 0;
        while (que.Count > 0) {
            JyoutaiDef Dequeued = que.Dequeue();
            if (MaxLevel < Dequeued.Log.Count) continue;
            if (Dequeued.FrogArr.SequenceEqual(new int[] { 1, 2, 3, 4, 0 })
             || Dequeued.FrogArr.SequenceEqual(new int[] { 0, 1, 2, 3, 4 })) {
                Console.WriteLine("解{0}を発見しました。", ++AnswerCnt);
                PrintFrogArrLog(Dequeued.Log);
                if (MaxLevel > Dequeued.Log.Count)
                    MaxLevel = Dequeued.Log.Count;
                continue;
            }
            int IndZero = Array.IndexOf<int>(Dequeued.FrogArr, 0);
            Action<int> EnqueSyori = (IndChanged) =>
            {
                WillEnqueue.FrogArr = (int[])Dequeued.FrogArr.Clone();
                WillEnqueue.FrogArr[IndZero] = WillEnqueue.FrogArr[IndChanged];
                WillEnqueue.FrogArr[IndChanged] = 0;
                //既存の配置だったら枝切り
                if (Dequeued.Log.Exists(X => X.SequenceEqual(WillEnqueue.FrogArr))) {
                    return;
                }
                WillEnqueue.Log = new List<int[]>(Dequeued.Log);
                WillEnqueue.Log.Add(WillEnqueue.FrogArr);
                que.Enqueue(WillEnqueue);
            };
            if (1 <= IndZero) EnqueSyori(IndZero - 1); //0の1つ左
            if (2 <= IndZero) EnqueSyori(IndZero - 2); //0の2つ左
            int UB = Dequeued.FrogArr.GetUpperBound(0);
            if (IndZero <= UB - 1) EnqueSyori(IndZero + 1); //0の1つ右
            if (IndZero <= UB - 2) EnqueSyori(IndZero + 2); //0の2つ右
        }
    }
    static void PrintFrogArrLog(List<int[]> pFrogArrLog)
    {
        int Level = 0;
        foreach (int[] AnyArr in pFrogArrLog) {
            Console.Write("LV{0,2}=", ++Level);
            foreach (int AnyInt in AnyArr) {
                Console.Write("{0},", AnyInt);
            }
            Console.WriteLine();
        }
    }
}
解1を発見しました LV 1=4,3,2,1,0, LV 2=4,3,2,0,1, LV 3=4,0,2,3,1, LV 4=0,4,2,3,1, LV 5=2,4,0,3,1, LV 6=2,4,1,3,0, LV 7=2,4,1,0,3, LV 8=2,0,1,4,3, LV 9=0,2,1,4,3, LV10=1,2,0,4,3, LV11=1,2,3,4,0, 解2を発見しました LV 1=4,3,2,1,0, LV 2=4,3,0,1,2, LV 3=4,0,3,1,2, LV 4=4,1,3,0,2, LV 5=4,1,3,2,0, LV 6=4,1,0,2,3, LV 7=0,1,4,2,3, LV 8=1,0,4,2,3, LV 9=1,2,4,0,3, LV10=1,2,0,4,3, LV11=1,2,3,4,0, 解3を発見しました LV 1=4,3,2,1,0, LV 2=4,3,0,1,2, LV 3=0,3,4,1,2, LV 4=3,0,4,1,2, LV 5=3,1,4,0,2, LV 6=3,1,4,2,0, LV 7=3,1,0,2,4, LV 8=0,1,3,2,4, LV 9=1,0,3,2,4, LV10=1,2,3,0,4, LV11=1,2,3,4,0, 解4を発見しました LV 1=4,3,2,1,0, LV 2=4,3,0,1,2, LV 3=4,3,1,0,2, LV 4=4,0,1,3,2, LV 5=0,4,1,3,2, LV 6=1,4,0,3,2, LV 7=1,4,2,3,0, LV 8=1,4,2,0,3, LV 9=1,0,2,4,3, LV10=1,2,0,4,3, LV11=1,2,3,4,0,
ListジェネリックのExistsメソッドの引数の、Predicateデリゲートで LINQのSequenceEqual拡張メソッドを使って枝切りしてます。 MSDN --- List<T>.Existsメソッド MSDN --- Enumerable.SequenceEqual<TSource>メソッド