私は数独パズルを解くクラスのためにcのプログラムに取り組んでいます。実装する方法は3つあります。最初に、選択肢が1つしかない各正方形に正しい数字を配置し、見つからなくなるまで繰り返します。次に、力ずくの力を使用して、各正方形に可能な限り少ない数を配置します。私はこれらの2つの方法を機能させています。最後の方法は、ブルートフォース機能の一部であるバックトラッキングを使用したブルートフォースです。通常のブルートフォースと同じように機能しますが、数字を配置できない正方形に到達すると、前の正方形に移動して次に大きい数字を配置します。これが実装されると、これは与えられたすべての数独パズルを解決するはずですが、これは私が問題を抱えているところです。
私は3つの方法すべてを実装しましたが、数独パズルの例をいくつか示しました。最初の「単一選択」方法のみを使用して解決できるものもあれば、「単一選択」と「ブルートフォースなし」のみを使用して解決できるものもあります。 「バックトラッキング」など、「単一選択」と「バックトラッキングによるブルートフォース」を使用するもの。私のプログラムは、「単一選択」パズルと「単一選択」および「バックトラックなしのブルートフォース」パズルの両方で機能します。ただし、「単一選択」および「バックトラックを伴うブルートフォース」パズルでは機能しません。
私が理解していない奇妙な部分は、バックトラックパズルの場合、ブルートフォース関数が呼び出される前にプログラムが動作を停止することです。
これが私の主な機能です:
#include <stdio.h>
#include "sudokusolver.h"
int main()
{
int puzzle[9][9], i, j, count, attempts=0, backTracks=0;
readSudoku(puzzle);
printf("a\n");
do
{
count=0;
for(i=0;i<9;i++)
{
for(j=0;j<9;j++)
{
if(singleCandidate(puzzle, i, j)==1)
count++;
}
}
}while(count!=0);
bruteForce(puzzle, &attempts, &backTracks);
printSudoku(puzzle);
return 0;
}
「printf( "a \ n")」を使用して、プログラムが機能しなくなる場所を示しました。
動作する出力の例を次に示します。これは、「単一選択」方式と「バックトラックなしのブルートフォース」を使用して機能する数独パズルの例です。ゼロはパズルの空白を表すことに注意してください。
Enter line 1: 010042000
Enter line 2: 008053010
Enter line 3: 900071560
Enter line 4: 400700600
Enter line 5: 067205130
Enter line 6: 002004005
Enter line 7: 080430001
Enter line 8: 030120700
Enter line 9: 000580090
a
315|642|987
678|953|412
924|871|563
-----------
453|718|629
867|295|134
192|364|875
-----------
786|439|251
539|126|748
241|587|396
そして、これは機能しない出力の例です。これは、「単一選択」と「バックトラックを伴うブルートフォース」を使用して解決する必要があるパズルの例です。
Enter line 1: 300910750
Enter line 2: 100570009
Enter line 3: 009000000
Enter line 4: 020740090
Enter line 5: 900000003
Enter line 6: 010069020
Enter line 7: 000000300
Enter line 8: 700085006
Enter line 9: 098034002
^C
プログラムは、無限ループにあるかのように実行を続け、^Cはプログラムを終了します。ご覧のとおり、プログラムは数独パズルを読み取る真下のprintf( "a")に到達することはなく、「バックトラックを伴うブルートフォース」関数を呼び出す前に、パズルだけであるため奇妙です。動作しないバックトラックを伴うブルートフォースを必要とします。
スタックしているように見えるreadSudoku関数は次のとおりです。
void readSudoku(int puzzle[][9])
{
int i, j;
for(i=0;i<9;i++)
{
printf("Enter line %d: ", i+1);
for(j=0;j<9;j++)
{
scanf("%1d", &puzzle[i][j]);
}
}
}
そして、これがバックトラッキングが実装されたブルートフォース機能です
void bruteForce(int puzzle[][9], int *attempt, int *backtracks)
{
int stable[9][9], i, j, k, found=0, temp=0;
for(i=0;i<9;i++)
{
for(j=0;j<9;j++)
{
if(puzzle[i][j]==0)
stable[i][j]=0;
else
stable[i][j]=1;
}
}
for(i=0;i<9;i++)
{
for(j=0;j<9;j++)
{
for(k=0;k<9;k++)
{
if(checkValid(puzzle, i, j, k+1)==1)
{
puzzle[i][j]=k+1;
break;
}
if(k==8)
break;
}
while(puzzle[i][j]==0)
{
found=0;
temp=j-1;
for(j=temp;j>=0;j--)
{
if(stable[i][j]==0)
{
found=1;
break;
}
}
temp=i-1;
if(found==0)
{
for(i=temp;i>=0;i--)
{
for(j=8;j>=0;j--)
{
if(stable[i][j]==0)
{
found=1;
break;
}
}
if(found==1)
break;
}
}
found=0;
temp=puzzle[i][j]+1;
for(k=temp;k<9;k++)
{
if(checkValid(puzzle, i, j, k+1)==1)
{
found=1;
puzzle[i][j]=k+1;
break;
}
}
if(found==0)
puzzle[i][j]=0;
}
}
}
}
これは非常に奇妙な問題であり、私にはまったく意味がありません。助けていただければ幸いです。