using System; using System.Collections.Generic; class Program { struct JyouraiDef { internal int CurrP; internal Dictionary<char, int> NumDict; } static void Main() { // READ // WRITE // TALK //+----- // SKILL //として下位の桁から求める const string QuestionStr = "DEKL" + "ATLL" + "EIAI" + "ERTK" + "WS"; int UB = QuestionStr.Length - 1; var stk = new Stack<JyouraiDef>(); JyouraiDef WillPush; WillPush.CurrP = 0; WillPush.NumDict = new Dictionary<char, int>(); stk.Push(WillPush); var AnswerList = new List<string>(); while (stk.Count > 0) { JyouraiDef Popped = stk.Pop(); //Console.WriteLine(Popped.CurrP); //クリア判定 if (Popped.CurrP > UB) { AnswerList.Add(DeriveAnswerStr(Popped.NumDict)); continue; } Action PushSyori = () => { if (WillEdakiri(WillPush)) return; stk.Push(WillPush); }; char CurrChar = QuestionStr[Popped.CurrP]; WillPush.CurrP = Popped.CurrP + 1; if (Popped.NumDict.ContainsKey(CurrChar)) { WillPush.NumDict = Popped.NumDict; PushSyori(); } else { for (int I = 0; I <= 9; I++) { if (Popped.NumDict.ContainsValue(I)) continue; //前ゼロは不可 if (CurrChar == 'R' && I == 0) continue; if (CurrChar == 'W' && I == 0) continue; if (CurrChar == 'T' && I == 0) continue; //S != Wを満たせない場合はNG if (CurrChar == 'W' && I == 9) continue; WillPush.NumDict = new Dictionary<char, int>(Popped.NumDict); WillPush.NumDict.Add(CurrChar, I); PushSyori(); } } } Console.WriteLine("解は{0}通り", AnswerList.Count); AnswerList.Sort(); AnswerList.ForEach(X => Console.WriteLine(X)); } static bool WillEdakiri(JyouraiDef pWillPush) { //1の位の和を返す Func<int> FuncSum1 = () => { int wkSum = 0; wkSum += pWillPush.NumDict['D']; wkSum += pWillPush.NumDict['E']; wkSum += pWillPush.NumDict['K']; return wkSum; }; //10の位の和を返す Func<int> FuncSum10 = () => { int wkSum = 0; wkSum += pWillPush.NumDict['A'] * 10; wkSum += pWillPush.NumDict['T'] * 10; wkSum += pWillPush.NumDict['L'] * 10; return wkSum; }; //100の位の和を返す Func<int> FuncSum100 = () => { int wkSum = 0; wkSum += pWillPush.NumDict['E'] * 100; wkSum += pWillPush.NumDict['I'] * 100; wkSum += pWillPush.NumDict['A'] * 100; return wkSum; }; //1000の位の和を返す Func<int> FuncSum1000 = () => { int wkSum = 0; wkSum += pWillPush.NumDict['R'] * 1000; wkSum += pWillPush.NumDict['R'] * 1000; wkSum += pWillPush.NumDict['T'] * 1000; return wkSum; }; //10000の位の和を返す Func<int> FuncSum10000 = () => { int wkSum = 0; wkSum += pWillPush.NumDict['W'] * 10000; return wkSum; }; //1桁目の和をチェック if (pWillPush.CurrP == 4) { int wkSum = FuncSum1(); if (wkSum % 10 != pWillPush.NumDict['L']) return true; } //10桁目の和をチェック if (pWillPush.CurrP == 8) { int wkSum = FuncSum1() + FuncSum10(); if (wkSum % 100 != pWillPush.NumDict['L'] * (10 + 1)) return true; } //100桁目の和をチェック if (pWillPush.CurrP == 12) { int wkSum = FuncSum1() + FuncSum10() + FuncSum100(); int wkResult = pWillPush.NumDict['L'] * (10 + 1); wkResult += pWillPush.NumDict['I'] * 100; if (wkSum % 1000 != wkResult) return true; } //1000桁目の和をチェック if (pWillPush.CurrP == 16) { int wkSum = FuncSum1() + FuncSum10() + FuncSum100() + FuncSum1000(); int wkResult = pWillPush.NumDict['L'] * (10 + 1); wkResult += pWillPush.NumDict['I'] * 100; wkResult += pWillPush.NumDict['K'] * 1000; if (wkSum % 10000 != wkResult) return true; } //10000桁目の和をチェック if (pWillPush.CurrP == 18) { int wkSum = FuncSum1() + FuncSum10() + FuncSum100() + FuncSum1000() + FuncSum10000(); int wkResult = pWillPush.NumDict['L'] * (10 + 1); wkResult += pWillPush.NumDict['I'] * 100; wkResult += pWillPush.NumDict['K'] * 1000; wkResult += pWillPush.NumDict['S'] * 10000; if (wkSum != wkResult) return true; } return false; } //解をString型に変換 static string DeriveAnswerStr(Dictionary<char, int> pNumDict) { var sb = new System.Text.StringBuilder(); Func<char, int> wkFunc = pChar => pNumDict[pChar]; sb.AppendFormat("{0}{1}{2}{3}+", wkFunc('R'), wkFunc('E'), wkFunc('A'), wkFunc('D')); sb.AppendFormat("{0}{1}{2}{3}{4}+", wkFunc('W'), wkFunc('R'), wkFunc('I'), wkFunc('T'), wkFunc('E')); sb.AppendFormat("{0}{1}{2}{3}=", wkFunc('T'), wkFunc('A'), wkFunc('L'), wkFunc('K')); sb.AppendFormat("{0}{1}{2}{3}{4}", wkFunc('S'), wkFunc('K'), wkFunc('I'), wkFunc('L'), wkFunc('L')); return sb.ToString(); } }