euler/other/sudoku.java

170 lines
3.5 KiB
Java
Raw Normal View History

import java.util.*;
import javax.swing.*;
import java.io.IOException;
import java.io.FileReader;
import java.io.Reader;
class Sudoku {
int[] fieldValues = new int[81];
int[] emptyFields;
int currentField;
void printField() {
String fieldOut = "";
int i;
for(i=0; i<81; i++) {
if(i%27 == 0 && i>0) {
fieldOut += "\n---------------------\n";
}
else if(i%9 == 0) {
fieldOut += "\n";
}
else if(i%3 == 0) {
fieldOut += "| ";
}
if(fieldValues[i] != 0) {
fieldOut += fieldValues[i] + " ";
}
else {
fieldOut += " ";
}
}
System.out.println(fieldOut);
}
int getThreeDigits() {
int i = 0;
i += fieldValues[2];
i += fieldValues[1] * 10;
i += fieldValues[0] * 100;
return i;
}
void loadFieldFromScanner(Scanner s) throws Exception {
int currentField = 0;
if (!s.hasNextLine()) {
throw new Exception("No lines to read");
}
if (!s.nextLine().startsWith("Grid")) {
throw new Exception("Not at start of grid");
}
while (s.hasNextLine()) {
String line = s.nextLine();
for (int i = 0; i < line.length(); i++) {
int v = line.charAt(i) - (int) '0';
fieldValues[currentField] = v;
currentField += 1;
}
if (currentField == 81) {
break;
}
}
return;
}
/** Function asks for an file name which
* should contain a sudoku and this sudoku
* into fieldValues, Empty fields should
* be marked by a '0'
*/
void loadFieldFromFile() {
String fileName = "";
Reader reader = null;
int i = 0;
fileName = JOptionPane.showInputDialog( "Enter filename" );
System.out.println(fileName);
try
{
reader = new FileReader (fileName);
for ( int c; ( c = reader.read() ) != -1; ) {
int v = 0;
v = c - (int) '0';
if( v >= 0 && v <= 9 ) {
fieldValues[i] = v;
i++;
}
if( i > 80 ) break;
}
}
catch ( IOException e) {
System.err.println( "Could not open file " + fileName );
return;
}
finally {
try { reader.close(); } catch ( Exception e ) { e.printStackTrace(); }
}
System.out.println("File loaded");
}
/** Function checks if "number" may be inserted
* in field "index"
*/
boolean isNumberAllowed(int number, int index) {
int i = 0, j = 0;
/* check col */
for(i=index%9; i<81; i+=9) {
if(fieldValues[i] == number)
return false;
}
/* check row */
for(i=index/9*9; i<(index/9*9+9); i++) {
if(fieldValues[i] == number)
return false;
}
/* check field */
int lu = (index/9/3*27) + (index%9/3*3); //first index of field
for(j = 0; j<3; j++) {
for(i = lu+(j*9); i<lu+(j*9)+3; i++) {
if(fieldValues[i] == number)
return false;
}
}
return true;
}
/** Function trys to solve the current sudoku
* using backtracking algorithm
*/
void solveSudoku() {
currentField = 0;
stepAhead();
}
boolean stepAhead() {
if(currentField==81) {
return true;
}
if(fieldValues[currentField] != 0) {
currentField++;
if(stepAhead()) {
return true;
}
}
else {
for(int i = 1; i<=9; i++) {
if(isNumberAllowed(i, currentField)) {
fieldValues[currentField] = i;
currentField++;
if(stepAhead())
return true;
}
}
fieldValues[currentField] = 0;
}
currentField--;
return false;
}
}