Knights tour problem with an irregular chessboard - java

the knights tour problem is a problem based on backtracking. In the normal version you have a N*N chessboard and you have to visit every single field on the board with your knight. But here comes the real problem: I can visit every field only once! So if i have no more fields to visit, i have to backtrack. At the end of your game, the number of fields should equals the number of movements. Now to my different version: I'm not working with a N*N chessboard, but with an irregular one. For example: The first row has 5 fields, the second one has 3, and the third one 8. These information are given me by a boolean array. There are also "false" fields that are not allowed to visit. I'm not allowed to change the boolean array.
public static boolean checkboard(boolean[][] board) {
for (int i0 = 0; i0 < board.length; i0++) {
boolean[] dim1 = board[i0];
if (dim1 == null) {
return false;
} if (board.length == 1) {
return false;
}
}
return true;
}
This is the first part of my code. It checks if the board (boolean array) is valid. That means it should give me false if at least one row is null or if there are no rows.
public static boolean checkPoint(boolean[][] board, int i, int j) {
try {
boolean test = board[i][j];
} catch (IndexOutOfBoundsException a) {
return false;
}
return true;
}
This method checks if the point is in the array.
public static boolean isValid(int i, int j, int[][] sol, boolean[][] board) {
if (i >= 0 && j >= 0 && sol[i][j] == -1 && board[i][j] != false && checkPoint(board,i,j)) {
return true;
}
return false;
}
Here are now some additional information: In the end i want an int array called "sol" that has the same chessboard like my boolean array "board". But in sol I save the number of movements. If there is an false in board, there has to be a 0 in sol. Here is an example of the sol array:
public static boolean springtour(int[][] sol, int i, int j, int step_count, int[] x_move, int[] y_move, boolean[][] board) {
int counter = 0;
for (int row = 0; row < sol.length; row++) {
for (int col = 0; col < sol[row].length; col++) {
if (board[row][col] == true) {
counter++;
}
}
}
if (step_count == counter) {
return true;
}
for(int k=0; k<8; k++) {
int nextI = i+x_move[k];
int nextJ = j+y_move[k];
if (isValid(nextI, nextJ, sol, board)) {
sol[nextI][nextJ] = step_count;
if (springtour(sol, nextI, nextJ, step_count+1, x_move, y_move,board)) {
return true;
}
sol[nextI][nextJ] = -1;
}
}
return false;
}
So now here happens the backtracking. There is a maximum of 8 possible moves from a cell (i, j). Thus, I will make 2 arrays so that we can use them to check for the possible moves (called x_move and y_move). Thus if I am on a cell (i, j), I can iterate over these arrays to find the possible move i.e., (i+2, j+1), (i+1, j+2), etc. My next task is to move to the next possible knight's move and check if this will lead me to the solution. If not, then I will select the different move and if none of the moves are leading me to the solution, then I will return false.
public static int[][] solve(boolean[][] board, int startRow, int startCol) throws IllegalArgumentException {
if (checkboard(board) == false || checkPoint(board,startRow, startCol) == false) {
throw new IllegalArgumentException();
}
int[][] sol = new int[board.length][];
for (int i = 0 ; i < board.length; i++) {
sol[i] = new int[board[i].length];
}
for (int row = 0; row < sol.length; row++) {
for (int col = 0; col < sol[row].length; col++) {
if (board[row][col] == false) {
sol[row][col] = 0;
}
else {
sol[row][col] = -1;
}
}
}
int[] x_move = new int[]{2, 1, -1, -2, -2, -1, 1, 2};
int[] y_move = new int[]{1, 2, 2, 1, -1, -2, -2, -1};
sol[startRow][startCol] = 1;
if(springtour(sol, startRow, startCol,1,x_move,y_move, board)) {
return sol;
}
return null;
}
Now to the last one. Here i will return the sol array. At first i check is there is everything fine with my board and the starting point of the knight. Then i create a sol array and fill it with -1 (or 0 if board is false). Then i have these two arrays with the possible moves x_move and y_move. I set the starting point to 1 and i call my method springtour to do the backtracking. If nothing works it returns null.
My code is not working. There is an ArrayIndexOutOfBoundsException. Can someone help me with this? Maybe i have some other mistakes here. Thank you for helping!

You don't check if the array indices are too high in isValid.
Also your statement "the knights tour problem is a problem based on backtracking" is wrong. Code which attempts to solve a knights tour problem may use backtracking, but there is nothing in the problem definition (find a Hamiltonian path between two given nodes in a class of graphs) which requires that backtracking must be used. You could, for example, use a genetic algorithm, simulated annealing or just keep picking random paths until one works.

Related

Java - How do I check for a straight in a poker hand without sorting?

This is not a duplicate. I understand how easy this is if you can sort, but I am not allowed to use the sort method for arrays and I am not allowed to write my own. I can't find any help with this anywhere, including StackOverflow.
In this scenario, I have a method that is supposed to check whether or not a five card hand is a straight. I have a card object that holds a value (integer) and a suit (integer). I also have some rules about implementing this method.
There are no face cards besides the ace
The ace can count as either a 1 or a 10 but not both
A straight cannot wrap around
You cannot use the sorting method for arrays or write your own sorting method
That last rule is what is killing me. I have an array of cards. If I could just sort it, this would be so easy but I can't even write my own method to sort the array. For my other methods it simple to iterate through the hand and store the information about the hand in two separate arrays like this:
private static int[] cardValues = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
private static int[] cardSuits = {0, 0, 0, 0, 0};
private static void evaluationHelper(Card[] cards) {
for (int i = 0; i < cardValues.length; i++) {
cardValues[i] = 0;
}
for (int i = 0; i <cardSuits.length; i++) {
cardSuits[i] = 0;
}
for (int i = 0; i < 5; i++) {
cardValues[cards[i].getValue() - 1]++;
cardSuits[cards[i].getSuit()]++;
if (cards[i].getValue() == 1) {
cardValues[9]++;
}
}
}
So in my first attempt to solve this issue I tried something like this:
public static boolean hasStraight(Card [] cards) {
int sequenCounter = 0;
evaluationHelper(cards);
for (int i = 0; i < cardValues.length; i++) {
if (sequenCounter != 5) {
if (cardValues[i] != 0) {
sequenCounter++;
} else {
sequenCounter = 0;
}
} else {
return true;
}
}
return false;
}
That didn't work. So then I tried this:
public static boolean hasStraight(Card [] cards) {
int min = 100, max = 0;
boolean seenSix = false, seenAce = false;
evaluationHelper(cards);
for (int i = 0; i < cards.length; i++) {
if (cards[i].getValue() > max) {
max = cards[i].getValue();
}
if (cards[i].getValue() < min) {
min = cards[i].getValue();
}
if (cards[i].getValue() == 6) {
seenSix = true;
}
if (cards[i].getValue() == 1) {
seenAce = true;
}
}
if (seenSix && seenAce) {
max = 10;
}
if (max - min == 4) {
return true;
}
return false;
}
That doesn't work either. I'm getting frustrated as both of these attempts went through many different changes over the course of overs and nothing has worked. I can't even figure out why they aren't working. The only information I have is that this method isn't spitting out the correct value. I don't know what values are being passed to the method. I don't know what the method is spitting out during the test. It could be spitting out false when it's supposed to be spitting true or vice versa. Please help!
In your evaluationHelper you forgot to address when an ace is 10 adding:
if (cards[i].getValue() == 10) {
cardValues[0]++;
}
will make at least your first solution work (I haven't checked the second).
Note that what this method does is still a form of Radix sort so I'm not sure if it satisfies your requirement.
Rules:
max_value - min_value must be 4
Other 3 cards' value must be between min and max
All 5 cards must have the same suit
Assumes there are no duplicates of a suit-number.
If none of these rules are violate then you have a straight.
The only tricky thing if the Ace. Ace can be a 10? What about the number 10 card? Is Ace 1 or 10, or 1 or 11?
I assume you understand the purpose of the evaluationHelper() method; if not, I suggest you view the contents of the two arrays after it is run.
You need to find the first non-zero value in the cardValues[] array. If that entry and the subsequent 4 are all one, then return true; else return false.
In the future if you need to find a straight flush, you would first confirm one of the cardSuit[] entries equals 5 (i.e. all 5 must be the same suit); if not, then return false.

How do you check if 4 different numbers in an array are equal to each other?

This method is supposed to return true if four different numbers in the array are all equal. But whenever I try to run it with 4 equal numbers, I get an error that says:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 5
at Assignment4.containsFourOfaKind(Assignment4.java:93)
at Assignment4.main(Assignment4.java:16)
public static boolean containsFourOfaKind( int hand[] ){
for (int i = 0; i < 5; i++) {
if (hand[i ] == hand[i + 1] &&
hand[i + 1] == hand[i + 2] &&
hand[i + 2] == hand[i + 3]
) {
return true;
}
}
return false;
}
How can I fix this?
Most answers only address the ArrayIndexOutOfBoundsException, but they don't address that your original code wasn't detecting for of a kind. It was trying to detect four-in-a-row. Imagine a hand {3, 0, 3, 3, 3}: even if your code didn't cause the ArrayIndexOutOfBoundsException, it still would say that this wasn't four-of-a-kind, although it clearly is.
You need code that actually counts how many of-a-kind there are and then check if it is four or more out of the total hand. (In a typical playing card deck you couldn't have more than 4 of a kind so you can check with == to 4 as well)
The code below is even agnostic to the number of cards in a hand, although from your code above it looks like your hand size is 5 (which is very typical in poker)
public static boolean containsFourOfaKind(int hand[]) {
for (int i = 0; i < hand.length; i++) {
int countOfKind = 0;
for (int j = 0; j < hand.length; j++) {
if (hand[i] == hand[j]) {
countOfKind++;
}
}
if (countOfKind >= 4) {
return true;
}
}
return false;
}
(Note that this is a native approach. You can optimize this further; for example if you look at this closely you'll see that i doesn't have to go any further than 0 and 1.)
When you run your loop from (i=0; i<5;...) you are checking five values... In your if statement you are looking at hand[i] == hand[i+1] && hand[i+1] == hand[i+2] && hand[i+2] == hand[i+3]. This means that during the iteration when i=4 you are trying to access hand[4] through to hand[7].
I suspect your array, hand, doesn't have that many elements.
public static boolean containsFourOfaKind(int hand[]){
for(int x=0; x < hand.length; x++){
for(int y=0; y < hand.length; y++){
if(y!=x){
if(hand[x]!=hand[y]){
return false;
}
}
}
}
return true;
}
You were going outside the index using the +1 within the loop. The above code checks to see if all of the elements in the array are the same.
While others have addressed the ArrayIndexOutOfBoundsException quite clearly, I'd like to propose another method that uses no indexes:
private boolean isArrayEqual(int[] array) {
Arrays.sort(array); //Sort array to place four of a kind in sequence
int[] setOfFour = Arrays.copyOfRange(array, 0, 4); //Copy first four values
int[] compareArray = new int[4];
Arrays.fill(compareArray, setOfFour[0]); //Make an array containing only first value
if (Arrays.equals(compareArray, setOfFour)) { //Test if first four are equal
return true;
} else { //Test is last four are equal
setOfFour = Arrays.copyOfRange(array, 1, 5); //Copy of last four values
Arrays.fill(compareArray, setOfFour[0]);
return Arrays.equals(compareArray, setOfFour);
}
}
You create a second array which is filled with one of the values from the array in question (any value will do - I picked the first one). Then just see if the arrays are equal. Done.
//brain compiled code
public static boolean containsFourOfaKind(int hand[])
{
for(int i=0; i < hand.length - 1; i++)
{
if(hand[i] != hand[i + 1])
return false;
}
return true;
}
Going with your approach you could have had a simple check that was non-iterative that would just check to see if all the four cards were equal, however if you're going for an iterative approach then this is probably your best bet. Whenever you receive an arrayindexoutofbounds exception you always know that it has something to do with your arrays, and in your case there is only one spot that deals with arrays so it should be easy to visualize once you know what t he exception means.
A noniterative approach is as follows...
//brain compiled code
public static boolean containsFourOfaKind(int hand[])
{
if((hand[0] == hand[1]) && (hand[1] == hand[2]) && (hand[2] == hand[3]))
return true;
return false;
}
This can be used however it is not recommended.
An approach that doesn't specifically target a hand, could be to target a larger group; where the array could be much larger than 4. In this case, you could have a loop add onto a map that counts how many times a certain "object" (literal meaning) is in that list:
public static boolean fourOfaKind(Integer[] hand) {
HashMap<Integer,Integer> counts = new HashMap<Integer,Integer>();
for(Integer i : hand) {
if(counts.containsKey(i))
{
int count = counts.get(i);
counts.put(i, ++count);
if(count >= 4)
return true;
}
else
counts.put(i, 1);
}
return false;
}
simple code can be as follows, this will work for N number of element.
public static boolean containsFourOfaKind(int hand[]){
for(int i=1; i < hand.length; i++){
if(hand[i-1] != hand[i]){
return false;
}
}
return true;
}
In Java8 you can do it very easy:
private static boolean isEqualElements(int[] arr) {
return Arrays.stream(arr).allMatch(value -> arr[0] == value);;
}

change the same numbers in a matrix recursively

given a matrix of int numbers, a row and col indexs (for a random cell that contains a number) and a new number, I need to recursively return the matrix- however now with all of the surrounding cells that matched the random cell number to the new one. for example:
for the following matrix-
4,1,2,2
4,4,3,1
1,4,4,4
1,4,0,2
called by fill(grid,1,1,0),
this one needs to be returned:
* 0 1 2 2
0 0 3 1
1 0 0 0
1 0 0 2
what I tried is the following
public static int[][] fill(int[][] grid, int i, int j, int needed ) {
if (i<= grid.length - 1 && j<=grid[0].length - 1 && i>0 && j>0) {
grid[i][j] = needed ;
if(legal_Neighbor(grid,i,j, i+1,j))
grid= fill(grid, i+1,j,needed );
if(legal_Neighbor(grid,i,j, i,j+1))
grid= fill(grid, i,j+1,needed );
if(legal_Neighbor(grid,i,j, i,j-1))
grid= fill(grid, i,j-1,needed );
if(legal_Neighbor(grid,i,j, i-1, j))
grid= fill(grid, i-1,j,needed );
}
where legal_Neighbor is a function I'm calling that's checking if both cells have the same number and are next to each other
been stuck on this for a couple of days. would love for some help
If I understand your question correctly, you want to propagate the needed value to neighbors with equal value to origin.
the point here, is to make each node in the grid acts like a automaton, to pass the value to the neighbor if itself gets changed.
following is the code, but i left boundaryCheck blank:
static int[][] fill(int[][] grid, int i, int j, int needed) {
if (!boundaryCheck()) throw new RuntimeException();
int[][] clone = new int[grid.length][grid[0].length];
//Clone matrix grid
for (int k = 0; k < clone.length; k++) {
clone[k] = grid[k].clone();
}
propagate(clone, i, j, needed, grid[i][j]);
return clone;
}
static void propagate(int[][] grid, int i, int j, int needed, int target) {
if (!boundaryCheck() || grid[i][j] != target || needed == target) return;
grid[i][j] = needed;
propagate(grid, i+1, j, needed, target);
propagate(grid, i-1, j, needed, target);
propagate(grid, i, j+1, needed, target);
propagate(grid, i, j-1, needed, target);
}

Binary Search w/o Library Methods

I am trying to construct a binarySearch method that goes through a sorted array, and evaluates whether a given element, given as int target, is present. It will do so by evaluating whether the mean value is greater or less than the target value, and will loop through the first or second half of the array accordingly.
I think I have the basic code down, but I am running into some problems:
int target = 0; (returns true) => correct
int target = (3, 6, 9); (returns false) => should return true
int target = (15, 19, 21, 90); returns "java.lang.ArrayIndexOutOfBoundsException: 15" => should be true
I imagine it has to do with my for statements in the respective if cases, but I have tried to debug and cannot. Also, I not permitted to use library methods.
Hopefully this question is helpful for other beginners like me. I would think it explores some java concepts like syntax, logic, and basic use Thanks for the help.
public class ArrayUtilities
{
public static void main(String[] args)
{
int[] arrayBeingSearched = {0, 3, 6, 9, 12, 15, 19, 21, 90};
int target = 90;
System.out.println("linear: " + linearSearch(arrayBeingSearched, target));
System.out.println("binary: " + binarySearch(arrayBeingSearched, target));
}
public static boolean binarySearch(int[] arrayBeingSearched, int target)
{
boolean binarySearch = false;
for (int i = 0; i < arrayBeingSearched.length; i++){
int left = 0; //array lower bound
int right = arrayBeingSearched.length - 1; //array upper bound
int middle = ((right - left) / (2)); //array mean
if(arrayBeingSearched[middle] == target){
binarySearch = true;
}
else if(arrayBeingSearched[middle] < target){
for(int j = middle + 1; j < arrayBeingSearched.length - 1; j ++){
int newLeft = arrayBeingSearched[j ++];
if(arrayBeingSearched[newLeft] == target){
binarySearch = true;
break;
}
else{
binarySearch = false;
}
}
}
else if(arrayBeingSearched[middle] > target)
for(int l = 0; l < middle - 1; l ++){
int newRight = arrayBeingSearched[l ++];
if(arrayBeingSearched[newRight] == target){
binarySearch = true;
break;
}
else{
binarySearch = false;
}
}
else{
binarySearch = false;
}
}
return binarySearch;
}
}
Okay, based on the comments, would this be a better representation? The first comment answered my question mostly but I just wanted to follow up:
public static boolean binarySearch(int[] array, int target)
{
int start = 0;
int end = array.length - 1;
while (start <= end)
{
int middle = start + (end - start)/2;
if (array[middle] == target) {
return true;
}
else if (array[middle] > target)
{
end = middle - 1;
}
else start = middle + 1;
}
return false;
}
}
This is a bad start:
for (int i = 0; i < arrayBeingSearched.length; i++)
That's a linear search, with something else within it. I haven't followed exactly what you're doing, but I think you should probably start again... with a description of binary search in front of you.
Typically a binary search loop looks something like:
int left = 0; // Inclusive lower bound
int right = arrayBeingSearch.length; // Exclusive upper bound
while (left < right) {
// Either change left, change right, or return success
// based on what you find
}
When your middle element is smaller than the target, you do this
int newLeft = arrayBeingSearched[j ++];
if(arrayBeingSearched[newLeft] == target) //...
And the equivalent when it's larger.
That is, you are taking an element of the array and using it as an index. Your array could contain only one element with a value of 1000, which is why you're running into an ArrayIndexOutOfBoundsException.
I'm sure there are other problems (see Jon's answer), but I wanted to mention that code like this:
for(int j = middle + 1; j < arrayBeingSearched.length - 1; j ++){
int newLeft = arrayBeingSearched[j ++];
will not do what you want. The for statement says that each time the program goes through the loop, it will add 1 to j (at the end of the loop code). But the next statement will use j as an index and then add 1 to it. The result is that each time you go through the loop, 1 will be added to j twice, so you're basically looking only at every other element. If this were otherwise correct (which I don't think it is), I'd say you definitely need to remove the ++ from the second line.

How to fill a matrix with 0 and 1 recursively?

Ok so my problem is basically, I have a matrix for example
010
101
111
just random 1s and 0s. So I have arrays that are rowcount and colcount, which count the number of ones in each row and column. So rowcount for this is {1,2,3} and colcount is {2,2,2}. Now in another method, I am given the arrays rowcount and colcount, and in that method, I am supposed to create a matrix with the counts in rowcount and colcount, but the end matrix can be different. Than the original. I think I'm supposed to exhaust all permutations until a matrix works. The base case must stay the same.
Note: Math.random cannot be used.
private static void recur(int[][] m, int[] rowcount, int[] colcount, int r, int c)
//recursive helper method
{
if(compare(m, rowcount, colcount)) //base case: if new matrix works
{
System.out.println();
System.out.println("RECREATED");
display(m, rowcount, colcount); //we're done!
System.exit(0);
}
else
{
int[] temp_r = new int[m.length];
int[] temp_c = new int[m[0].length];
count(m, temp_r, temp_c);
if(rowcount[r] > temp_r[r] && colcount[c] > temp_c[c])
m[r][c] = 1;
if(r+1 < m.length)
recur(m,rowcount,colcount,r+1,c);
if(rowcount[r] < temp_r[r] || colcount[c] < temp_c[c])
m[r][c] = 0;
if(c+1 < m[0].length)
recur(m,rowcount,colcount,r,c+1);
}
}
private static boolean compare(int[][] m, int[] rowcount, int[] colcount)
{
int[] temp_r = new int[m.length];
int[] temp_c = new int[m[0].length];
count(m, temp_r, temp_c);
for (int x = 0; x < temp_r.length; x++)
{
if(temp_r[x] != rowcount[x])
return false;
}
for (int y = 0; y < temp_c.length; y++)
{
if(temp_c[y] != colcount[y])
return false;
}
return true;
}
public static void count(int[][] matrix, int[] rowcount, int[] colcount)
{
for(int x=0;x<matrix.length;x++)
for(int y=0;y<matrix[0].length;y++)
{
if(matrix[x][y]==1)
{
rowcount[x]++;
colcount[y]++;
}
}
}
Well, I decided I'd implement a solution, but instead of Java (which you haven't actually specified the solution needs to be in), I'm going to use Groovy (which is Java based anyway)! I've tried to use Java syntax where possible, it's not hard to extrapolate the Java code from this (but it is much more verbose!)
Note:
*Generating a random bit matrix, not using Math.random()
*I'm storing my matrix in a string i.e. [[0,1],[1,0]] = "0110"
*My solution relies heavily, on converting Integers to/from BinaryStrings (which is essentially what your matrix is!)
// Generate random matrix
int colSize = 3;
int rowSize = 4;
String matrix = '';
for (int i = 0; i < rowSize; i++){
String bits = Integer.toBinaryString(System.currentTimeMillis().toInteger());
matrix += bits.substring(bits.length() - colSize);
Thread.sleep((System.currentTimeMillis() % 1000) + 1);
}
def (cols1,rows1) = getCounts(matrix, colSize)
println "matrix=$matrix rows1=$rows1 cols1=$cols1"
// Find match (brute force!)
int matrixSize = colSize * rowSize
int start = 0
int end = Math.pow(Math.pow(2, colSize), rowSize) // 2 is number of variations, i.e. 0 and 1
for (int i = start; i <= end; i++){
String tmp = leftPad(Integer.toBinaryString(i), matrixSize, '0')
def (cols2,rows2) = getCounts(tmp, colSize)
if (cols1 == cols2 && rows1 == rows2){
println "Found match! matrix=$tmp"
break;
}
}
println "Finished."
String leftPad(String input, int totalWidth, String padchar){ String.format('%1$' + totalWidth + "s", input).replace(' ',padchar) }
int[][] getCounts(String matrix, int colSize){
int rowSize = matrix.length() / colSize
int[] cols = (1..colSize).collect{0}, rows = (1..rowSize).collect{0}
matrix.eachWithIndex {ch, index ->
def intval = Integer.parseInt(ch)
cols[index % colSize] += intval
rows[(int)index / colSize] += intval
}
[cols,rows]
}
Gives output:
matrix=001100011000 rows1=[1, 1, 2, 0] cols1=[1, 1, 2]
Found match! matrix=001001110000
Finished.
Brute force search logic:
Given a rowcount of [1,2,3]
And a colcount of [2,2,2]
Iterate over all matrix combinations (i.e. numbers 0 - 511 i.e. "000000000" -> "111111111")
Until the new matrix combination's rowcount and colcount matches the supplied rowcount and colcount
OK, your question and comments indicate you are on the right track. The code itself is a bit messy and it has obviously gone through some iterations. That's not great, but it's OK.
You are right, I believe, that you have to 'exhaust' the recursion until you find a new result that matches the existing column/row counts. So, attack the problem logically. First, create a method that can compare a matrix with a row/column count. You call it 'compare(...)'. I assume this method you have already works ;-). This is the method that marks the end of the recursion. When compare returns true, you should return up the recursion 'stack'. You should not do a System.exit(...).
So, the basic rule of recursion, you need an input, output, a method body that contains an exit-condition check, and a recursive call if the condition is not met....
Your problem has a specific issue which complicates things - you need to make copies if the input matrix every time you go down a recursion level. Alternatively you need to 'undo' any changes you make when you come up a level. The 'undo' method is faster (less memory copies).
So, the process is as follows, start with an all-zero matrix. Call your recursive function for the all-zero start point.
int[][] matrix = new int[width][height];
int rpos = 0;
boolean found = recur(matrix, rowcount, colcount, 0, 0);
This is how it will be called, and found will be true if we found a solution.
The difference here from your code is that recur now returns a boolean.
So, our recur method needs to do:
1. check the current matrix - return true if it matches.
2. make meaningful changes (within the limits that we've added)
3. recursively check the change (and add other changes).
Your method does not have an output, so there's no way to escape the recursion. So, add one (boolean in this case).
The way this can work is that we start in the top left, and try it with that bit set, and with it unset. For each contition (set or unset) we recursively test whether the next bit matches when set, or unset, and so on.... :
private static boolean recur(int[][] m, int[] rowcount, int[] colcount,
int row, int col) {
if (compare(m, rowcount, colcount)) {
// our matrix matches the condition
return true;
}
if (row >= m.length) {
return false;
}
int nextcol = col + 1;
int nextrow = row;
if (nextcol >= m[row].length) {
nextcol = 0;
nextrow++;
if (nextrow > m.length) {
return false;
}
}
// OK, so nextrow and nextcol are the following position, and are valid.
// let's set our current position, and tell the next level of recursion to
// start playing from the next spot along
m[row][col] = 1;
if (recur(m, rowcount, colcount, nextrow, nextcol)) {
return true;
}
// now unset it again
m[row][col] = 0;
if (recur(m, rowcount, colcount, nextrow, nextcol)) {
return true;
}
return false;
}
The above code is just hand-written, it may have bugs, etc. but try it. The lesson in here is that you need to test your consitions, and you need a strategy....

Categories

Resources