2

Say there's a 2d boolean array

boolean[][] = {  x  x  x  x  x  x  x
                 x  x  x  x  x  x  x
                 x  x  x  x  x  x  x
                 x  x  x  x  x  x  x  }

Criteria:

  1. Each column must have 2 'true'
  2. Each row cannot have more than 4 'true'

For example a solution can be:

boolean[][] = {  T  T  T  T  F  F  F
                 T  T  T  T  F  F  F
                 F  F  F  F  T  T  T
                 F  F  F  F  T  T  T  }

Another one:

boolean[][] = {  T  F  T  F  F  T  T
                 F  T  T  T  F  F  F
                 F  F  F  T  T  T  F
                 T  T  F  F  T  F  T  }

How to write a recursive function to find out all possible combinations given the two criteria above?

I wish I can show something that I tried, but I don't even know how to start. I tried to solve this by using object oriented way, by creating class for the row or column but doesn't seem to help simplifying it since the rows and columns are closely affecting each other.

Thanks in advance!

9
  • Must it be a recursive function? Commented Aug 27, 2014 at 0:51
  • if time isn't an issue you can do a simple bruteforce backtracking. Commented Aug 27, 2014 at 1:01
  • Doesn't need to be recursive, as long as it works. @MateuszDymczyk can you show an example code on how to do bruteforce backtracking? Sounds like a built in thing for languages such as Prolog, but for Java do we need to download third party library? Commented Aug 27, 2014 at 1:39
  • @Bruce backtracking is just a technique which incrementally tries to build a solution (well more of a candidate) and then evaluates it. If at some point the evaluation fails you go back to the previous good state (you backtrack) and try other states from that point. This will create a search tree, where leaves will have candidate solutions. You will try go cell by cell (row by row or column by column) and try both states for each cell "F" and "T". Each time you check the state of that row/column and either move to the next one or backtrack. You have a solution when you hit bottom right corner. Commented Aug 27, 2014 at 1:47
  • This would find me a solution, but how to intelligently loop it so we can find all possible solutions to the problem? (each one of them unique by its own) Commented Aug 27, 2014 at 2:10

1 Answer 1

2
static final int NB_ROWS = 4;
static final int NB_COLUMNS = 7;

public static void main(String[] args) {

    boolean[][] initialState = new boolean[NB_ROWS][NB_COLUMNS];
    //everything is initialize to false
    System.out.println(algo(initialState, 0, 0, 0));

}

//path: column by column
public static int algo(boolean[][] state, int currentRow, int currentColumn, int acc) {
    if(currentColumn == NB_COLUMNS) { //end of the array reached
        return acc + 1;
    }
    if(currentRow == NB_ROWS) { //end of the column reached
        if(checkColumn(state, currentColumn)) { //the current column meets requirements
            return algo(state, 0, currentColumn+1, acc);
        } else {
            return acc;
        }
    }
    state[currentRow][currentColumn] = true; //try with true at the given coordinates
    if(checkRow(state, currentRow)) { //current row meets the requirements
        acc += algo(state, currentRow+1, currentColumn, 0); //start with a fresh counter
    }
    state[currentRow][currentColumn] = false; //try with false at the given coordinates
    // no need to check row with a false value
    return algo(state, currentRow+1, currentColumn, acc);
}

public static boolean checkColumn(boolean[][] state, int currentColumn) {
    int count = 0;
    for(int i=0; i<NB_ROWS; i++) {
        if(state[i][currentColumn])
            count++;
    }
    return count == 2;
}

public static boolean checkRow(boolean[][] state, int currentRow) {
    int count = 0;
    for(int i=0; i<NB_COLUMNS; i++) {
        if(state[currentRow][i])
            count++;
    }
    return count <= 5;
}

I put some comments in the code to explain what I am doing, but with english words.

At any given point in a recursive call: try to put T in cell (p,q). If it does not break a row condition, call the algorithm on cell (p+1,q). After, in both cases, put a F in cell (p,q) and calls the algorithm on cell (p+1,q).

When calling the algorithm on cell (p,q), first check that the coordinates are inside the array. If p is greater than the row number, check that the column condition is met, and calls the algorithm on cell (0,q+1). If q is greater than the column number, you have reach the end of the array, and you just return the accumulator (number of "winning" situation already found) + 1.

Tested for 3 rows and 4 columns, it returns 81 = 3*3*3*3, which is indeed the good result (3 possibilities for each column, and no row constraints since 4 < 5).

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks a lot! Will try this as soon as I have the chance!
Confirmed that this works... you're awesome! Your code is slightly more advanced than the one used to solve n-Queen chess board puzzle, and now I understand recursion and recursive backtracking a lot more! Thanks!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.