What would be the time complexity of solution to this problem? - c++
Question:
https://www.spoj.com/problems/BALNUM/
My Solution:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
string s;
vector<ll>v;
ll dp[20][2][3][3][3][3][3][3][3][3][3][3][2];
ll solve(ll i,ll less,ll start,ll m0,ll m1,ll m2,ll m3,ll m4,ll m5,ll m6,ll m7,ll m8,ll m9){
if(i == s.size()){
if((m1 == 2 or m1 == 0) and (m3 == 2 or m3 == 0) and (m5 == 2 or m5 == 0) and (m7 == 2 or m7 == 0) and (m9 == 2 or m9 == 0) and (m0 == 1 or m0 == 0) and (m2 == 1 or m2 == 0) and (m4 == 1 or m4 == 0) and (m6 == 1 or m6 == 0) and (m8 == 1 or m8 == 0)){
return 1;
}
return 0;
}
ll &ret = dp[i][less][m0][m1][m2][m3][m4][m5][m6][m7][m8][m9][start];
if(ret != -1) return ret;
ll k = less ? 9 : v[i];
ll ans = 0;
for(ll j = 1; j <= k; j++){
if(j == 1){
ans += solve(i+1,less | (j < v[i]),0,m0,((m1+1)%3 == 0) ? 1:(m1+1)%3,m2,m3,m4,m5,m6,m7,m8,m9);
}else if(j == 2){
ans += solve(i+1,less | (j < v[i]),0,m0,m1,((m2+1)%3 == 0) ? 1:(m2+1)%3,m3,m4,m5,m6,m7,m8,m9);
}else if(j == 3){
ans += solve(i+1,less | (j < v[i]),0,m0,m1,m2,((m3+1)%3 == 0) ? 1:(m3+1)%3,m4,m5,m6,m7,m8,m9);
}else if(j == 4){
ans += solve(i+1,less | (j < v[i]),0,m0,m1,m2,m3,((m4+1)%3 == 0) ? 1:(m4+1)%3,m5,m6,m7,m8,m9);
}else if(j == 5){
ans += solve(i+1,less | (j < v[i]),0,m0,m1,m2,m3,m4,((m5+1)%3 == 0) ? 1:(m5+1)%3,m6,m7,m8,m9);
}else if(j == 6){
ans += solve(i+1,less | (j < v[i]),0,m0,m1,m2,m3,m4,m5,((m6+1)%3 == 0) ? 1:(m6+1)%3,m7,m8,m9);
}else if(j == 7){
ans += solve(i+1,less | (j < v[i]),0,m0,m1,m2,m3,m4,m5,m6,((m7+1)%3 == 0) ? 1:(m7+1)%3,m8,m9);
}else if(j == 8){
ans += solve(i+1,less | (j < v[i]),0,m0,m1,m2,m3,m4,m5,m6,m7,((m8+1)%3 == 0) ? 1:(m8+1)%3,m9);
}else if(j == 9){
ans += solve(i+1,less | (j < v[i]),0,m0,m1,m2,m3,m4,m5,m6,m7,m8,((m9+1)%3 == 0) ? 1:(m9+1)%3);
}
}
if(!start){
ans += solve(i+1,less | (0 < v[i]),0,((m0+1)%3 == 0) ? 1:(m0+1)%3,m1,m2,m3,m4,m5,m6,m7,m8,m9);
}
if(start){
ans += solve(i+1,1,1,0,0,0,0,0,0,0,0,0,0);
}
return ret = ans;
}
int main(){
ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
ll t;
cin>>t;
while(t--){
ll x;
cin>>x;
--x;
s = to_string(x);
memset(dp,-1,sizeof(dp));
v.clear();
for(char c:s) v.push_back(c-'0');
ll a=solve(0,0,1,0,0,0,0,0,0,0,0,0,0);
cin>>s;
memset(dp,-1,sizeof(dp));
v.clear();
for(char c:s) v.push_back(c-'0');
ll b=solve(0,0,1,0,0,0,0,0,0,0,0,0,0);
cout<<b-a<<endl;
}
}
Here the array i use for memoization is dp[20][2][3][3][3][3][3][3][3][3][3][3][2] (20 is max length of integer A or B)
Is the time complexity O(n) with a very high constant (like 2*3*3*3*3*3*3*3*3*3*3*2) where n is max length of integer A or B?
Its T * ( N * (2^2 * 3^10 * 9) + C ), The constant factor is really huge, but overall i think you can say that the time complexity is T * N * (a huge constant factor).
So you could say its O(T*N).
Related
DiceSum - How to extend if/ if-else statement to reroll dice if dice sum is not a certain number
#include <iostream> #include <ctime> #include <cstdlib> #include <iomanip> using namespace std; int main() { int n; int win = 0; int lose = 0; int dice1; int dice2; int diceSum; srand(time(0)); cout << "How many turns would you like? "; cin >> n; for (int i = 1; i <= n; i++) { dice1 = rand()%6 + 1; dice2 = rand()%6 + 1; diceSum = dice1 + dice2; if((diceSum == 2) || (diceSum == 3) || (diceSum == 12)){ win++; } else if((diceSum == 7) || (diceSum == 11)){ lose++; } else{ } } cout << "No. of Wins: " << win << endl; cout << "No. of Losses: " << lose << endl; cout<< setprecision(4)<<fixed<<showpoint; cout << "\nThe experimental probability of winning "<< (static_cast<float>(win)/n)*100 << "%.\n"; return 0; } My assignments states that "...can be shown analytically that the long term probability of winning the dice game you have programmed in PA 8-3 is .4929293. Extend that program you wrote to run a large number of turns and calculate the empirical (experimental) probability." My last assignment I had to make a program to roll two die and reveal the dice sum. If it was a 2, 3, or 12, I won; if it was a 7 or 11 it was a loss, otherwise it would repeat the roll. I was unable to repeat the roll, now for this assignment, I have to do the same thing.This is my output from my current code
I you want to not take into account the cases where the sum is not 2,3,12,7 or 11 you have lot of possibilities, for instance : closer to your code do i -=1; in the empty else {} for (int i = 1; i <= n; i++) { dice1 = rand()%6 + 1; dice2 = rand()%6 + 1; diceSum = dice1 + dice2; if((diceSum == 2) || (diceSum == 3) || (diceSum == 12)){ win++; } else if((diceSum == 7) || (diceSum == 11)){ lose++; } else{ i -= 1; } } or increment i only when you win or lose and remove i++ in the for() for (int i = 1; i <= n;) { dice1 = rand()%6 + 1; dice2 = rand()%6 + 1; diceSum = dice1 + dice2; if((diceSum == 2) || (diceSum == 3) || (diceSum == 12)){ win++; i++; } else if((diceSum == 7) || (diceSum == 11)){ lose++; i++; } } or the variant i = n; for (;;) { dice1 = rand()%6 + 1; dice2 = rand()%6 + 1; diceSum = dice1 + dice2; if((diceSum == 2) || (diceSum == 3) || (diceSum == 12)){ win++; if (!--i) break; } else if((diceSum == 7) || (diceSum == 11)){ lose++; if (!--i) break; } } or remove all about i and replace your for by do { dice1 = ..... } while ((win + lose) != n); without having the last else branch do { dice1 = rand()%6 + 1; dice2 = rand()%6 + 1; diceSum = dice1 + dice2; if((diceSum == 2) || (diceSum == 3) || (diceSum == 12)){ win++; } else if((diceSum == 7) || (diceSum == 11)){ lose++; } } while ((win + lose) != n); or the variant for (;;) { dice1 = rand()%6 + 1; dice2 = rand()%6 + 1; diceSum = dice1 + dice2; if((diceSum == 2) || (diceSum == 3) || (diceSum == 12)){ if ((++win + lose) == n) break; } else if((diceSum == 7) || (diceSum == 11)){ if ((++lose + win) == n) break; } } Example of execution whatever the way : pi#raspberrypi:/tmp $ ./a.out How many turns would you like? 1000 No. of Wins: 336 No. of Losses: 664 The experimental probability of winning 33.6000%. This result it normal even it seems opposite of the intuition because the possibilities to make these numbers are : 2 : 1+1 3 : 1+2 2+1 12 : 6+6 and 7: 1+6 6+1 2+5 5+2 3+4 4+3 11 : 5+6 6+5 so 4 possibilities to win ( 1/3/12 ) and 8 possibilities to lose ( 7/11 ), so the probability to lose if two times more than the probability to win I encourage you to always check the input, replacing cin >> n; by something like if (!(cin >> n)) { cerr << "invalid number" << endl; return -1; }
Watershed implementation in C++
I'm working in the watershed algortih in C++. I have implemented a source that i've found but i didn't get the expected results. I obtain: [ But the result should be this: [ I have charge the image .bmp into a matrix an then i obtain the Gradient of the image using the Sobel operator. My wathershed algorith now is: void Watershed() { stack<punto> s; punto p, neighbour; C_Matrix prueba3 (Gradiente.FirstRow(), Gradiente.LastRow(), Gradiente.FirstCol(), Gradiente.LastCol(), -1); int auxU, auxV, Eaux, L=1; for (double g = Gradiente.Min(); g <= Gradiente.Max(); g++) { for (int i = Gradiente.FirstRow(); i <= Gradiente.LastRow(); i++) { for (int j = Gradiente.FirstCol(); j <= Gradiente.LastCol(); j++) { if (Gradiente(i, j) == g) { p.Guarda(i, j); s.push(p); } while (s.empty() == 0) { p = s.top(); s.pop(); auxU = p.x; auxV = p.y; Eaux = -1; // 8-connectivity for (int i = 0; i < 8; i++) { if (i == 0) neighbour.Guarda(auxU - 1, auxV - 1); else if (i == 1) neighbour.Guarda(auxU, auxV - 1); else if (i == 2) neighbour.Guarda(auxU + 1, auxV - 1); else if (i == 3) neighbour.Guarda(auxU - 1, auxV); else if (i == 4) neighbour.Guarda(auxU + 1, auxV); else if (i == 5) neighbour.Guarda(auxU - 1, auxV + 1); else if (i == 6) neighbour.Guarda(auxU, auxV + 1); else neighbour.Guarda(auxU + 1, auxV + 1); if (neighbour.x >= Gradiente.FirstRow() && neighbour.x <= Gradiente.LastRow() && neighbour.y >= Gradiente.FirstCol() && neighbour.y <= Gradiente.LastCol()) { if (prueba3(neighbour.x, neighbour.y) > 0) { if (Eaux == -1) { Eaux = prueba3(neighbour.x, neighbour.y); } else if (prueba3(neighbour.x, neighbour.y) != Eaux) Eaux = 0; } } } if (auxU >= Gradiente.FirstRow() && auxU <= Gradiente.LastRow() && auxV >= Gradiente.FirstCol() && auxV <= Gradiente.LastCol()) { if (Eaux >= 0) { prueba3(auxU, auxV) = Eaux; } else { prueba3(auxU, auxV) = L; L++; } } else { C_Print("Se sale"); C_PrintNum("AuxU", auxU); C_PrintNum("AuxV", auxV); } } } } } C_PrintNum("L = ", L); double max = prueba3.Max(); if (max > 255.0) { prueba3.Stretch(0, 255); } aux = C_Image(prueba3); } I don't know where is the fail, maybe my source has mistakes.
Replace if else with a for loop?
I have: if (a[i] == 1) { howMany[1] += 1; } else if (a[i] == 2) { howMany[2] += 1; } else if (a[i] == 3) { howMany[3] += 1; } else if (a[i] == 4) { howMany[4] += 1; } else if (a[i] == 5) { howMany[5] += 1; } else if (a[i] == 6) { howMany[6] += 1; } else if (a[i] == 7) { howMany[7] += 1; } else if (a[i] == 8) { howMany[8] += 1; } else if (a[i] == 9) { howMany[9] += 1; } I want to replace it with something like: if (a[i] == 1 || a[i] == 2 <-- etc) { howMany[i] += 1; } But that doesn't work. Anybody has a clue? This is C++, but I've experienced the same issue in Python, so I don't think it's a language issue but rather just a general problem.
If you are sure that the range of a is from one to nine you can simply write howMany[a[i]]++; otherwise you will need one if statement if(a[i] >= 1 && a[i] <= 9) howMany[a[i]]++;
how about howMany[a[i]] += 1; since you are always accessing the element of howMany based on the value of a[i]
Lets look at what you are doing if (a[i] == 1) { howMany[1] += 1; } So if a[i] is 1 then you want to increment the value of howMany[1]. Since a[i] == 1 and index of howMany == 1 then all you need is howMany[a[i]] += 1;
You need to use: howMany[a[i]] += 1; (or ++ rather than += 1) inside the if statement (not a loop, by the way) since a[i] is the variable holding 1, 2, etc. Your new if statement could also be simplified to something like: if ((a[i] >= 1) && (a[i] <= 9)) ...
Algorithm to calculate sum of LUCKY FACTOR in given range
Problem Statement :- A number is given, N, which is given in binary notation, and it contains atmost 1000000 bits. You have to calculate the sum of LUCKY FACTOR in range from 1 to N (decimal notation). Here, LUCKY FACTOR means, (after converting into binary representation) if rightmost or leftmost 1's neighbour is either 0 or nothing(for boundary bit). EDITED :- Means if rightmost one's left neighbour is 0, means it count as a LUCKY FACTOR, simlarly in the left side also Example, 5 == 101, LUCKY FACTOR = 2. 7 == 111, LUCKY FACTOR = 0. 13 == 1101, LUCKY FACTOR = 1. 16 == 1110, LUCKY FACTOR = 0. 0 == 0, LUCKY FACTOR = 0. Answer must be in binary form I am totally stuck, give me a hint. My code #include<stdio.h> #include<string> #include<string.h> #include<vector> //#include<iostream> using namespace std; vector<string> pp(10000001); string add(string a, string b) { if(b == "") return a; string answer = ""; int c = 0; int szeA = a.size() - 1; int szeB = b.size() - 1; while(szeA >= 0 || szeB >= 0) { answer = (char)( ( ( ( (szeA >= 0) ? (a[szeA] - 48) : 0 ) ^ ( (szeB >= 0) ? (b[szeB] - 48) : 0 ) ) ^ (c) ) + 48 ) + answer; c = ( ( ( (szeA >= 0) ? (a[szeA] - 48) : 0 ) & ( (szeB >= 0) ? (b[szeB] - 48) : 0 ) ) | ( ( (szeA >= 0) ? (a[szeA] - 48) : 0 ) & (c) ) | ( ( (szeB >= 0) ? (b[szeB] - 48) : 0 ) & (c) ) ); szeA--; szeB--; } if(c) answer = '1' + answer; return answer; } string subtract(string a, string b) { int sze = a.size() - b.size(); while(sze--) b = '0' + b; sze = a.size(); for(int i = 0; i < sze; i++) { if(b[i] == '1') b[i] = '0'; else b[i] = '1'; } if(b[sze-1] == '0') { b[sze-1] = '1'; } else { int i = sze-1; while(i >= 0 && b[i] == '1') { b[i] = '0'; i--; } if(i >= 0) b[i] = '1'; else b = '1' + b; } b = add(a, b); b.erase(b.begin() + 0); //b[0] = '0'; while(b[0] == '0') b.erase(b.begin() + 0); return b; } string power(int index) { if(index < 0) return ""; string answer = ""; while(index--) { answer = '0' + answer; } answer = '1' + answer; return answer; } string convert(long long int val) { int divisionStore=0; int modStore=0; string mainVector = ""; do { modStore=val%2; val=val/2; mainVector = (char)(modStore+48) + mainVector; }while(val!=0); return mainVector; } string increment(string s) { int sze = s.size()-1; if(s[sze] == '0') { s[sze] = '1'; return s; } while(sze >= 0 && s[sze] == '1') { s[sze] = '0'; sze--; } if(sze >= 0) s[sze] = '1'; else s = '1' + s; return s; } main() { int T; char s[1000001]; string answer; scanf("%d", &T); for(int t = 1; t <= T; t++) { int num; answer = "1"; int bitComeEver = 0; int lastBit = 0; scanf("%s", s); int sze = strlen(s); // I used below block because to avoid TLE. if(sze > 3300) { printf( "Case #%d\n", t); for(int i = 0; i < sze; i++) printf("%c", '1'); printf("\n"); //continue; } else { if(pp[sze-1] != "") answer = pp[sze-1]; else { pp[sze-1] = power(sze-1); answer = pp[sze-1]; } answer = subtract(answer, convert(sze-1)); //////////////////////////// //cout << answer << endl; for(int i = 1; i < sze; i++) { if(s[i] == '1') { if(s[1] == '0') { num = sze-i-1; if(num > 0) { if( pp[num-1] == "") { pp[num-1] = power(num-1); } if(pp[num+1] == "") { pp[num+1] = power(num+1); } answer = add(answer, subtract(pp[num+1], pp[num-1])); if(lastBit) answer = add(answer, "1"); //else answer = increment(answer); //cout << "\t\t" << answer << endl; } else{ int inc; if(lastBit) inc = 2; //answer = add(answer, "10"); else inc = 1; //answer = increment(answer); if(s[i-1] == '0') lastBit = 1; else lastBit = 0; if(lastBit) inc += 2; else inc += 1; if(inc == 2) answer = add(answer, "10"); else if(inc == 3) answer = add(answer, "11"); else answer = add(answer, "100"); } } else { if(num > 0) { if(pp[num-1] != "") pp[num-1] = power(num-1); answer = add(answer, pp[num-1]); } else { int inc = 0; if(lastBit) inc = 1; //answer = increment(answer); if(s[i-1] == '0') lastBit = 1; else lastBit = 0; if(lastBit) inc += 1; answer = add(answer, convert(inc)); } } if(s[i-1] == '0') lastBit = 1; else lastBit = 0; } } if(s[sze-1] == '0') { if(lastBit) { if(s[1] == '0') { answer = add(answer, "10"); } else answer = increment(answer); } else if(s[1] == '0'){ answer = increment(answer); } } printf( "Case #%d\n", t); for(int i = 0; i < sze; i++) printf("%c", answer[i]); printf("\n"); } } return 0; }
If a number has k bits, then calculate the number of such numbers having a LUCKY FACTOR of 2: 10.............01 Hence in this the 1st two and last two digits are fixed, the remaining k-4 digits can have any value. The number of such numbers = 2^(k-4). So you can easily calculate the sum of lucky factors of such numbers = lucky_factor x 2^(k-4) (ofcourse this is assuming k >= 4) What's more, you do not need to calculate this number since it will be of the form 10000000. If the number n is 11010010. Then 8 bit numbers less than n shall be of form: 10........ or 1100...... or 1101000_. If you see a pattern, then we have divided the calculation in terms of the number of 1s in the number n . I leave the rest for you.
Sudoku Solving Function Explanation
I have been searching for a Sudoku Solving Algorithm for a while and I found this code. But I have some difficulties. I can't understand it. If there are conflicts with all numbers between 1 and 9 in a single cell, the program should stop, right? But it continues. Can somebody explain me how the code works, please? Here it is: bool Sudoku::Help_Solve(int i, int j) { int nextrow, nextcol; while(change[i][j] == 1) //We find the first cell in which we can change the number { j++; if(j > 9) { j = 1; i++; } if(i > 9) return true; } for(int p = 1; p <= 9; p++) { if(Game.Check_Conflicts(p, i, j)) //We are checking for conflicts { board[i][j] = p; nextrow = i; nextcol = j+1; if(nextcol > 9) { nextcol = 1; nextrow++; } if(nextcol == 1 && nextrow == 10) return true; if(Game.Help_Solve(nextrow, nextcol)) return true; } } board[i][j] = 0; return false; }
Not enough code to explain properly, what happens in Game.Check_Conflicts(p, i, j), is this function getting called recursively?
Here is the whole code if you want to see it: #include <iostream> #include <iomanip> #include <time.h> #include <cstdlib> #include <windows.h> using namespace std; class Sudoku { private: int board[9][9]; int change[9][9]; public: Sudoku(); void Print_Board(); void Add_First_Cord(); bool Help_Solve(int i, int j); bool Check_Conflicts(int p, int i, int j); }; Sudoku Game; void setcolor(unsigned short color) //The function that you'll use to { //set the colour HANDLE hcon = GetStdHandle(STD_OUTPUT_HANDLE); SetConsoleTextAttribute(hcon,color); } Sudoku::Sudoku() { for(int i = 0; i <= 9; i++) for(int j = 0; j <= 9; j++) board[i][j] = 0; } void Sudoku::Print_Board() { for(int i = 1; i <= 9; i++) { for(int j = 1; j <= 9; j++) { if(change[i][j] == 1) { setcolor(12); cout << board[i][j] << " "; setcolor(7); } else cout << board[i][j] << " "; if(j%3 == 0) cout << "| "; } cout << endl; if(i%3 == 0) cout << "------+-------+--------" << endl; } } void Sudoku::Add_First_Cord() { board[1][1] = 5; change[1][1] = 1; board[1][2] = 3; change[1][2] = 1; board[1][5] = 7; change[1][5] = 1; board[2][1] = 6; change[2][1] = 1; board[2][4] = 1; change[2][4] = 1; board[2][5] = 9; change[2][5] = 1; board[2][6] = 5; change[2][6] = 1; board[3][2] = 9; change[3][2] = 1; board[3][3] = 8; change[3][3] = 1; board[3][8] = 6; change[3][8] = 1; board[4][1] = 8; change[4][1] = 1; board[4][5] = 6; change[4][5] = 1; board[4][9] = 3; change[4][9] = 1; board[5][1] = 4; change[5][1] = 1; board[5][4] = 8; change[5][4] = 1; board[5][6] = 3; change[5][6] = 1; board[5][9] = 1; change[5][9] = 1; board[6][1] = 7; change[6][1] = 1; board[6][5] = 2; change[6][5] = 1; board[6][9] = 6; change[6][9] = 1; board[7][2] = 6; change[7][2] = 1; board[7][7] = 2; change[7][7] = 1; board[7][8] = 8; change[7][8] = 1; board[8][4] = 4; change[8][4] = 1; board[8][5] = 1; change[8][5] = 1; board[8][6] = 9; change[8][6] = 1; board[8][9] = 5; change[8][9] = 1; board[9][5] = 8; change[9][5] = 1; board[9][8] = 7; change[9][8] = 1; board[9][9] = 9; change[9][9] = 1; } bool Sudoku::Check_Conflicts(int p, int i, int j) { for(int k = 1; k <= 9; k++) if(board[i][k] == p) return false; for(int q = 1; q <= 9; q++) if(board[q][j] == p) return false; /* *00 000 000 */ if((j == 1 || j == 4 || j == 7) && (i == 1 || i == 4 || i == 7)) { if(board[i][j+1] == p || board[i][j+2] == p || board[i+1][j] == p || board[i+2][j] == p || board[i+1][j+1] == p || board[i+1][j+2] == p || board[i+2][j+1] == p || board[i+2][j+2] == p)return false; } /* 000 000 *00 */ if((j == 1 || j == 4 || j == 7) && (i == 3 || i == 6 || i == 9)) { if(board[i-1][j] == p || board[i-2][j] == p || board[i][j+1] == p || board[i][j+2] == p || board[i-1][j+1] == p || board[i-1][j+2] == p || board[i-2][j+1] == p || board[i-2][j+2] == p)return false; } /* 000 *00 000 */ if((j == 1 || j == 4 || j == 7) && (i == 2 || i == 5 || i == 8)) { if(board[i-1][j] == p || board[i-1][j+1] == p || board[i-1][j+2] == p || board[i][j+1] == p || board[i][j+2] == p || board[i+1][j] == p || board[i+1][j+1] == p || board[i+1][j+2] == p)return false; } /* 0*0 000 000 */ if((j == 2 || j == 5 || j == 8) && (i == 1 || i == 4 || i == 7)) { if(board[i][j-1] == p || board[i][j+1] == p || board[i+1][j+1] == p || board[i+1][j-1] == p || board[i+1][j] == p || board[i+2][j-1] == p || board[i+2][j] == p || board[i+2][j+1] == p)return false; } /* 000 0*0 000 */ if((j == 2 || j == 5 || j == 8) && (i == 2 || i == 5 || i == 8)) { if(board[i-1][j] == p || board[i-1][j-1] == p || board[i-1][j+1] == p || board[i][j+1] == p || board[i][j-1] == p || board[i+1][j+1] == p || board[i+1][j] == p || board[i+1][j-1] == p)return false; } /* 000 000 0*0 */ if((j == 2 || j == 5 || j == 8) && (i == 3 || i == 6 || i == 9)) { if(board[i][j-1] == p || board[i][j+1] == p || board[i-1][j] == p || board[i-1][j+1] == p || board[i-1][j-1] == p || board[i-2][j] == p || board[i-2][j+1] == p || board[i-2][j-1] == p) return false; } /* 00* 000 000 */ if((j == 3 || j == 6 || j == 9) && (i == 1 || i == 4 || i == 7)) { if(board[i][j-1] == p || board[i][j-2] == p || board[i+1][j] == p || board[i+1][j-1] == p || board[i+1][j-2] == p || board[i+2][j] == p || board[i+2][j-1] == p || board[i+2][j-2] == p) return false; } /* 000 00* 000 */ if((j == 3 || j == 6 || j == 9) && (i == 2 || i == 5 || i == 8)) { if(board[i-1][j] == p || board[i-1][j-1] == p || board[i-1][j-2] == p || board[i][j-1] == p || board[i][j-2] == p || board[i+1][j] == p || board[i+1][j-1] == p || board[i+1][j-2] == p) return false; } /* 000 000 00* */ if((j == 3 || j == 6 || j == 9) && (i == 3 || i == 6 || i == 9)) { if(board[i][j-1] == p || board[i][j-2] == p || board[i-1][j] == p || board[i-1][j-1] == p || board[i-1][j-2] == p || board[i-2][j] == p || board[i-2][j-1] == p || board[i-2][j-2] == p) return false; } return true; } bool Sudoku::Help_Solve(int i, int j) { int nextrow, nextcol; while(change[i][j] == 1) { j++; if(j > 9) { j = 1; i++; } if(i > 9) return true; } for(int p = 1; p <= 9; p++) { if(Game.Check_Conflicts(p, i, j)) { board[i][j] = p; nextrow = i; nextcol = j+1; if(nextcol > 9) { nextcol = 1; nextrow++; } if(nextcol == 1 && nextrow == 10) return true; if(Game.Help_Solve(nextrow, nextcol)) return true; } } board[i][j] = 0; return false; } int main() { Game.Add_First_Cord(); Game.Help_Solve(1, 1); Game.Print_Board(); system("pause"); return 0; }
It looks like Sudoku::Check_Conflicts returns true if the number CAN be placed there, or false if it CAN'T be placed there due to a simple conflict. A different function name could maybe better self-document the code.
The thing is rhat I can't understand why it continues if in the end it returns false :/ It doesn't ALWAYS return at the bottom of the function tho': bool Sudoku::Help_Solve(int i, int j) { int nextrow, nextcol; while(change[i][j] == 1) //We find the first cell in which we can change the number { j++; if(j > 9) { j = 1; i++; } if(i > 9) return true; -------------------------^^^^ returns true if we have filled all squares. } for(int p = 1; p <= 9; p++) { if(Game.Check_Conflicts(p, i, j)) //We are checking for conflicts { board[i][j] = p; nextrow = i; nextcol = j+1; if(nextcol > 9) { nextcol = 1; nextrow++; } if(nextcol == 1 && nextrow == 10) return true; -----------------------------------------------------^^^^ returns when we have filled everything! if(Game.Help_Solve(nextrow, nextcol)) return true; ---------------------------------------------------------^^^^ returns if we filled at the next level of solution. } } board[i][j] = 0; return false; -----------^^^^^ returns if we failed to fill the whole thing. } As someone else mentioned in a comment, there are some trivial things that can be done to improve on the algorithm - such as looking for the "most suitable place to fill first" [which doesn't improve the worst case, but it does improve the typical case]. I have written a Sudoku solver that uses a similar algorithm, but it tries to find the cell with the lowest number of candidates (possible numbers to go in the that cell) and only tries recursively if there are multiple choices.