下の図に1〜3までの自然数を1つずつ入れるパズルです。 下の段にある○の中には、すぐ上にある2つの○の中にある数字の差が入ります。 同じ数字は1回しか使えません。
using System; using System.Linq; using System.Collections.Generic; class Program { const int husaCnt = 6; struct JyoutaiDef { internal int Level; internal int[] IntArr; } static void Main() { var stk = new Stack<JyoutaiDef>(); JyoutaiDef WillPush; WillPush.Level = 1; for (int I = 1; I <= husaCnt; I++) { WillPush.IntArr = new int[husaCnt]; WillPush.IntArr[0] = I; stk.Push(WillPush); } while (stk.Count > 0) { JyoutaiDef Popped = stk.Pop(); if (Popped.Level == husaCnt) { string WillOut = ""; foreach (int each in Popped.IntArr) { WillOut += each.ToString() + ","; } Console.WriteLine("Answer={0}", WillOut); continue; } WillPush.Level = Popped.Level + 1; for (int I = 1; I <= husaCnt; I++) { if (Popped.IntArr.Any(X => X == I)) continue; WillPush.IntArr = (int[])Popped.IntArr.Clone(); WillPush.IntArr[WillPush.Level - 1] = I; if (IsValid(WillPush)) { stk.Push(WillPush); } } } } static bool IsValid(JyoutaiDef pJyoutai) { int[] wkArrP = pJyoutai.IntArr; if (wkArrP[3] != 0 && wkArrP[0] != 0 && wkArrP[1] != 0) { if (wkArrP[3] != Math.Abs(wkArrP[0] - wkArrP[1])) return false; } if (wkArrP[4] != 0 && wkArrP[1] != 0 && wkArrP[2] != 0) { if (wkArrP[4] != Math.Abs(wkArrP[1] - wkArrP[2])) return false; } if (wkArrP[5] != 0 && wkArrP[3] != 0 && wkArrP[4] != 0) { if (wkArrP[5] != Math.Abs(wkArrP[3] - wkArrP[4])) return false; } return true; } }
Answer=6,2,5,4,3,1, Answer=6,1,4,5,3,2, Answer=5,6,2,1,4,3, Answer=5,2,6,3,4,1, Answer=4,6,1,2,5,3, Answer=4,1,6,3,5,2, Answer=2,6,5,4,1,3, Answer=1,6,4,5,2,3,
LINQのAny拡張メソッドを使ってみましたが、 LINQのContains拡張メソッドを使うか、 Array.IndexOfジェネリックメソッドを使うほうが良さそうだと後で気付きました・・・ MSDN --- Array.IndexOf(T) メソッド