Example #1
0
void Grid::solveRand(){
	std::cout << std::endl << "solving" << std::endl;
	int wordsDone = 0;
	std::vector<int> wordsDone_v;
	int solveCount = 0;
	int rand_int = 0;
	this->print();

	while (!this->isDone()){
		//std::cout << "Solving " <<	solveCount << std::endl;
		rand_int = rand() % 100; // 0 - 99
		if (rand_int < PERCENTFWD) wordsDone = solveForward();
		else if (rand_int < PERCENTBWD) wordsDone = solveBackward(); 
		else if (rand_int < PERCENTBIG) wordsDone = solveBigWords();
		else if (rand_int < PERCENTSMALL) wordsDone = solveSmallWords();
		else if (rand_int < PERCENTCLEAR) {	clearAroundBlank(); wordsDone = 0; }
		else if (rand_int < PERCENTCLEARL) { clearAroundBlankLarge(); wordsDone = 0; }
		else throw  1; // Should never happen
		wordsDone_v.push_back(wordsDone);
		std::cout << solveCount << " " << wordsDone << " " << rand_int << std::endl;
		if (solveCount % 10 == 0){
			this->print();
		}
		if (solveCount == 10000) {
			std::cout << "After 10000 attempts no solution was found. Sorry!" << std::endl;
			throw (-1);
		}
		solveCount++;
	} // END OF WHILE LOOP

	// if there are any empty cells - fill them with a word from the dictionary. This cells are not counted as words because they are an '_' surrounded by # or edges. In other words, they are single character long
	for (int ii = 0; ii<mychars.size(); ii++){
		if (mychars[ii].getChar() == '_') mychars[ii].setChar('a'); // a is a word in the dictionary
	}
}
Example #2
0
void Grid::solve(){
	std::cout << std::endl << "solving" << std::endl;
	int wordsDone = 0;
	std::vector<int> wordsDone_v;
	int solveCount = 0;
	int patternSetting = 16;
	this->print();
	while (!this->isDone()){
		//std::cout << "Solving " <<	solveCount << std::endl;
		switch (solveCount % patternSetting) {
		case 0:
		case 6:
			wordsDone = solveBigWords();
			break;
		case 11:
			wordsDone = solveSmallWords();
			break;
		case 3:
		case 8:
		case 13:
			wordsDone = solveBackward();
			break;
		case 5:
		case 10:
			//clearAroundBlank();
			wordsDone = 0;
			break;
		case 15:
			//this->print();
			clearAroundBlankLarge();
			patternSetting+=7;
			wordsDone = 0;
			for (int ii = 0; ii < wordsDone_v.size(); ii++)
				//std::wcout << " " << wordsDone_v[ii];
			//std::wcout << std::endl;
			wordsDone_v.clear();
			break;
		default:
			wordsDone = solveForward();
			break;
		}
		wordsDone_v.push_back(wordsDone);
		std::cout << solveCount << " " << wordsDone << std::endl;
     	this->print();  //}
		//std::cout << "\tWords done " << wordsDone << std::endl;
		if (solveCount == 10000) {
			std::cout << "After 10000 attempts no solution was found. Sorry!" << std::endl;
			throw (-1);
		}
		solveCount++;
	} // END OF WHILE LOOP

	// if there are any empty cells - fill them with a word from the dictionary. This cells are not counted as words because they are an '_' surrounded by # or edges. In other words, they are single character long
	for (int ii = 0; ii<mychars.size(); ii++){
		if (mychars[ii].getChar() == '_') mychars[ii].setChar('a'); // a is a word in the dictionary
	}
}
Example #3
0
void Sudoku::solve()//沒有輸入,輸出解答(OK)
{
	//寫一個檢查程序,看是否題目有誤變成無解
	bool nums[10];
	
	for(int i=0; i<=8; i++)
	{
		for(int j=0; j<=8; j++)
		{
			if(sudokuBoard[i][j]==0)
			{
				//cout<<"開始檢查("<<i<<","<<j<<")"<<endl;
				//先找一格,然後從row,column,cell看是否有不合理之處
				
				//先初始化陣列都為false
				//cout<<"先初始化nums陣列"<<endl;
				for(int k=1; k<=9; k++)
				{
					nums[k]=false;
					//cout<<nums[k];
				}
				//cout<<endl;
				
				//然後用row填入我們的候選數裡面
				//cout<<"開始在row上找"<<endl;
				for(int k=0; k<=8; k++)
				{
					if(sudokuBoard[i][k]!=0)//如果找到一格已經有數字的格子的話
					{
						//cout<<"在"<<i<<","<<k<<"發現了數字"<<sudokuBoard[i][k]<<endl;
						if(nums[sudokuBoard[i][k]]==true)//可是該數字已經出現過了,代表矛盾
						{
							
							//cout<<"矛盾,數字"<<sudokuBoard[i][k]<<"已經出現過了"<<endl;
							cout<<0;
							return;
						}
						else//如果該數字還沒出現過,我們就紀錄他出現了
						{
							//cout<<"該數字還沒出現過!"<<endl;
							nums[sudokuBoard[i][k]]=true;
						}
					}
				}
				
				//cout<<"先初始化nums陣列"<<endl;
                                for(int k=1; k<=9; k++)
                                {
                                        nums[k]=false;
                                        //cout<<nums[k];
                                }
                                //cout<<endl;
				//接下來用column填入我們的候選數裡面
				//cout<<"開始在column上找"<<endl;
				for(int k=0; k<=8; k++)
				{
					if(sudokuBoard[k][j]!=0)
					{
						//cout<<"在"<<k<<","<<j<<"發現了數字"<<sudokuBoard[k][j]<<endl;
						if(nums[sudokuBoard[k][j]]==true)
						{
							//cout<<"矛盾,數字"<<sudokuBoard[k][j]<<"已經出現過了"<<endl;
							cout<<0;
							return;
						}
						else
						{
							//cout<<"該數字還沒出現過!"<<endl;
							nums[sudokuBoard[k][j]]=true;
						}
					}
				}
				

				//cout<<"先初始化nums陣列"<<endl;
                                for(int k=1; k<=9; k++)
                                {
                                        nums[k]=false;
                                        //cout<<nums[k];
                                }
                                //cout<<endl;
				//接下來用cell填入我們的候選數裡面
				//cout<<"開始在cell上找"<<endl;
				for(int k=i-i%3; k<=(i-i%3)+2; k++)
				{
					for(int l=j-j%3; l<=(j-j%3)+2; l++)
					{
						if(sudokuBoard[k][l]!=0 && (k!=i) && (l!=j))
						{
							//cout<<"在"<<i<<","<<k<<"發現了數字"<<sudokuBoard[i][k]<<endl;
							if(nums[sudokuBoard[k][l]]==true)
							{
								//cout<<"矛盾,數字"<<sudokuBoard[k][l]<<"已經出現過了"<<endl;
								cout<<0;
								return;
							}
							else
							{
								//cout<<"該數字還沒出現過!"<<endl;
								nums[sudokuBoard[k][l]]=true;
							}
						}
					}
				}
			}
		}
	}



	int resultF,resultB;

	for(int c=0; c<=8; c++)
	{
		for(int d=0; d<=8; d++)
		{
			forwardAns[c][d]=sudokuBoard[c][d];
			backwardAns[c][d]=sudokuBoard[c][d];
		}
	}
	
	//先執行solveForward();
	recursiveTimes=0;
	resultF=solveForward();
	if(resultF==-1)
	{
		cout<<0;
		return;
	}
	
	
	//再執行solveBackward();
	recursiveTimes=0;
	resultB=solveBackward();
	//cout<<"用solveBackward結果為"<<resultB<<endl;
	//cout<<"打印backwardAns"<<endl;
	/*
	for(int c=0; c<=8; c++)
	{
		for(int d=0; d<=8; d++)
		{
			cout<<backwardAns[c][d];
		}
		cout<<endl;
	}
	*/
	
	bool isSame;
	isSame=true;
	
	for(int c=0; c<=8; c++)
	{
		for(int d=0; d<=8; d++)
		{
			if(forwardAns[c][d]!=backwardAns[c][d])
			{
				cout<<2;
				return;
			}
		}
	}
	cout<<1<<endl;
	
	for(int c=0; c<=8; c++)
        {
                for(int d=0; d<=8; d++)
                {
			cout<<backwardAns[c][d]<<" ";
                }
                cout<<endl;
        }
	
	
		
}
Example #4
0
int Sudoku::solveForward()
{
	if(recursiveTimes==100)
	{
		exit(0);
	}
	
	justFailed=false;

	bool candidate[10];//候選數的陣列,1~9代表1~9,0我們不使用

	for(int i=1; i<=9; i++)
	{
		candidate[i]=false;
	}		

	for(int i=0; i<=8; i++)//代表row
	{
		for(int j=0; j<=8; j++)//代表column
		{
			if(forwardAns[i][j]==0)
			{

				//cout<<"找到一個待填空格("<<i<<"'"<<j<<")"<<endl;

				//如果找到一個空格,就開始確認候選數
				for(int k=0; k<=8; k++)//在同一row上做搜尋,如果找到某數字,candidate上就寫true
                                {
                                        if(forwardAns[i][k]!=0)
                                        {
                                                candidate[forwardAns[i][k]]=true;
                                        }
                                }
				
				for(int k=0; k<=8; k++)//在同一column上做搜尋,如果找到某數字,candidate上就寫true
                                {
                                        if(forwardAns[k][j]!=0)
                                        {
                                                candidate[forwardAns[k][j]]=true;
                                        }
                                }

				for(int k=(i-i%3); k<=((i-i%3)+2); k++)//在所在的cell上面做搜尋,如果找到某數字,candidate上就寫true
                                {
                                        for(int l=(j-j%3); l<=((j-j%3)+2); l++)
                                        {
                                                if(forwardAns[k][l]!=0)
                                                {
                                                        candidate[forwardAns[k][l]]=true;
                                                }
                                        }
                                }

				//cout<<"輸出candidate陣列檢查";
				
				/*
				for(int k=1; k<=9; k++)
				{
					cout<<candidate[k];	
				}
				cout<<endl;
				*/		
				
                                LastRecursiveFailed:
				
				if(justFailed==true)
				{

					//cout<<"剛剛失敗了"<<endl;

					candidate[justPicked[recursiveTimes]]=true;
				}
				
				
				int countCandidate;
				countCandidate=0;
				for(int k=1; k<=9; k++)
				{
					if(candidate[k]==true)
					{
						countCandidate++;
					}
				}
				if(countCandidate==9)//如果9個數字全都存在了,代表該題可能無解或是之前填錯
				{

					//cout<<"發現矛盾"<<endl;

					forwardAns[i][j]=0;
					return -1;//所以無解的題目,他會return-1
				}
				
				
				//cout<<"現在開始找一個測試數填入"<<endl;

				for(int k=1; k<=9; k++)
				{

					//cout<<"進入迴圈第"<<k<<"次"<<endl;

					if(candidate[k]!=true)//如果某號候選數,還沒出現的話
					{
						forwardAns[i][j]=k;//我們就試著把該格填上其中一個候選數
						
						//cout<<"試著在"<<i<<","<<j<<"填入"<<k<<endl;

						justPicked[recursiveTimes]=k;//我們在第幾次遞迴,測試了某個數字
						justFailed=false;
						int count;
						count=0;
						for(int a=0; a<=8; a++)
						{
							for(int b=0; b<=8; b++)
							{
								if(forwardAns[a][b]!=0)
								{
									count++;
								}
							}
						}
						if(count==81)
						{
							return 1;
						}

					}else
					{
						continue;
					}


					/*
					我們填完一個測試數之後,就在執行下一次
					如果下一次return 1的話,代表出現矛盾,這邊我們就要把剛剛挑的數字( justPicked[recursiveTimes] )
					在candidate[]裡面變成true,不讓我們填他,並再次執行當次的遞迴
					*/
					recursiveTimes++;
					int result;
					result=solveForward();

					//cout<<"solve執行完畢"<<endl;
					//cout<<"result目前為"<<result<<endl;

					if(result==-1)
					{

						//cout<<"接到矛盾消息,該重新執行當次迴圈"<<endl;

						recursiveTimes--;
						justFailed=true;

						//cout<<"更新justFailed為true"<<endl;

						goto LastRecursiveFailed;	
					}
					else if(result==1)
					{
						return 1;
					}					
				}
			}	
		}
	}
}