Showing posts with label algorithm. Show all posts
Showing posts with label algorithm. Show all posts

Friday, September 9, 2011

N-Queens Problem

The N-Queens problem consists in placing N queens in a NxN cheese board, so that none of them attack each other, as we show in the following figure:



The input of the problem is the N size of the board and the output its solution.

This is a nontrivial problem and there are many approaches to solve it such as constraint programming, logic programming or genetic algorithms.

The solution range is N^2*N so a brute force algorithm would take much time to solve it. For instance, in the N=3 case there would be (3*3)^3=387420489 possible placements.

I made a depth-first search (DFS) and backtracking (BT) algorithm to solve it.

In my proposed solution, the root of the tree represents the empty board and each node of the tree represents a different board configuration. On the other hand, the algorithm explores the branches of the tree (using DFS) that have a promising solution (BT), otherwise the branch is pruned and another one is explored.

In the following tree an example of the algorithm for N=4 is shown:



I implemented the algorithm in Java, for values of N larger than 14 you might need to increase the size of the java stack by adding -Xss8m in the java options as for these values there is a very deep recursion and it could be overflowed. The code is shown below:

/**
 * N-Queens Problem: Using Depth-First Search & Backtracking
 * @author gru
 */
public class Main {

    public static void NQueen(int N, int[][] board, int i, int j, boolean found) {

        //if found we return the result
        if (!found) {
            //check if the current position is valid
            if (IsValid(board, i, j)) {
                board[i][j] = 1;
                //Uncomment to track the partial results
                //System.out.println("[+]New Queen added at (" + i + "," + j + ")");
                //PrintBoard(board);
                
                //check if this was the last queen
                if (i == N - 1) {
                    found = true;
                    PrintBoard(board);
                }
                //call the next iteration
                NQueen(N, board, i + 1, 0, found);
            } else {
                //if the position is not valid
                //if it was the last row we do backtracking
                while (j >= N - 1) {
                    int[] a = BackTracking(board, i, j);
                    i = a[0];
                    j = a[1];
                    //Uncomment to track the partial results
                    //System.out.println("[+]Rolled back at (" + i + "," + j + ")");
                    //PrintBoard(board);
                }
                //we do the next call
                NQueen(N, board, i, j + 1, false);
            }
        }
    }

    public static int[] BackTracking(int[][] board, int i, int j) {
        int[] a = new int[2];
        for (int x = i; x >= 0; x--) {
            for (int y = j; y >= 0; y--) {
                //seeks the last queen
                if (board[x][y] != 0) {
                    //deletes the last queen and returns the position
                    board[x][y] = 0;
                    a[0] = x;
                    a[1] = y;
                    return a;
                }
            }
        }
        return a;
    }

    public static boolean IsValid(int[][] board, int i, int j) {

        int x;
        //check if there is any queen in the same column
        for (x = 0; x < board.length; x++) {
            if (board[i][x] != 0) {
                return false;
            }
        }
        //check if there is any queen in the same row
        for (x = 0; x < board.length; x++) {
            if (board[x][j] != 0) {
                return false;
            }
        }
        //check if there is any queen in the diagonals
        if (!IsSafeDiag(board, i, j)) {
            return false;
        }
        return true;
    }

    public static boolean IsSafeDiag(int[][] board, int i, int j) {

        int ii = i;
        int jj = j;
        while (jj >= 0 && ii >= 0 && ii < board.length && jj < board.length) {
            if (board[ii][jj] != 0) {
                return false;
            }
            jj++;
            ii++;
        }
        ii = i;
        jj = j;
        while (jj >= 0 && ii >= 0 && ii < board.length && jj < board.length) {
            if (board[ii][jj] != 0) {
                return false;
            }
            jj--;
            ii--;
        }
        ii = i;
        jj = j;
        while (jj >= 0 && ii >= 0 && ii < board.length && jj < board.length) {
            if (board[ii][jj] != 0) {
                return false;
            }
            jj--;
            ii++;
        }
        ii = i;
        jj = j;
        while (jj >= 0 && ii >= 0 && ii < board.length && jj < board.length) {
            if (board[ii][jj] != 0) {
                return false;
            }
            jj++;
            ii--;
        }
        return true;
    }

    public static void PrintBoard(int[][] board) {
        System.out.print(" ");
        for (int j = 0; j < board.length; j++) {
            System.out.print(j);
        }
        System.out.print("\n");
        for (int i = 0; i < board.length; i++) {
            System.out.print(i);
            for (int j = 0; j < board.length; j++) {
                if (board[i][j] == 0) {
                    System.out.print(" ");
                } else {
                    System.out.print("Q");
                }
            }
            System.out.print("\n");
        }
    }
    
    public static void main(String[] args) {

        //we parse the input, which is the size of the problem
        int N = Integer.parseInt(args[0]);

        //we create a board
        int[][] board = new int[N][N];

        //we call the method that solves the problem
        NQueen(N, board, 0, 0, false);
    }
}

Friday, September 2, 2011

The Led Clock Problem

This morning I had some free time and I made The Clock of the Tuenti Programming Contest.

In this problem we have a digital (7 led segment) clock and we have to count how many times will the individual leds turn on after X seconds (starting form 00:00:00 position).


We have to take into account that every second all leds turn off and then the ones of the next position will turn on.

Sample Input:
0
4

Sample output:
36
172

I made a quite simple solution for Java:
  1. We parse the input.
  2. For each second we calculate the value that each led will have.
  3. We calculate the number of leds on for each of the previous led value and add all of them.
  4. We print the final result.

This solution has a complexity in big O notation of O(6*N) being N the input number of seconds.

The code is shown below:
/**
 * problem http://contest.tuenti.net/Question_6.html
 * @author gru
 */
public class Main {

    //these constants contain the number of leds on for each number
    static final int zero = 6;
    static final int one = 2;
    static final int two = 5;
    static final int three = 5;
    static final int four = 4;
    static final int five = 5;
    static final int six = 6;
    static final int seven = 3;
    static final int eight = 7;
    static final int nine = 6;

    public static void main(String[] args) {

        //parse the input (time in seconds)
        int input = Integer.parseInt(args[0]);

        //count will contain the output
        int count = 0;

        //each iteration calculates one second
        for (int i = 0; i <= input; i++)
            count += toTime(i);

        //print out the result
        System.out.println(count);
    }

    //this method converts seconds to a real hour
    private static int toTime(int i) {
        int count = 0;

        //hours units
        count += toLeds((i / 6000) % 10);
        //hours tens
        count += toLeds(((i / 6000) % 100) / 10);

        //minutes units
        count += toLeds((i / 60) % 10);
        //minutes tens
        count += toLeds(((i / 60) % 100) / 10);

        //seconds units
        count += toLeds((i % 60) % 10);
        //seconds tens
        count += toLeds(((i % 60) % 100) / 10);

        return count;
    }

    //this method returns the # of leds turned on for each digit (0-9)
    private static int toLeds(int i) {

        if (i == 0)
            return zero;
        else if (i == 1)
            return one;
        else if (i == 2)
            return two;
        else if (i == 3)
            return three;
        else if (i == 4)
            return four;
        else if (i == 5)
            return five;
        else if (i == 6)
            return six;
        else if (i == 7)
            return seven;
        else if (i == 8)
            return eight;
        else
            return nine;
    }
}

Thursday, August 25, 2011

The Milkman Problem

Tuenti recently made the Tuenti Programming Contest 2011 where they  proposed some programming problems.

One of these problems is The Milkman Problem where there is a group of cows for sale, each with different milk production and weight, and we also have a truck with a weight limit.
We have to decide what cows we buy and transfer in our track maximizing the amount of milk production per day. 

Input 4 parameters:
Number of cows available for sale, e.g. 6
Truck weight limit in kilograms, e.g. 700
Comma-separated list of cow weights, e.g. 360,250,400,180,50,90
Comma-separated list of cow milk production, e.g. 40,35,43,28,12,13
Output 93

Sample input
6 700 360,250,400,180,50,90 40,35,43,28,12,13
8 1000 223,243,100,200,200,155,300,150 30,34,28,45,31,50,29,28
10 2000 340,355,223,243,130,240,260,155,302,130 45,50,34,39,29,40,30,52,31,29
Sample output
93
188
320

I made a recursive algorithm that does an iteration per cow. In each iteration it checks whether taking or not the cow we get a optimal solution and returns the higher one.

The complexity of the algorithm in the big O notation is O(N^2) being N the number of cows.

public final class Main {

	public static void main(String args[]) {

		// we parse the input
		int tCows = Integer.parseInt(args[0]);
		int tWeight = Integer.parseInt(args[1]);
		String[] wei = args[2].split(",");
		String[] prod = args[3].split(",");

		// we print the solution given the the MaxProduction method
		System.out.println(MaxProduction(tCows, tWeight, wei, prod, 0, 0, 0));
	}

	private static int MaxProduction(int tCows, int tWei, String[] wei,
			String[] prod, int iter, int aProd, int aWei) {

		// we check if there are cows left to process
		if (iter < tCows) {

			// we make sure not to exceed the weight restrictions imposed
			if (aWei + Integer.parseInt(wei[iter]) <= tWei) {

				// we return the higher production between taking or not the current cow
				return Math.max(Math.max(
						MaxProduction(tCows, tWei, wei, prod, iter + 1, aProd
								+ Integer.parseInt(prod[iter]),
								aWei + Integer.parseInt(wei[iter])), aProd),
						Math.max(
								MaxProduction(tCows, tWei, wei, prod, iter + 1,
										aProd, aWei), aProd));
			} else {
				// we do not take the current cow as it does not fit
				return MaxProduction(tCows, tWei, wei, prod, iter + 1, aProd,
						aWei);
			}
		}
		return aProd;
	}

}

Monday, August 22, 2011

NxN numbers spiral

This evening I was reading a forum about questions google ask to software engineers during job interviews and it came to my mind a programming challenge that Softonic made me and my classmates the second year of my BCS.

The problem consists in printing a spiral array of a given size. The input of the program is the size of the spiral, and the output is the spiral itself.

For instance, for N=4 we would get the following output:
00 01 02 03 
11 12 13 04 
10 15 14 05 
09 08 07 06 

For N=11, the output would be:
000 001 002 003 004 005 006 007 008 009 010 
039 040 041 042 043 044 045 046 047 048 011 
038 071 072 073 074 075 076 077 078 049 012 
037 070 095 096 097 098 099 100 079 050 013 
036 069 094 111 112 113 114 101 080 051 014 
035 068 093 110 119 120 115 102 081 052 015 
034 067 092 109 118 117 116 103 082 053 016 
033 066 091 108 107 106 105 104 083 054 017 
032 065 090 089 088 087 086 085 084 055 018 
031 064 063 062 061 060 059 058 057 056 019 
030 029 028 027 026 025 024 023 022 021 020 

The solution is quite easy, I implemented it in java, the code basically creates an array of N size, and there are 4 for loops in a main for loop, these fill the array, one for loop each side of the spiral, as shown in the following figure:




The last part of the code (lines 46 to 53) are a little bit tricky, I had to make this to have zeros padded properly to have a good-looking output (same number of digits for each array value).

The complexity of the code in big O notation is O(N^2).



I think it can be useful to somebody. Any suggestion to improve it will be appreciated.

Thursday, August 18, 2011

document.getElementsByTagName('title')[0].innerHTML="hello world";

Even though I am finishing my vacations and coming back to office on Monday, I decided to create this weblog to write some random stuff.

The blog pretends to share my concerns about different topics related to software engineering, information security and maybe others with whoever is interested in.

Topics will change as my interests and scene do, so far I have start reading two books about algorithm design and working on some problems and I think the firsts posts will be about this. The books I am reading are The Algorithm Design Manual and Introduction to Algorithms but as I said I am also working on some other problems I will explain in other messages.

I guess this is all for today, I am still setting up the blog, deciding the graphic stuff, and choosing the gadgets I find useful.