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();
}
}