前回までの状況はこちら。
最新ソースはこちら(gitHub)
https://github.com/takishita2nd/sudoku
前回、仮置きロジックを完成させたのですが、
このコード、結構無駄な処理をやっていることに気がついたんですよ。
private Square doKarioki(Square[,] squares)
{
Square ret = null;
List<Square> kariokiList = searchKariokiSquare(squares);
foreach (var s in kariokiList)
{
bool roop = true;
int kariValue = GetUnconfirmedValue(s.GetCandidate());
if (kariValue == 0)
{
return null;
}
Square[,] copySquare = makeClone(squares);
copySquare[s.Row, s.Col].SetValue(kariValue);
int now_count = 0;
int prev_coount = 0;
while (roop)
{
for (int row = 0; row < 9; row++)
{
for (int col = 0; col < 9; col++)
{
if (copySquare[row, col].isConfirmed() == false)
{
Candidate candidate = new Candidate();
searchRowLine(copySquare, row, candidate);
searchColLine(copySquare, col, candidate);
search9Area(copySquare, row, col, candidate);
copySquare[row, col].checkCandidate(candidate);
}
}
}
searchNumber(copySquare);
if (checkContradict(copySquare))
{
break;
}
prev_coount = now_count;
now_count = countInputedNumber(copySquare);
if (prev_coount == now_count)
{
Console.WriteLine("仮置きロジック");
Square s2 = doKarioki(copySquare);
if (s2 == null)
{
Console.WriteLine("失敗しました");
return null;
}
else
{
copySquare[s2.Row, s2.Col].SetValue(s2.GetValue());
}
}
if (checkEnd(copySquare) == true)
{
★
roop = false;
s.SetValue(kariValue);
Console.WriteLine("[{0},{1}] = {2}", s.Row, s.Col, s.GetValue());
ret = s;
}
FileAccess.Output(copySquare);
}
if(ret != null)
{
break;
}
}
return ret;
}
今までは★に入ったタイミングで仮置きした値が確定して、という処理を行っていたんですが、
実はここに入った時点で解析結果が判明しているんですよね。
なので、この時点で解析結果を出力して終了、という処理にすれば、大幅に処理が短くなるはずです。
詳細はgitHubのソースコードを参照して頂ければ。
ついでに関数ヘッダにコメント入れました。