====== The Rubik's cube 2 by 2 ======
{{ :java:cubo_rubik_2x2.jpg?direct&100 |}}
Because I'm not good at all at solving this puzzle, I've decided to give Java an opportunity to solve it for me. 
So, I've made a program to solve the rubik's cube. If you want to simply run the program, here it is:
{{:java:rubik.zip|}}
Just uncompress the contents of this zip file and you will find a file called ''rubik.jar''. Run it using the following command: 
java -jar rubik.jar
And you the program will start. 
Remember that the faces of the cube must be read as if you were reading a text: from left to right, topmost to bottom. 
And the source code of the project: 
{{:java:rubik_src.zip|}}
===== My comments =====
The data structure I've choose for the cube is in fact a 4x4 matrix of colors:
public class Cube22 implements Cube {
	private static final int SIDE_SIZE = 2;
	private static final String nl = System.getProperty("line.separator");
	private Color[][][] cube = new Color[SIDE_SIZE+2][SIDE_SIZE+2][SIDE_SIZE+2];
	
	// default constructor: a cube 
	// with all the colors correct
	public Cube22()
	{
	    /*
	     *        TOP OF THE CUBE
	     *  +-+-+-+-+
         *  | | | | |
         *  +-+-+-+-+
         *  | |b|b| |
         *  +-+-+-+-+
         *  | |b|b| |
         *  +-+-+-+-+
         *  | | | | |
         *  +-+-+-+-+
	     */
        cube[0][0][0] = Color.NOCOLOR; cube[1][0][0] = Color.NOCOLOR; cube[2][0][0] = Color.NOCOLOR; cube[3][0][0] = Color.NOCOLOR;
        cube[0][1][0] = Color.NOCOLOR; cube[1][1][0] = Color.BLUE;    cube[2][1][0] = Color.BLUE;    cube[3][1][0] = Color.NOCOLOR;
        cube[0][2][0] = Color.NOCOLOR; cube[1][2][0] = Color.BLUE;    cube[2][2][0] = Color.BLUE;    cube[3][2][0] = Color.NOCOLOR;
        cube[0][3][0] = Color.NOCOLOR; cube[1][3][0] = Color.NOCOLOR; cube[2][3][0] = Color.NOCOLOR; cube[3][3][0] = Color.NOCOLOR;
        /*
         *        VERTICAL COLORS, 1
         *  +-+-+-+-+
         *  | |V|V| |
         *  +-+-+-+-+
         *  |W| | |Y|
         *  +-+-+-+-+
         *  |W| | |Y|
         *  +-+-+-+-+
         *  | |R|R| |
         *  +-+-+-+-+
         */
        cube[0][0][1] = Color.NOCOLOR; cube[1][0][1] = Color.VIOLET;  cube[2][0][1] = Color.VIOLET;  cube[3][0][1] = Color.NOCOLOR;
        cube[0][1][1] = Color.WHITE;   cube[1][1][1] = Color.NOCOLOR; cube[2][1][1] = Color.NOCOLOR; cube[3][1][1] = Color.YELLOW;
        cube[0][2][1] = Color.WHITE;   cube[1][2][1] = Color.NOCOLOR; cube[2][2][1] = Color.NOCOLOR; cube[3][2][1] = Color.YELLOW;
        cube[0][3][1] = Color.NOCOLOR; cube[1][3][1] = Color.RED;     cube[2][3][1] = Color.RED;     cube[3][3][1] = Color.NOCOLOR;
        /*
         *        VERTICAL COLORS, 2
         *  +-+-+-+-+
         *  | |V|V| |
         *  +-+-+-+-+
         *  |W| | |Y|
         *  +-+-+-+-+
         *  |W| | |Y|
         *  +-+-+-+-+
         *  | |R|R| |
         *  +-+-+-+-+
         */
        cube[0][0][2] = Color.NOCOLOR; cube[1][0][2] = Color.VIOLET;  cube[2][0][2] = Color.VIOLET;  cube[3][0][2] = Color.NOCOLOR;
        cube[0][1][2] = Color.WHITE;   cube[1][1][2] = Color.NOCOLOR; cube[2][1][2] = Color.NOCOLOR; cube[3][1][2] = Color.YELLOW;
        cube[0][2][2] = Color.WHITE;   cube[1][2][2] = Color.NOCOLOR; cube[2][2][2] = Color.NOCOLOR; cube[3][2][2] = Color.YELLOW;
        cube[0][3][2] = Color.NOCOLOR; cube[1][3][2] = Color.RED;     cube[2][3][2] = Color.RED;     cube[3][3][2] = Color.NOCOLOR;
        /*
         *        BOTTOM OF THE CUBE
         *  +-+-+-+-+
         *  | | | | |
         *  +-+-+-+-+
         *  | |G|G| |
         *  +-+-+-+-+
         *  | |G|G| |
         *  +-+-+-+-+
         *  | | | | |
         *  +-+-+-+-+
         */
        cube[0][0][3] = Color.NOCOLOR; cube[1][0][3] = Color.NOCOLOR; cube[2][0][3] = Color.NOCOLOR; cube[3][0][3] = Color.NOCOLOR;
        cube[0][1][3] = Color.NOCOLOR; cube[1][1][3] = Color.GREEN;   cube[2][1][3] = Color.GREEN;   cube[3][1][3] = Color.NOCOLOR;
        cube[0][2][3] = Color.NOCOLOR; cube[1][2][3] = Color.GREEN;   cube[2][2][3] = Color.GREEN;   cube[3][2][3] = Color.NOCOLOR;
        cube[0][3][3] = Color.NOCOLOR; cube[1][3][3] = Color.NOCOLOR; cube[2][3][3] = Color.NOCOLOR; cube[3][3][3] = Color.NOCOLOR;
	    
	} // Cube22
	
    @Override
    public Color getColor( int x, int y, int z )
    {
        return cube[x][y][z];
    }
    @Override
    public void setColor( int x, int y, int z, Color color )
    {
        cube[x][y][z] = color;
    }
	
    @Override
    public Cube getCopy()
    {
        Cube22 result = new Cube22();
        
        for( int x = 0; x < 4; x++ )
            for( int y = 0; y < 4; y++ )
                for( int z = 0; z < 4; z++ )
                {
                    result.setColor(x, y, z, getColor(x, y, z));
                }
        
        return result;
        
    } // getCopy 
    
	@Override
	public String toString()
	{
	    StringBuilder out = new StringBuilder();
	    
	    out.append( "        ____________ " ); out.append( nl );
	    out.append( "       /     /     /|" ); out.append( nl ); 
	    out.append( "      /  "+Color.toString(cube[1][1][0])+"  /   "+Color.toString(cube[2][1][0])+" / |" ); out.append( nl );
	    out.append( "     /_____/_____/ "+Color.toString(cube[3][1][1])+"|" ); out.append( nl );
	    out.append( "    /     /     /|  ," ); out.append( nl );
	    out.append( "   /  "+Color.toString(cube[1][2][0])+"  /   "+Color.toString(cube[2][2][0])+" / | /|" ); out.append( nl );
	    out.append( "  /_____/_____/  |/ |" ); out.append( nl );
	    out.append( "  |     |     |"+Color.toString(cube[3][2][1])+" / "+Color.toString(cube[3][1][2])+"," ); out.append( nl ); 
	    out.append( "  |  "+Color.toString(cube[1][3][1])+"  |  "+Color.toString(cube[2][3][1])+"  | /| / " ); out.append( nl );
	    out.append( "  |_____|_____|/ |/  " ); out.append( nl );
	    out.append( "  |     |     |"+Color.toString(cube[3][2][2])+" /   " ); out.append( nl );
	    out.append( "  |  "+Color.toString(cube[1][3][2])+"  |  "+Color.toString(cube[2][3][2])+"  | /    " ); out.append( nl );
	    out.append( "  |_____|_____|/     " ); out.append( nl );
	    
	    return out.toString();
	} // toString
	
	/**
	 * Return true if the cube is solved, in other words, all the colors 
	 * are grouped in the same face of the cube.
	 * 
	 * @return
	 */
	@Override
	public boolean isSolved()
	{
        boolean facade1;
        boolean facade2;
        boolean facade3;
        boolean facade4;
        boolean facade5;
        boolean facade6;
        
	    facade1 = cube[1][1][0] == cube[2][1][0] && cube[2][1][0] == cube[1][2][0] && cube[1][2][0] == cube[2][2][0];
        facade2 = cube[3][2][1] == cube[3][1][1] && cube[3][1][1] == cube[3][1][2] && cube[3][1][2] == cube[3][2][2];
        facade3 = cube[1][3][1] == cube[2][3][1] && cube[2][3][1] == cube[1][3][2] && cube[1][3][2] == cube[2][3][2];
        facade4 = cube[1][1][3] == cube[2][1][3] && cube[2][1][3] == cube[1][2][3] && cube[1][2][3] == cube[2][2][3];
        facade5 = cube[0][2][1] == cube[0][1][1] && cube[0][1][1] == cube[0][1][2] && cube[0][1][2] == cube[0][2][2];
        facade6 = cube[1][0][1] == cube[2][0][1] && cube[2][0][1] == cube[1][0][2] && cube[1][0][2] == cube[2][0][2];
        
        return facade1 && facade2 && facade3 && facade4 && facade5 && facade6;
	}
	
	
	/**
	 * Determine if two cubes are equal regardless of their orientation.
	 * This is important because this, applied to the search algorithm
	 * prevents to explore branches that in fact are the seame than a 
	 * previous one but with the colors rotated. 
	 * 
	 */
	@Override
	public boolean equals( Object comp )
	{
	    if( this == comp )
	        return true; 
	    if( comp instanceof Cube22 )
	    {
	        Cube22 compCube = (Cube22) comp; 
	        return equalsXYZ(compCube);
	    }
	    else
	        return false;
	} // equals
	
   public boolean equalsXYZ( Cube compCube )
    {
        boolean equal = true; 
        for( int x = 0; x < SIDE_SIZE+2 && equal; x++ )
            for( int y = 0; y < SIDE_SIZE+2 && equal; y++ )
                for( int z = 0; z < SIDE_SIZE+2 && equal; z++ )
                    equal = equal && (cube[x][y][z] == compCube.getColor(x, y, z));
        return equal;
    } // equals
	
}
After two days developing (in my spare time) I've realized that it was a wrong decision, because there is a better way to store the cube and allow the rotation operations to be more easy: is to create a ''sticker'' data structure and link the stickers between them. Thus, the operation of rotation of the cube is more easy and less error prone. 
An idea of what it would be:
class Sticker
{
   private Sticker north; 
   private Sticker south; 
   private Sticker east;
   private Sticker west; 
   private Sticker northCorner; 
}
So, the cube is constructer by linking the respective north, south, east ... links between them. But I think it would be needed to keep a link in order to know the orientation of the cube (to know what is ''up'' and ''down''): because of this is necessary this ''northCorner'', who will be set with a value only with one sticker.