📄 solver.java
字号:
group[found1][ pairs[p][0]] = 1;
group[found1][ pairs[p][1]] = 1;
group[found1][0] = 2;
Arrays.fill( group[found2], 0); // clear array
group[found2][ pairs[p][0]] = 1;
group[found2][ pairs[p][1]] = 1;
group[found2][0] = 2;
posibleValsChanged = true;
//CONSTS.log("HIDDEN PAIR. Pos val removed!");
break;
}
}
}
} // for m
}
if( posibleValsChanged) break;
} // for n
if( posibleValsChanged) break;
} // for p
return posibleValsChanged;
}
private int[][] getAllPairsFromGroup(int[][] group)
{
int[][] res;
ArrayList aux = new ArrayList();
int[] par;
boolean repeated;
for (int n = 0; n < 9; n++)
{
for (int pos1 = 1; pos1 <= 9; pos1++)
{
if( group[n][pos1] == 0) continue;
for (int pos2 = pos1+1; pos2 <= 9; pos2++)
{
if( group[n][pos2] == 0) continue;
par = new int[2];
par[0] = pos1;
par[1] = pos2;
repeated = false;
for (int i = 0; i < aux.size(); i++)
{
if( par[0] == ((int[] )aux.get(i))[0] &&
par[1] == ((int[] )aux.get(i))[1])
{
repeated = true; // already in list
break;
}
}
if( !repeated)
{
aux.add( par);
}
}
}
}
res = new int[aux.size()][2];
for (int i = 0; i < aux.size(); i++)
{
res[i] = (int[] )aux.get(i);
}
return res;
}
private boolean applyStrategy_7_naked_triples()
{
// CONSTS.log("----------------------------- Start applyStrategy_7_naked_triples");
// CONSTS.log( toString());
// CONSTS.log( posibleValsToString());
boolean posibleValsChanged = false;
for (int n = 0; n < 27; n++)
{
posibleValsChanged = checkGroupForNakedTriples( groups[n]) || posibleValsChanged;
if( posibleValsChanged )
{
logStrategy(7);
return true;
}
}
return false;
}
private boolean applyStrategy_8_naked_triples_B()
{
// CONSTS.log("----------------------------- Start applyStrategy_8_naked_triples_B");
// CONSTS.log( toString());
// CONSTS.log( posibleValsToString());
boolean posibleValsChanged = false;
for (int n = 0; n < 27; n++)
{
posibleValsChanged = checkGroupForNakedTriplesB( groups[n]) || posibleValsChanged;
if( posibleValsChanged )
{
logStrategy(8);
return true;
}
}
return false;
}
private boolean applyStrategy_9_hidden_triples()
{
// CONSTS.log("----------------------------- Start applyStrategy_9_hidden_triples");
// CONSTS.log( toString());
// CONSTS.log( posibleValsToString());
boolean posibleValsChanged = false;
for (int n = 0; n < 27; n++)
{
posibleValsChanged = checkGroupForHiddenTriples( groups[n]) || posibleValsChanged;
if( posibleValsChanged )
{
logStrategy(9);
return true;
}
}
return false;
}
private boolean checkGroupForHiddenTriples(int[][] group)
{
boolean posibleValsChanged = false;
boolean hiddenTripleFound = false;
ArrayList triples = getAllTriples( group);
int[] triple = null;
int[] found = new int[3];
int f = 0;
for (int t = 0; t < triples.size(); t++)
{
hiddenTripleFound = false;
triple = (int[] ) triples.get(t);
f=0;
for (int cell = 0; cell < 9; cell++)
{
if( group[cell][triple[0]] +
group[cell][triple[1]] +
group[cell][triple[2]] >= 1 )
{
found[f++] = cell;
}
if( f == 3) break; // posible triple found
}
if( f == 3) // we have to check that the triple is not in any other cell
{
hiddenTripleFound = true;
for (int cell2 = 0; cell2 < 9; cell2++)
{
if( cell2 == found[0] ||
cell2 == found[1] ||
cell2 == found[2]) continue;
if( group[cell2][triple[0]] == 1 ||
group[cell2][triple[1]] == 1 ||
group[cell2][triple[2]] == 1 ) // is not a hidden triple
{
hiddenTripleFound = false;
break;
}
}
}
if( hiddenTripleFound) // hidden triple found -> remove other pos vals from these 3 cells
{
// CONSTS.log("********* Hidden triple found: " + triple[0] + triple[1] + triple[2]);
for (int n = 1; n <= 9; n++)
{
if( triple[0] == n ||
triple[1] == n ||
triple[2] == n ) continue;
for (int fnd = 0; fnd < 3; fnd++)
{
if( group[found[fnd]][n] == 1 )
{
// CONSTS.log("Hidden triple. Remove number: " + n);
group[found[fnd]][0]--;
group[found[fnd]][n] = 0;
posibleValsChanged = true;
}
}
}
}
// TODO: if( posibleValsChanged) break; (?)
} // for t
return posibleValsChanged;
}
private boolean checkGroupForNakedTriples(int[][] group)
{
boolean posibleValsChanged = false;
boolean found = false;
String t1 = null, t2 = null, t3 = null;
int posTriple1 = -1, posTriple2 = -1, posTriple3 = -1;
for( int triple1=0; triple1<9; triple1++)
{
if( group[triple1][0] != 3) continue;
t1="";
posTriple1 = triple1;
for (int n = 1; n < 9; n++)
{
if( group[triple1][n] == 1) t1 += String.valueOf( n);
}
for( int triple2=triple1+1; triple2<9; triple2++)
{
if( group[triple2][0] != 3) continue;
t2 = "";
posTriple2 = triple2;
for (int n = 1; n < 9; n++)
{
if( group[triple2][n] == 1) t2 += String.valueOf( n);
}
if( !t1.equals( t2)) continue;
for( int triple3=triple2+1; triple3<9; triple3++)
{
if( group[triple3][0] != 3) continue;
t3 = "";
posTriple3 = triple3;
for (int n = 1; n < 9; n++)
{
if( group[triple3][n] == 1) t3 += String.valueOf( n);
}
if( !t2.equals( t3)) continue;
// Found!
// CONSTS.log("Naked triple found: " + t3);
found = true;
break;
} // for triple3
if( found) break;
} // for triple2
if( found) break;
} // for triple1
if( found)
{
int n1 = Character.getNumericValue( t1.charAt(0));
int n2 = Character.getNumericValue( t1.charAt(1));
int n3 = Character.getNumericValue( t1.charAt(2));
for (int n = 0; n < 9; n++)
{
if( n==posTriple1 || n==posTriple2 || n==posTriple3 ) continue;
if( group[n][n1] == 1 || group[n][n2] == 1 || group[n][n3] == 1 )
{
// CONSTS.log("naked triple. posval removed: " +
// (group[n][n1] == 1 ? ""+n1 : "") +
// (group[n][n2] == 1 ? ""+n2 : "") +
// (group[n][n3] == 1 ? ""+n3 : ""));
group[n][0] -= group[n][n1] + group[n][n2] + group[n][n3];
group[n][n1] = group[n][n2] = group[n][n3] = 0;
posibleValsChanged = true;
}
}
}
return posibleValsChanged;
}
private boolean checkGroupForNakedTriplesB(int[][] group)
{
// Search groups of 3 cells with 2 or 3 numbers of the same triple.
boolean posibleValsChanged = false;
ArrayList triples = getAllTriples( group);
int[] triple;
int[] found = new int[3];
int f = 0;
for (int t = 0; t < triples.size(); t++)
{
triple = (int[] ) triples.get(t);
f=0;
for (int cell = 0; cell < 9; cell++)
{
if( group[cell][0] > 3) continue;
if( group[cell][triple[0]] + // if 3 pos vals -> all should be 1
group[cell][triple[1]] + // if 2 pos vals -> 2 of them should be 1
group[cell][triple[2]] == group[cell][0] )
{
found[f++] = cell;
if(f==3) break;
}
}
if( f==3) // naked triple found
{
// CONSTS.log("Naked triple found: " + triple[0] + triple[1] + triple[2]);
for (int cell2 = 0; cell2 < 9; cell2++) // remove triple from other cells
{
if( cell2 == found[0] ||
cell2 == found[1] ||
cell2 == found[2]) continue;
if( group[cell2][triple[0]] == 1 ||
group[cell2][triple[1]] == 1 ||
group[cell2][triple[2]] == 1 )
{
// CONSTS.log("naked triple B. posval removed: " +
// (group[cell2][triple[0]] == 1 ? ""+triple[0] : "") +
// (group[cell2][triple[1]] == 1 ? ""+triple[1] : "") +
// (group[cell2][triple[2]] == 1 ? ""+triple[2] : ""));
group[cell2][0] -= group[cell2][triple[0]] +
group[cell2][triple[1]] +
group[cell2][triple[2]];
group[cell2][triple[0]] = group[cell2][triple[1]] = group[cell2][triple[2]] = 0;
posibleValsChanged = true;
}
}
f=0;
}
}
return posibleValsChanged;
}
/**
* @param group
* @return
*/
private ArrayList getAllTriples(int[][] group)
{
ArrayList res = new ArrayList();
// Find all diferent numbers
int[] numbers = new int[9];
int cont = 0;
for (int n = 1; n <= 9; n++)
{
for (int i = 0; i < 9; i++)
{
if( group[i][n] == 1)
{
numbers[cont++] = n;
break;
}
}
}
// Find all posible triples with this numbers
int[] aux = null;
for (int t1 = 0; t1 < cont; t1++)
{
for (int t2 = t1+1; t2 < cont; t2++)
{
for (int t3 = t2+1; t3 < cont; t3++)
{
aux = new int[3];
aux[0] = numbers[t1];
aux[1] = numbers[t2];
aux[2] = numbers[t3];
res.add( aux);
}
}
}
return res;
}
private boolean boardChanged2()
{
boolean changed = false;
for (int i = 0; i < 9; i++)
{
for (int j = 0; j < 9; j++)
{
if( posVals[i][j][0] == 1)
{
for (int k = 1; k <= 9; k++)
{
if( posVals[i][j][k] == 1)
{
setVal( i, j, k);
break;
}
}
// CONSTS.log("boardChanged: " + i + " " + j + " "
// + matriu[i][j] + " filled " + filled);
changed = true;
}
}
}
return changed;
}
private boolean removeNumFromRow(int num, int row, int except)
{
boolean posValsChanged = false;
// CONSTS.log("removeNum " + num + " FromRow " + row);
for (int n = 0; n < 9; n++)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -