[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.

Advertisements

Ubuntu 12.04: how to fix the wifi interface using Ralink RT3090 card

After the issues appeared on previous versions of Ubuntu (related here: Ubuntu 11.10 WIFI problems with RT3090), I have good news for you: it seems that the driver issues has been solved on the new kernel version that the Precise Pangolin version of Ubuntu uses. Although, we need to follow some steps to rise it up:

  1. Check the wireless card status (sudo iwlist scan). You can see on the bottom the printed information on the terminal. For the sake of this tutorial, you must see any WIFI network. If you are not able to see any, maybe you should try another fix, out from this page (here – post #71).
  2. Disable wireless energy management: sudo iwconfig wlan0 power off. You can also remain it disable after reboot as it is explained here.
  3. From this step we will be able to see the different WIFI networks that we have around, We can try to connect through the upper toolbar, using the wireless network manager. The manager will ask the password, but the connection will not succeed.
  4. Using the same energy manager, we must click on the “Disconnect” menu option, and just followed connect again, and retry the connection with the WIFI network.

[EDIT]

Detected some troubles to keep stable the connection, or even to connect (continuously asking for the Wireless password). Nevertheless, I have had some good results that I am going to deeply check:
1) Edition of the file /etc/networks:

sudo gedit /etc/network

This is the current content of that file (wrong content, I know):

#auto lo
#iface lo inet loopback
auto wlan0
iface wlan0 inet dhcp
wireless_mode Managed
wireless_essid vodafoneE503 key XXXXXXXXXX
wireless_channel auto
wireless_rate 54G
#wpa-conf /etc/wpa_supplicant.conf

After saving the file, you must restart the networking:

sudo /etc/init.d/networking restart

And then, it will be able to connect to the wireless network with a stable speed.

[/EDIT]

After step four, you should get a message “Connection established with Network YourNetwork“. In my case, the speed is quite optimum, as you can see below:

Image

-Terminal output after step 1:

ubuntu@ubuntu:~$ sudo iwlist scan
lo        Interface doesn't support scanning.

wlan0     Scan completed :
Cell 01 - Address: 00:1A:2B:14:12:71
Channel:3
Frequency:2.422 GHz (Channel 3)
Quality=51/70  Signal level=-59 dBm
Encryption key:on
ESSID:"WLAN_D9"
Bit Rates:1 Mb/s; 2 Mb/s; 5.5 Mb/s; 11 Mb/s
Bit Rates:6 Mb/s; 9 Mb/s; 12 Mb/s; 18 Mb/s; 24 Mb/s
36 Mb/s; 48 Mb/s; 54 Mb/s
Mode:Master
Extra:tsf=00000005dbc312a7
Extra: Last beacon: 868ms ago
IE: Unknown: 0007574C414E5F4439
IE: Unknown: 010482848B96
IE: Unknown: 030103
IE: Unknown: 2A0100
IE: Unknown: 2F0100
IE: Unknown: 32080C1218243048606C
IE: Unknown: DD06001018020104
Cell 02 - Address: 64:16:F0:08:E5:04
Channel:6
Frequency:2.437 GHz (Channel 6)
Quality=70/70  Signal level=-27 dBm
Encryption key:on
ESSID:"vodafoneE503"
Bit Rates:1 Mb/s; 2 Mb/s; 5.5 Mb/s; 6 Mb/s; 9 Mb/s
11 Mb/s; 12 Mb/s; 18 Mb/s
Bit Rates:24 Mb/s; 36 Mb/s; 48 Mb/s; 54 Mb/s
Mode:Master
Extra:tsf=000000014beec83f
Extra: Last beacon: 600ms ago
IE: Unknown: 000C766F6461666F6E6545353033
IE: Unknown: 010882848B0C12961824
IE: Unknown: 030106
IE: Unknown: 200100
IE: WPA Version 1
Group Cipher : CCMP
Pairwise Ciphers (1) : CCMP
Authentication Suites (1) : PSK
IE: Unknown: 2A0104
IE: Unknown: 32043048606C
IE: Unknown: DD180050F2020101020003A4000027A4000042435E0062322F00
IE: Unknown: DD1E00904C334E101BFFFF000000000000000000000000000000000000000000
IE: Unknown: 2D1A4E101BFFFF000000000000000000000000000000000000000000
IE: Unknown: DD1A00904C3406051900000000000000000000000000000000000000
IE: Unknown: 3D1606051900000000000000000000000000000000000000
IE: Unknown: DD0900037F01010000FF7F
IE: Unknown: DD0A00037F04010020000000
IE: Unknown: 0706455320010D14
Cell 03 - Address: 64:16:F0:79:7C:BA
Channel:6
Frequency:2.437 GHz (Channel 6)
Quality=51/70  Signal level=-59 dBm
Encryption key:on
ESSID:"Orange-7cba"
Bit Rates:1 Mb/s; 2 Mb/s; 5.5 Mb/s; 6 Mb/s; 9 Mb/s
11 Mb/s; 12 Mb/s; 18 Mb/s
Bit Rates:24 Mb/s; 36 Mb/s; 48 Mb/s; 54 Mb/s
Mode:Master
Extra:tsf=000000045d131b6a
Extra: Last beacon: 668ms ago
IE: Unknown: 000B4F72616E67652D37636261
IE: Unknown: 010882848B0C12961824
IE: Unknown: 030106
IE: Unknown: 0706455320010D14
IE: Unknown: 2A0100
IE: Unknown: 32043048606C
IE: WPA Version 1
Group Cipher : TKIP
Pairwise Ciphers (1) : TKIP
Authentication Suites (1) : PSK
IE: Unknown: DD140050F204104A000110104400010210080002018C
Cell 04 - Address: 02:30:B4:C4:58:C0
Channel:12
Frequency:2.467 GHz (Channel 12)
Quality=51/70  Signal level=-59 dBm
Encryption key:on
ESSID:"ONO9392"
Bit Rates:1 Mb/s; 2 Mb/s; 5.5 Mb/s; 11 Mb/s
Bit Rates:6 Mb/s; 9 Mb/s; 12 Mb/s; 18 Mb/s; 24 Mb/s
36 Mb/s; 48 Mb/s; 54 Mb/s
Mode:Master
Extra:tsf=00000252801bb1ea
Extra: Last beacon: 280ms ago
IE: Unknown: 00074F4E4F39333932
IE: Unknown: 010482848B96
IE: Unknown: 03010C
IE: Unknown: 0706455320010D14
IE: Unknown: 2A0100
IE: Unknown: 32080C1218243048606C
IE: Unknown: DD180050F202010100000364000027A4000041435E0061322F00
IE: Unknown: DD050010910400
Cell 05 - Address: 72:A8:E4:4E:2E:A8
Channel:11
Frequency:2.462 GHz (Channel 11)
Quality=63/70  Signal level=-47 dBm
Encryption key:on
ESSID:"vodafone2EA9"
Bit Rates:1 Mb/s; 2 Mb/s; 5.5 Mb/s; 11 Mb/s; 9 Mb/s
18 Mb/s; 36 Mb/s; 54 Mb/s
Bit Rates:6 Mb/s; 12 Mb/s; 24 Mb/s; 48 Mb/s
Mode:Master
Extra:tsf=000001adf40ca534
Extra: Last beacon: 356ms ago
IE: Unknown: 000C766F6461666F6E6532454139
IE: Unknown: 010882848B961224486C
IE: Unknown: 03010B
IE: Unknown: 2A0104
IE: Unknown: 32040C183060
IE: Unknown: 2D1A8E1117FFFF0000010000000000000000000000000C0000000000
IE: Unknown: 3D160B000600000000000000000000000000000000000000
IE: Unknown: 3E0100
IE: WPA Version 1
Group Cipher : CCMP
Pairwise Ciphers (1) : CCMP
Authentication Suites (1) : PSK
IE: Unknown: DD180050F2020101000003A4000027A4000042435E0062322F00
IE: Unknown: 0B05020009127A
IE: Unknown: 4A0E14000A002C01C800140005001900
IE: Unknown: 7F0101
IE: Unknown: DD07000C4304000000
IE: Unknown: 0706455320010D10
IE: Unknown: DD1E00904C338E1117FFFF0000010000000000000000000000000C0000000000
IE: Unknown: DD1A00904C340B000600000000000000000000000000000000000000
Cell 06 - Address: 02:30:B4:C4:58:C1
Channel:12
Frequency:2.467 GHz (Channel 12)
Quality=53/70  Signal level=-57 dBm
Encryption key:on
ESSID:"ONO0607"
Bit Rates:1 Mb/s; 2 Mb/s; 5.5 Mb/s; 11 Mb/s
Bit Rates:6 Mb/s; 9 Mb/s; 12 Mb/s; 18 Mb/s; 24 Mb/s
36 Mb/s; 48 Mb/s; 54 Mb/s
Mode:Master
Extra:tsf=00000252801b8eb1
Extra: Last beacon: 288ms ago
IE: Unknown: 00074F4E4F30363037
IE: Unknown: 010482848B96
IE: Unknown: 03010C
IE: Unknown: 0706455320010D14
IE: Unknown: 2A0100
IE: Unknown: 32080C1218243048606C
IE: WPA Version 1
Group Cipher : TKIP
Pairwise Ciphers (1) : TKIP
Authentication Suites (1) : PSK
IE: Unknown: DD180050F202010100000364000027A4000041435E0061322F00
IE: Unknown: DD050010910400

eth0      Interface doesn't support scanning.

[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”.

[HOWTO] Use AJAX to send a file through a form

As you know, AJAX is used to asynchronously transfer information from the client to the server without refreshing the web page. You normally use it as follows:

1) Client side HTML form code:

<div id="formulary">
<form name="example" method = "POST" enctype="multipart/form-data" onsubmit="send_form()">
<input type="text" name="param1">
<input type="text" name="param2">
<input type="submit" value="Cargar archivo" />
</form>
</div>

2) Client side AJAX script (Javascript):

<script>
function send_form(){
if (window.XMLHttpRequest)
{// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp=new XMLHttpRequest();
}
else
{// code for IE6, IE5
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange=function(){
if (xmlhttp.readyState==4){
if (xmlhttp.status==200 || window.location.href.indexOf("http")==-1){
document.getElementById("divresponse").innerHTML=xmlhttp.responseText;
}
else{
alert("An error has occured making the request");
}
}
}
//parameters for the POST request
var parameter1 =encodeURIComponent(document.getElementById("parameter1").value);
var usuariovalue=encodeURIComponent(document.getElementById("parameter2").value);
var parameters="parameter1"="+ parameter1+"&amp; parameter2="+ parameter2;

//open asynchronous connection, indicating the sending method, the webpage receiver, and “true”, which means the proper asynchronous sending
xmlhttp.open(“POST”, “sendform.php”, true);
xmlhttp.setRequestHeader(“Content-type”, “application/x-www-form-urlencoded”);
xmlhttp.send(parameters);
}

2) Server side (PHP, for example):

<?php
echo 'parameters: ' . $_POST['parameter1'] . $_POST['parameter2']
?>

But the problem is that XMLHttpRequest was not thought to send a file within. There are different implementations to solve it, the most extended one is shown below. It consists on reloading the page into an invisible , sending the output from the form into this :

1)Client side (HTML):

<div id="message"></div>

2)Server side (PHP):

<?php
$tmp = $_FILES['fichero']['tmp_name'];
//check if the file has been sent
if(isset($_FILES['fichero'])){
//definitely file route (where you want the file to be stored into the server)
$name = "../folder/" . $_FILE['usuario'] . end(explode(".", $tmp)+1);
if(move_uploaded_file($tmp, $name)){
//the file has been succesfully received and stored
echo '
<script>
parent.document.getElementById("mensaje").innerHTML="file received";
new_f.type="file";
new_f.name="fichero";
new_f.value="";
new_f.id="fichero";
new_f.onchange=function(){
parent.document.getElementById("message").innerHTML="";
}
old_f.parentNode.replaceChild(new_f,old_f);
</script>';
exit;
}
}
?>

[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.

Ubuntu 11.10: how to change double tap action in a Synaptics touchpad

By default, using a Synaptics touchpad, Ubuntu 11.10 configures double tap as a right-click button. Nothing in this way can be changed through System Settings. All you need to use is the synclient command:

kortax@kortaxubuntu:~$ synclient
Parameter settings:
LeftEdge                = 105
RightEdge               = 2339
TopEdge                 = 63
BottomEdge              = 989
FingerLow               = 24
FingerHigh              = 29
(…)
LBCornerButton          = 0
TapButton1              = 1
TapButton2              = 3
TapButton3              = 2
ClickFinger1            = 1
(…)

The bolded attribute means that double tap is configured to act as a right click. What we need is to change TapButton2 value to 2:

kortax@kortaxubuntu:~$ synclient TapButton2=2

Via: askubuntu.com

Ubuntu 11.10: avoid wireless network energy management

By Default, Ubuntu 11.10, comes with a very awkward energy management policy: when you switch off the power cable or you come from a sleep, the wireless network card turns instantly off. Besides, if your wireless card doesn’t work properly as mine (RT3090), maybe this policy can bring you some unexpected headaches.

The solution is to create a text file, located in /etc/pm/power.d/ and name it wireless:

sudo gedit /etc/pm/power.d/wireless

With the following content:

#!/bin/sh

/sbin/iwconfig wlan0 power off

In addition, it is necessary to give “read” and “write” permissions to all users:

sudo chmod 777 /etc/pm/power.d/wireless

All we have to do now is to reboot. Energy Manager will not disconnect again the WIFI card.

Source: askubuntu.com