[Java] Sudoku tester in an “object oriented” way

As a result of one of my job small talks, It emerged the need to propose a possible solution to the following: “if a system receives a filled sudoku, what and how do you process that information to return a simple boolean variable that tells if the sudoku is solved right or wrong?”.

Once at home, I decided to give a formal an “object oriented” solution to this. Here is my approach.

1) Foreword: information about the problem

The system receive a sudoku filled, as seen in the picture below:

We are going to model the sudoku as a 9×9 matrix.

We need to check 3 conditions to decide if the sudoku is rightly or wrongly filled:

  1. Check if each of the 9 rows contains 1 to 9 numbers, once each.
  2. Check if each of the 9 columns contains 1 to 9 numbers, once each.
  3. Check if each of the 9 3×3 squares contains 1 to 9 numbers, once each.

2) Classes description

As you have found out, the three conditions above are very similar: we can check them by using a 1×9 vector. So, the first class we have to implement is that vector (Vector.java), which is going to be also a bean.

What we are going to need also is a class that contains one of these vectos, and with some methods implemented that let us check the three conditions. Actually, we need only one method, because (due to the vector implementation), the 3 conditions have the same purpose: check that the 9 numbers from 1 to 9 are inside the vector.  So, we are going to implement a class (called Vectest.java), that is a bean too, and contains a vector, and a “method to check the if the input vector is correct” in 2 different ways:

  • Passing the vector while initializing the object (through the constructor Vectest(vector))  and then calling the boolean method check().
  • Initializing the object, then passing the vector though a setter (setVectorTest(Vector)) and then calling the boolean method check().

The last method we need is (due to the typical Java SE implementation) a class that contains a main method (which is called Sudoku.java).

3) Solution: Java code

3.1) Vector class:


package beans;

public final class Vector {
	protected int [] vectortest = {1,1,1,1,1,1,1,1,1};

	public  Vector(String ent){
		//check if the string size is 8 characters and is formed by numbers from 1 to 9
		if (ent.length()== 9 && ent.matches("[1-9][1-9][1-9][1-9][1-9][1-9][1-9][1-9][1-9]"))
			{
				for (int i=0;i<=8;i++){
					//pass the input to the vectortest
					this.vectortest[i]=Integer.parseInt(ent.substring(i, i+1));
				}
			}
		//if the ent String does not match the above conditions, it continues with the initialized values
	}
	//constructor overriding
	public Vector(){

	}

}

3.2) Vectest class:


package beans;

/*
 * This class can be used in two ways:
 * 1. Instantiate a Vectest()-> set the vector->check()
 * 2. Instantiate a Vectest(string)-> check()
 */

public class Vectest {

	private boolean resultVect;
	private Vector vecTest;

	public Vectest(){

	}
	public Vectest(String s) {
		Vector vectorint = new Vector (s);
		vecTest = vectorint;
		//by default, resultVect=true. just in case all the 9 numbers are not found, then it will be changed to resultVect=false
		this.resultVect=true;
	}

	public void setVectortest(String s){
		Vector vectorint = new Vector (s);
		vecTest = vectorint;
		//by default, resultVect=true. just in case all the 9 numbers are not found, then it will be changed to resultVect=false
		this.resultVect=true;
	}

	public boolean check (){
		//by default, resultVect=true. just in case all the 9 numbers are not found, then it will be changed to resultVect=false
		//i= numbers to check (from 1 to 9)
		for (int i= 1; i<=9;i++){
			//j = vector occurrencies (from 0 to 8)
			for (int j= 0; j<=8;j++){
				if (vecTest.vectortest[j] == i)
					break;
				else if(j == 8)
					//if we get to the last occurrence and we do not find the number "i", the result is not-ok (resultVect=false)
					this.resultVect=false;
			}
		}
		return this.resultVect;
	}

}

3.3) Sudoku class (main class):


package core;

import beans.Vectest;;

public class Sudoku {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub

		String sudoku = new String ("164739528" +
									"857462319" +
									"923815674" +
									"682543197" +
									"341987256" +
									"795621483" +
									"479256831" +
									"518394762" +
									"236178945");
		boolean result=true;

		boolean finalCondition1=true;
		boolean finalCondition2=true;
		boolean finalCondition3=true;

		Vectest vectorRow = new Vectest();

		//first condition: rows
		for (int i=0; i<=8; i++){
			//passing the row to the vectorRow
			vectorRow.setVectortest(sudoku.substring(i*8, i*8+9));
			if(!vectorRow.check())
				finalCondition1=false;
				break;
		}
		if (finalCondition1==false)
			result=false;
		else{
			//second condition: columns
			for (int i=0; i<=8; i++){
				//passing the column to the vectorRow
				String column = sudoku.substring(i, i+1) + sudoku.substring(i+9,i+10) + sudoku.substring(i+18,i+19)+ sudoku.substring(i+27,i+28)+ sudoku.substring(i+36,i+37)+ sudoku.substring(i+45,i+46)+ sudoku.substring(i+54,i+55)+ sudoku.substring(i+63,i+64)+ sudoku.substring(i+72,i+73);
				vectorRow.setVectortest(column);
				if(!vectorRow.check()){
					finalCondition2=false;
					break;
				}
			}
			if (finalCondition2==false)
				result=false;
			else{
				for (int i=0; i<=8; i++){
					int x=0;//default
					int y=0;//default
					//third condition: 3x3 squares
					switch (i){
						case 1:
							x=3;
							break;
						case 2:
							x=6;
							break;
						case 3:
							y=3;
							break;
						case 4:
							x=3;
							y=3;
							break;
						case 5:
							x=6;
							y=3;
							break;
						case 6:
							y=6;
							break;
						case 7:
							x=3;
							y=6;
							break;
						case 8:
							x=6;
							y=6;
							break;
					}

					//lets extract each of the three rows of the square using the x and y positions
					String row1= sudoku.substring((9*y)+x,(9*y)+x+3);
					String row2= sudoku.substring((9*(y+1))+x,(9*(y+1))+x+3);
					String row3= sudoku.substring((9*(y+2))+x,(9*(y+2))+x+3);
					//now we can join the 3 rows
					String square= row1+row2+row3;
					vectorRow.setVectortest(square);
					if(!vectorRow.check()){
						finalCondition3=false;
						break;
					}
				}
				if (finalCondition3==false)
					result=false;
			}
		}
		if (result)
			System.out.println("The sudoku is correct");
		else
			System.out.println("The sudoku is wrong");
	}

}

I have been putting off this post some in order to write with the aim that it should be shown in the most formal and detailed way, and maybe anyday in the future I will modify it, introducing some UML2 diagrams or additional implementation. But I think it is easier and the code is clearer enough to release it in its current status.

Any suggestion through comments are welcome.

[Eclipse] [HOWTO] Solve java.lang.OutOfMemoryError: PermGen space

Recently (since I have been using Eclipse for PHP developers) I am getting an error while executing Eclipse Helios and I try to commit a ‘non-simple’ task (for the IDE), like saving a project, cutting multiple code lines, auto-complete function, and so on:

  1. Foreword. OS and configuration
  2. Problem description
  3. Solution
1. Foreword: OS and configuration
  • Windows 7 Professional 64bits.
  • Eclipse Helios for PHP developers x64.
  • Oracle JDK 7u4.

2. Problem description: you might see below Eclipse’s output when the JVM crashes:

!SESSION 2012-04-28 18:15:40.832 -----------------------------------------------
eclipse.buildId=I20100608-0911
java.version=1.7.0_04
java.vendor=Oracle Corporation
BootLoader constants: OS=win32, ARCH=x86_64, WS=win32, NL=es_ES
Framework arguments: -product org.eclipse.epp.package.php.product
Command-line arguments: -os win32 -ws win32 -arch x86_64 -product org.eclipse.epp.package.php.product
!ENTRY org.eclipse.core.resources 2 10035 2012-04-28 18:16:06.184
!MESSAGE The workspace exited with unsaved changes in the previous session; refreshing workspace to recover changes.


!SESSION Tue May 01 13:36:02 CEST 2012 -----------------------------------------
!ENTRY org.eclipse.equinox.launcher 4 0 2012-05-01 13:36:02.532
!MESSAGE Exception launching the Eclipse Platform:
!STACK
java.lang.OutOfMemoryError: PermGen space

While on the first paragraph it is shown the information about the Eclipse launching (OS, Eclipse version, Java version…) on the second paragraph it is shown the error information:

java.lang.OutOfMemoryError: PermGen space

Which means, as stated here (which redirects to here):

PermGen is the permanent generation of objects in the VM (Class names, internalized strings, objects that will never get garbage-collected)

3. Solution.

Looking up through the Internet about this error, I found (again on the Eclipse wiki) that it is necessary to increase the amount of memory that the JVM is authorized to use. It can be achieved by changing the launching configuration file (eclipse.ini), enhancing the XXMaxPermSize and Xmx parameters (by default to 256m and 384m respectively) as shown below:

– Complete eclipse.ini content:


-startup
plugins/org.eclipse.equinox.launcher_1.1.0.v20100507.jar
--launcher.library
plugins/org.eclipse.equinox.launcher.win32.win32.x86_64_1.1.0.v20100503
-product
org.eclipse.epp.package.php.product
--launcher.defaultAction
openFile
--launcher.XXMaxPermSize
512M
-showsplash
org.eclipse.platform
--launcher.XXMaxPermSize
512m
--launcher.defaultAction
openFile
-vm
C:\Program Files\Java\jdk1.7.0_04\bin
-vmargs
-XX:MaxPermSize=512m
-Dosgi.requiredJavaVersion=1.5
-Xms40m
-Xmx1024m

Edit: It is important to add the “-XX:MaxPermSize=256m” line after “-vmargs” (in my case, I decided to put “-XX:MaxPermSize=512m”.

[Java] [Singleton Pattern] Why using Public classes with Private constructors?

We can find an example of a Public class with Private constructor below:

public class Products {

private static List<Product> listProducts = new ArrayList<Product>();
static {
for (int i = 0; i<19; i++) {
listProducts.add(new Producto(i, “producto ” + i));
}
}

private Products() {}

}

If we try to cast an instance of the class above we will obtain the following error:

GestionProductos example = new GestionProductos();

Error: The constructor GestionProductos() is not visible

So, how can we use this kind of class, and more important, why? well, the answer is simple. The designer has done the class in this way because he/she doesn’t want the class to be instanced. Although most of the times this behavior is a whimsy decission, it is a good practice for (like the class from the example above) a component delivered to a third, which is going to be forced to use only one instance from the class, avoiding unnecesary and memory spending copies from that class. For example, the class above is going to simulate the persistence layer, and we only want one copy of this layer,and the properties from the class are only accessible by the public setters and getters from the same class, like the following example:

List <Producto> listadoProducts = Products.getProducts();

This coding practice is called Singleton Pattern, or unique instance (the designers ensures that the class is going to be instanced only once).

Another use of a Public class with one private constructor could be, for example, to be instanced using other overloaded constructors, and these constructors would call the private constructor.