1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163
| int CSudokuDlg::resol_double()
{
int n = 0, t;
// création de l'arbre:
for(int a=0; a<81; a++) {
if(!map[a])
memset(table, 0, 81);
}
bool *pass2;
// générer la table
for(int j=0; j<9; j++) {
for(int i=0; i<9; i++) {
// travail pour la case i,j
if(map[i+9*j])
continue; // ce n'est pas un trou
pass2 = table[i+9*j];
for(int a=0; a<9; a++) { // élimination des candidats mode LIGNE
if(t = map[a+9*j])
pass2[t] = 1;
if(t = map[i+9*a]) // ... et COLONNE
pass2[t] = 1;
}
for(int a=0; a<3; a++) { // mode CUBE
for(int b=0; b<3; b++) {
if(t = map[3*(i/3)+a+9*(3*(j/3)+b)])
pass2[t] = 1;
}
}
}
}
retry:
// chercher pour chaque trou de chaque ligne/colonne/bloc
// s'il y a pas 2 cases qui ont que 2 possibilités et qu'elles soient identiques
// éliminer les possibilités
int f,a1,a2,b1,b2;
for(int j=0; j<9; j++) {
for(int i=0; i<9; i++) {
if(map[i+9*j])
continue; // ce n'est pas un trou
pass2 = table[i+9*j];
f = 0;
for(int k=1; k<10; k++) {
if(pass2[k]) {
f++;
if(f) // systémtatiquement dans le même ordre (de a=1 à a=10)
a2 = k;
else
a1 = k;
}
}
if(f==2) { // on a trouvé une case a 2 candidats
// rechercher pour cette case, tous les trous suivants
// de cette ligne, qui ont eux-aussi que 2 candidats et les mêmes
for(int a=i+1; a<9; a++) { // recherche en LIGNE
if(map[a+9*j])
continue; // ce n'est pas un trou
f = 0;
for(int k=1; k<10; k++) { // recherche du nombre de possibilité pour la case courrante
if(pass2[k]) {
f++;
if(f)
b2 = k;
else
b1 = k;
}
}
if(f==2) {
if(a1 == b1 && a2 == b2) { // la case courrante est une paire cachée avec I,J
// I,J vaut A1 OU B1
// A,J vaut l'autre
// éliminer de la table A1 et B1 du reste de la ligne!
for(int b=0; b<9; b++) {
if(b == i || b == a) // X des paires
continue;
table[b+9*j][a1] = 1; // ne peut plus être
table[b+9*j][b1] = 1;
}
}
}
} // mode ligne
for(int a=i+1; a<9; a++) { // recherche en COLONNE
if(map[i+9*a])
continue; // ce n'est pas un trou
f = 0;
for(int k=1; k<10; k++) {
if(pass2[k]) {
f++;
if(f)
b2 = k;
else
b1 = k;
}
}
if(f==2) {
if(a1 == b1 && a2 == b2) { // la case courrante est une paire cachée avec I,J
for(int b=0; b<9; b++) {
if(b == j || b == a) // Y des paires
continue;
table[i+9*b][a1] = 1; // ne peut plus être
table[i+9*b][b1] = 1;
}
}
}
} // mode colonne
for(int a=0; a<3; a++) { // recherche en CUBE
for(int b=0; b<3; b++) {
if(a==i%3 && b==j%3)
continue; // case courrante
if(map[3*(i/3)+a+9*(3*(j/3)+b)])
continue; // ce n'est pas un trou
f = 0;
for(int k=1; k<10; k++) {
if(pass2[k]) {
f++;
if(f)
b2 = k;
else
b1 = k;
}
}
if(f==2) {
if(a1 == b1 && a2 == b2) { // la case courrante est une paire cachée avec I,J
for(int c=0; c<3; c++) {
for(int d=0; d<3; d++) {
if(c+(i/3)*3 == i && d+(j/3)*3 == j) // première paire (original)
continue;
if(c == a && d == b) // seconde paire (trouvé)
continue;
table[3*(i/3)+c+9*(3*(j/3)+d)][a1] = 1; // ne peut plus être
table[3*(i/3)+c+9*(3*(j/3)+d)][b1] = 1;
}
}
}
}
}
} // mode cube
} // if(f==2)
}
} // comparaison
int e, n2 = 0;
for(int i=0; i<9; i++) { // reconstitution...
for(int j=0; j<9; j++) {
if(map[i+9*j])
continue;
f = 0;
for(int a=1; a<10; a++) {
if(table[i+9*j][a])
f++;
else
e = a;
}
if(f==8) { // on a éliminé 8 possibilités. En resite qu'une
map[i+9*j] = e;
n++;
n2++;
}
}
}
if(n2)
goto retry;
resultat[5] += n;
return n;
} |
Partager