Solve Sudoko in Java - java

I've written the code as per the logic, but my Eclipse console is empty when I click 'Run'.
This is my code:
public class test {
public static void main(String[] args) {
int[][] board = new int[9][9];
helper(board, 0, 0);
}
public static void saveBoard(int[][] board) {
for (int i = 0; i < board.length; i++) {
for (int j = 0; j < board.length; j++) {
System.out.print(board[i][j]);
}
System.out.println();
}
}
public static void helper(int[][] board, int row, int col) {
if (row == board.length - 1) {
saveBoard(board);
return;
}
if (col == board.length - 1) {
col = 0;
row += 1;
}
for (int i = 1; i <= 9; i++) {
if (isSafe(board, row, col, i)) {
board[row][col] = i;
helper(board, row, col + 1);
}
}
}
public static boolean isSafe(int[][] board, int row, int col, int number) {
// row & column
for (int i = 0; i < board.length; i++) {
if (board[row][i] == number) return false;
if (board[i][col] == number) return false;
}
// grid
int sc = (col / 3) * 3;
int sr = (row / 3) * 3;
for (int i = 0; i < sr + 3; i++) {
for (int j = 0; j < sc + 3; j++) {
if (board[i][j] == number) return false;
}
}
return true;
}
}
or here's a screenshot

Related

Java array out of bounds - sudoku

My code for filling sudoku board looks like this:
public class SudokuBoard {
static int N = 9;
static int[][] grid = new int[N][N];
static void printGrid()
{
for (int row = 0; row < N; row++)
{
for (int col = 0; col < N; col++) {
System.out.printf("%5d", grid[row][col]);
}
System.out.println("\n");
}
}
private static boolean checkRow(int row, int num)
{
for( int col = 0; col < 9; col++ )
if(grid[row][col] == num)
return false;
return true;
}
private static boolean checkCol(int col, int num)
{
for( int row = 0; row < 9; row++ )
if(grid[row][col] == num)
return false;
return true;
}
private static boolean checkBox(int row, int col, int num)
{
row = (row / 3) * 3;
col = (col / 3) * 3;
for(int r = 0; r < 3; r++)
for(int c = 0; c < 3; c++)
if(grid[row+r][col+c] == num)
return false;
return true;
}
public static boolean fillBoard(int row, int col, int[][] grid)
{
if(row==9)
{
col = 0;
if(col++ == 9)
return true;
}
if(grid[row][col] != 0)
return fillBoard(row+1, col, grid);
for(int num = 1; num <=9; num++)
{
if(checkRow(row,num) && checkCol(col,num) && checkBox(row,col,num)){
grid[row][col] = num;
if(fillBoard(row+1, col, grid))
return true;
}
}
grid[row][col] = 0;
return false;
}
static public void main(String[] args){
fillBoard(0, 0, grid);
printGrid();
}
}
It uses backtrack algorithm to check if placement of numbers are good according to sudoku game puzzle rules.
It throws errors:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 9
at SudokuBoard.fillBoard(SudokuBoard.java:68)
at SudokuBoard.fillBoard(SudokuBoard.java:74) x9
at SudokuBoard.main(SudokuBoard.java:84)
Where is it out of bounds? I cannot see that...
This block looks wrong:
if(row==9)
{
col = 0;
if(col++ == 9)
return true;
}
I suspect you want this:
if(row==9) {
row = 0;
if(++col == 9)
return true;
}
col++ increments col, but returns the old value. You probably meant to use ++col, which returns the new value. (see Java: Prefix/postfix of increment/decrement operators?)
In your code, when fillBoard(8, 8, grid) is called, col is increased to 9, but (col++ == 9) gets evaluated to false, because col++ returns 8. So you then try to access grid[8][9], which is when the exception is thrown.

Java Loop star pattern - algorithm optimalization

Can anyone tell me what is the more elegant solution for outputting this pattern?
I most interested in my makeTemplate method, but any other help will be appreciated.
Here is my code, which i want to be more readable:
public class Main {
public static void makeTemplate(char tab[][], int rows, int col) {
boolean increase = true;
int j = 0;
char star = '*';
for (int i = 0; i < rows; i++) {
if (increase) {
tab[i][j] = star;
if (j >= col - 1) {
increase = false;
j--;
continue;
}
j++;
} else {
tab[i][j] = star;
if (j < 0 + 1) {
increase = true;
j++;
continue;
}
j--;
}
}
}
public static void main(String[] args) {
char[][] tab = new char[30][6];
makeTemplate(tab, 30, 6);
for (int i = 0; i < 30; i++) {
for (int j = 0; j < 6; j++) {
System.out.print(tab[i][j]);
}
System.out.println();
}
}
}
Only made some changes to makeTemplate
public static void makeTemplate(char tab[][], int rows, int col) {
boolean increase = true;
int j = 0;
char star = '*';
for (int i = 0; i < rows; i++) {
tab[i][j] = star;
if (increase) {
if (j >= col - 1) {
increase = false;
j--;
} else {
j++;
}
} else {
if (j < 1) {
increase = true;
j++;
}else {
j--;
}
}
}
}
Replaced the continue statements with else as the continue statement pretty much does the same thing as the else. Using continue in the if statement says to skip the j++ or j-- below. So instead the j++ or j-- will only be executed if the if is true.
I also changed if(j < 0 + 1) to if(j < 1) as 0+1 = 1
Moved tab[i][j] = star; before the first if as it is the first line in the if and else - Thanks Betlista
Elegant java8 solution:
IntStream.range(0, ROWS).forEach(i -> {
int cur = i % (COLS * 2);
if(cur < 6) {
IntStream.range(0, cur).forEach(f -> System.out.print(" "));
} else {
IntStream.range(0, COLS - cur % COLS).forEach(f -> System.out.print(" "));
}
System.out.println("*");
});
Granted, I haven't used the makeTemplate() method but as far as elegance and understand-ability goes, this does the job well.
You can use recursion
public static char[][] makeTemplate(char tab[][], int rows, int col, int curRow, int curPos, boolean increase) {
if (curRow == rows)
return tab;
tab[curRow][curPos] = '*';
if (increase && curPos + 1 == col) {
increase = false;
} else if (curPos == 0) {
increase = true;
}
return makeTemplate(tab, rows, col, curRow + 1, (increase) ? ++curPos : --curPos, increase);
}
public static void main(String[] args) {
char[][] tab = makeTemplate(new char[30][6], 30, 6, 0, 0, true);
for (int i = 0; i < 30; i++) {
for (int j = 0; j < 6; j++) {
System.out.print(tab[i][j]);
}
System.out.println();
}
}

Trouble printing chars thru a 2 dim java array

I tried to run this code as a score table where I have chars and ints as below for heading;
A B c
1
2 65 //this is where I'm stuck again!
3
In order to print the score like (65) above in a particular place (matrix) but as soon as I try to add the print statements the table falls apart. Any help would be appreciated;
public class Table3 {
static int[][] list = new int[4][4];
//private char column = 'A';
//private int row = 1;
private static int row = 1;
public Table3(){
//column = 'A';
for (int i = 0; i < 4; i++) {
for (int j = 1; j < 4; j++)
list[i][j] = 0;
}
}
public static void table(char col, int row, int value) {
//System.out.printf("\n\n%s\n", "Table");
for (int i = 1; i < 4; i++) {
System.out.print(row + " ");
row++;
for (int j = 1; j < 4; j++)System.out.print(col + " ");
System.out.println("\n");
col++;
if (row >= 0 && row <= 4 && col >=0 && col <= 4)
System.out.print(list[col][row]=value);
System.out.println("\n");
}
}
}
Client
public class TableTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
Table3 t = new Table3();
t.table('A', 5, 5);
}
}
Learn how to use System.out.printf. The docs are here.
public class Table3
{
static int numRows = 4;
static int numCols = 4;
static int[][] list = new int[numRows][numCols];
public Table3()
{
//column = 'A';
for (int i = 0; i < 4; i++)
{
//this is the row number so you don't have to print it manually
//just print the array
list[i][0] = i;
//initialize the list to 0
for (int j = 1; j < 4; j++)
{
list[i][j] = 0;
}
}
}
public static void table(char col, int row, int value)
{
list[row][col] = value;
int columnWidth = 5; //in characters
//empty space before first column header
for (int i = 0; i < columnWidth; i++)
{
System.out.print(" ");
}
//print the column headers (A through C)
for (int i = 1; i < numCols; i++)
{
System.out.printf("%-" + columnWidth" + "c", (char)(64 + i));
}
System.out.println(); //get off of the column header row
//print the rest of the table
for (int i = 1; i < numRows; i++)
{
for (int j = 0; j < numCols; j++)
{
if (list[i][j] == 0)
{
System.out.printf("%" + columnWidth + "s", " ");
}
else
{
System.out.printf("%-" + columnWidth + "d", list[i][j]);
}
}
System.out.println("\n");
}
}
}

Everytime I run this method my array is reset

Everytime I call set() it resets all the values in the array to false except for what ever the int row int col is because i set that to true before the method ends. Why is this happening I thought I was making a copy of the array B and then setting the values that are in A to the values in B? Or am I mistaken here.
public void set(int row, int col) throws IndexOutOfBoundsException {
if (row >capacityr) {
boolean B[][] = new boolean[row+1][capacityc+1];
for (int k = 0; k < capacityr; k++)
for (int j = 0; j < capacityc; j++)
B[k][j] = a[k][j];
capacityr=row;
a = B;
}
if (col >capacityc) {
boolean C[][] = new boolean[capacityr+1][col+1];
for (int k = 0; k <capacityr; k++)
for (int j = 0; j < capacityc; j++)
C[k][j] = a[k][j];
capacityc=col;
a = C;
}
a[row][col] = true;
pT++;
}
It should be easier to use an ArrayList but I think this would fix your problem.
public void set(int row, int col) throws IndexOutOfBoundsException {
if(row > capacityr) {
if(col > capacityc) {
//both row and col are too big
boolean temp[][] = new boolean[row+1][col+1];
//copy a
for(int i = 0; i <= capacityr; i++) {
for(int j = 0; j <= capacityc; j++) {
temp[i][j] = a[i][j];
}
}
//set all the new elements to false
for(int i = capacityr+1; i <= row; i++) {
for(int j = capacityc+1; j <= col; j++) {
temp[i][j] = false;
}
}
//set row and col and a to temp
temp[row][col] = true;
a = temp;
//update capacity
capacityr = row;
capacityc = col;
}
else {
//just row is too big
boolean temp[][] = new boolean[row+1][capacityc+1];
for(int i = 0; i <= capacityr; i++) {
for(int j = 0; j <= capacityc; j++) {
temp[i][j] = a[i][j];
}
}
for(int i = capacityr+1; i <= row; i++) {
temp[i][capacityc] = false;
}
temp[row][col] = true;
a = temp;
capacityr = row;
}
}
else {
if(col > capacityc) {
//just col is too big
boolean temp[][] = new boolean[capacityr+1][col+1];
for(int i = 0; i <= capacityr; i++) {
for(int j = 0; j <= capacityc; j++) {
temp[i][j] = a[i][j];
}
}
for(int j = capacityc+1; j <= col; j++) {
temp[capacityr][j] = false;
}
temp[row][col] = true;
a = temp;
capacityc = col;
}
else {
//neither are too big
a[row][col] = true;
}
}
}

Building a tester class?

I am a very new java user, and I have always had trouble with testing my programs. Here I have implement a basic boolean array interface. I want to test it buy adding a couple values and then running each of the interface methods. Please be nice I am not very good at this but I want to get better.
package booleanmatrix;
import java.util.Arrays;
/**
*
* #author David
*/
public class ArrayMatrix implements BooleanMatrixs {
private boolean a[][];
public int Rows;
public int Cols;
public int capacityr = 1;
public int capacityc = 1;
public int pT=0;
public int pF=0;
public ArrayMatrix() {
a = new boolean[capacityr][capacityc];
}
#Override
public int getNumberRows() {
return capacityr;
}
#Override
public int getNumberCols() {
return capacityc;
}
#Override
public void set(int row, int col) throws IndexOutOfBoundsException {
if (row > capacityr) {
capacityr = row;
boolean B[][] = new boolean[capacityr][capacityc];
for (int k = 0; k < capacityr; k++) {
for (int j = 0; j < capacityc; j++) {
B[k][j] = a[k][j];
}
}
a = B;
}
if (col > capacityc) {
capacityc = col;
boolean C[][] = new boolean[capacityr][capacityc];
for (int k = 0; k < capacityr; k++) {
for (int j = 0; j < capacityc; j++) {
C[k][j] = a[k][j];
}
}
a = C;
}
a[row][col] = true;
pT++;
}
#Override
public void clear(int row, int col) throws IndexOutOfBoundsException {
if (row > capacityr) {
capacityr = row;
boolean B[][] = new boolean[capacityr][capacityc];
for (int k = 0; k < capacityr; k++) {
for (int j = 0; j < capacityc; j++) {
B[k][j] = a[k][j];
}
}
a = B;
}
if (col > capacityc) {
capacityc = col;
boolean C[][] = new boolean[capacityr][capacityc];
for (int k = 0; k < capacityr; k++) {
for (int j = 0; j < capacityc; j++) {
C[k][j] = a[k][j];
}
}
a = C;
}
a[row][col] = false;
}
#Override
public void set(int row, int col, boolean value) throws IndexOutOfBoundsException {
if (row > capacityr) {
capacityr = row;
boolean B[][] = new boolean[capacityr][capacityc];
for (int k = 0; k < capacityr; k++) {
for (int j = 0; j < capacityc; j++) {
B[k][j] = a[k][j];
}
}
a = B;
}
if (col > capacityc) {
capacityc = col;
boolean C[][] = new boolean[capacityr][capacityc];
for (int k = 0; k < capacityr; k++) {
for (int j = 0; j < capacityc; j++) {
C[k][j] = a[k][j];
}
}
a = C;
}
a[row][col] = value;
if(value==true){
pT++;
}
}
#Override
public void toggle(int row, int col) throws IndexOutOfBoundsException {
if (row > capacityr) {
capacityr = row;
boolean B[][] = new boolean[capacityr][capacityc];
for (int k = 0; k < capacityr; k++) {
for (int j = 0; j < capacityc; j++) {
B[k][j] = a[k][j];
}
}
a = B;
}
if (col > capacityc) {
capacityc = col;
boolean C[][] = new boolean[capacityr][capacityc];
for (int k = 0; k < capacityr; k++) {
for (int j = 0; j < capacityc; j++) {
C[k][j] = a[k][j];
}
}
a = C;
}
if (a[row][col] == true) {
a[row][col] = false;
pT--;
} else {
a[row][col] = true;
pT++;
}
}
#Override
public void setAll() {
Arrays.fill(a, Boolean.TRUE);
pT=(capacityr*capacityc);
}
#Override
public void clearAll() {
Arrays.fill(a, Boolean.FALSE);
pT=0;
}
#Override
public void setAll(boolean value) {
if (value == false) {
Arrays.fill(a, Boolean.FALSE);
} else {
Arrays.fill(a, Boolean.TRUE);
pT=(capacityr*capacityc);
}
}
#Override
public boolean get(int row, int col) throws IndexOutOfBoundsException {
boolean x;
x = a[row][col];
return x;
}
#Override
public int[][] getTruePositions() {
int count = 0;
int ret[][] = new int[pT][2];
for (int k = 0; k < capacityr; k++) {
for (int j = 0; j < capacityc; j++) {
if (a[k][j] == true) {
ret[count][0] = k;
ret[count][1] = j;
count++;
}
}
}
return ret;
}
#Override
public int[][] getFalsePositions() {
int total = (capacityr*capacityc);
int P=(total-pT);
int count=0;
int ret[][] = new int[P][2];
for (int k = 0; k < capacityr; k++) {
for (int j = 0; j < capacityc; j++) {
if (a[k][j] == false) {
ret[count][0] = k;
ret[count][1] = j;
count++;
}
}
}
return ret;
}
#Override
public int[][] getPositions(boolean value) {
int total = (capacityr*capacityc);
int P=(total-pT);
int count=0;
if(value==false){
int retf[][] = new int[P][2];
for (int k = 0; k < capacityr; k++) {
for (int j = 0; j < capacityc; j++) {
if (a[k][j] == false) {
retf[count][0] = k;
retf[count][1] = j;
count++;
}
}
}
return retf;}
else{
int count2 = 0;
int ret[][] = new int[pT][2];
for (int k = 0; k < capacityr; k++) {
for (int j = 0; j < capacityc; j++) {
if (a[k][j] == true) {
ret[count2][0] = k;
ret[count2][1] = j;
count2++;
}
}
}
return ret;
}}
#Override
public int getNumberTrueValues() {
return pT;
}
#Override
public int getNumberFalseValues() {
int total = (capacityr*capacityc);
int P=(total-pT);
return P;
}
#Override
public int getNumberValues(boolean value) {
if (value==false){
int total = (capacityr*capacityc);
int P=(total-pT);
return P;
}
else{return pT;}}
#Override
public String toString(){
String X= "1)The number of rows"+capacityr+"\n 2)The number of Columns"+capacityc+"\n 3)The number of True Values"+pT+"\n 4)The number of false values"+(capacityc*capacityr-pT);
return X;
}
public static void main(String[] args) {
}
}
Take a look at this JUnit tutorial. It might be just a bit of overkill, but a good unit testing framework is usually the best way to test your code at this level.
Add a new class that has a Main method (if you are using eclipse there is an auto click button that does that for you) then instantiate a new variable from your class.
ArrayMatrix arrayVar = new ArrayMatrix();
Then you would be able to access all the methods such as:
arrayVar.getNumberCols();

Categories