I am solving n-queen, but i have a problem for some reason the while loop keeps looping without iterating, tempx and tempy doesn't go up by i/j. and the result keeps outputting 0,0
public static boolean isSafe(Board board, int row, int col){
int tempx;
int tempy;
for(int i = -1; i <= 1; i ++){
for(int j = -1; j <= 1; j ++){
try {
tempx = row + i;
tempy = col + j;
while(tempx >= 0 && tempx < board.getRow() && tempy >= 0 && tempy < board.getRow()) {
if(board.getTile(tempx, tempy).isOccupied())
return false;
tempx += i;
tempy += j;
}
} catch(Exception e){}
}
}
return true;
}
EDIT:
Ok i figured it out and it seems to work fine, for anyone that wants to know here it is, please correct me if there is a better way of doing this
public static boolean isSafe(Board board, int row, int col){
int tempx;
int tempy;
for(int i = -1; i <= 1; i ++){
for(int j = -1; j <= 1; j ++){
try {
tempx = row + i;
tempy = col + j;
for(int k = 0; k < board.getRow(); k++){
if(tempx >= 0 && tempx < 8 && tempy >= 0 && tempy < 8) {
if(board.getTile(tempx, tempy).isOccupied() )
return false;
tempx += i;
tempy += j;
}
}
} catch(Exception e){}
}
}
return true;
}
Do you realize that the loop
while(tempx >= 0 || tempx < 8 || tempy >= 0 || tempy < 8) {
is infinite as for every number tempx and tempy it is satisfied?
You probably wanted
while(tempx >= 0 && tempx < 8 && tempy >= 0 && tempy < 8) {
Related
I am implementing the matlab 'bwmorph(img, 'thin')' algorithm in Java ImageJ. I've searched all over the net pretty much and found some similar implementations that work better, but I can't find the issue in my code. Any ideas?
My code:
public void run(ImageProcessor ip) {
MakeBinary(ip);
int sum2 = processThin(ip);
int sum = -1;
while (sum2 != sum) {
sum = sum2;
sum2 = processThin(ip);
}
}
public int processThin(ImageProcessor ipOriginal) {
int sum = 0;
// first iteration
ImageProcessor ip = ipOriginal.duplicate();
for (int i = 1; i < ip.getWidth() -1; i++)
for (int j = 1; j < ip.getHeight() -1; j++) {
int[] neighbors = selectNeighbors(ip, i, j);
if (G1(neighbors) == 1 && G2(neighbors) >= 2 && G2(neighbors) <= 3 && G3(neighbors) == 0)
ip.putPixel(i,j, 0);
}
// second iteration
for (int i = 1; i < ip.getWidth() -1; i++)
for (int j = 1; j < ip.getHeight()-1; j++) {
int[] neighbors = selectNeighbors(ip, i, j);
if (G1(neighbors) == 1 && G2(neighbors) >= 2 && G2(neighbors) <= 3 && G3prime(neighbors) == 0)
ip.putPixel(i,j, 0);
}
for(int i = 0; i < ip.getWidth(); i++)
for(int j = 0; j < ip.getHeight(); j++) {
if (ip.getPixel(i,j) != 0) sum++;
ipOriginal.putPixel(i, j, ip.getPixel(i, j));
}
return sum;
}
private int G1(int[] input) {
int xh = 0;
for (int i = 1; i <= 4; i++) {
if (input[2 * i - 1] == 0 && (input[2 * i] == 1 || (2 * i + 1 <= 8 ? input[2 * i + 1] == 1 : input[1] == 1)))
xh += 1;
}
return xh;
}
private int G2(int[] input) {
int n1 = 0, n2 = 0;
n1 = toInt(toBool(input[4]) || toBool(input[3])) + toInt(toBool(input[1]) || toBool(input[2])) +
toInt(toBool(input[8]) || toBool(input[7])) + toInt(toBool(input[6]) || toBool(input[5]));
n2 = toInt(toBool(input[2]) || toBool(input[3])) + toInt(toBool(input[1]) || toBool(input[8])) +
toInt(toBool(input[6]) || toBool(input[7])) + toInt(toBool(input[4]) || toBool(input[5]));
return Math.min(n1,n2);
}
private int G3 (int[] input){
return toInt((toBool(input[2]) || toBool(input[3]) || !toBool(input[8])) && toBool(input[1]));
}
private int G3prime (int[] input){
return toInt((toBool(input[6]) || toBool(input[7]) || !toBool(input[4])) && toBool(input[5]));
}
private boolean toBool(int i ){
return i == 1;
}
private int toInt(boolean i) {
return i ? 1 : 0;
}
private int[] selectNeighbors(ImageProcessor ip, int i, int j) {
int[] result = new int[9];
result[1] = ip.getPixel(i+1,j);
result[2] = ip.getPixel(i+1,j+1);
result[3] = ip.getPixel(i,j+1);
result[4] = ip.getPixel(i-1,j+1);
result[5] = ip.getPixel(i-1,j);
result[6] = ip.getPixel(i-1,j-1);
result[7] = ip.getPixel(i,j-1);
result[8] = ip.getPixel(i+1,j-1);
for (int x = 0; x < result.length; x++)
if (result[x] != 0) result[x] = 1;
return result;
}
The main issue appears to be with the horizontal lines, but not only that.
Note: I've added the toBool and toInt methods to deal with convenient data types, the code was binary before and the result is the same apparently.
EDIT:
After editing the code and omitting doing modifications between two iterations, I ended up with this result now.
The code looks like this now.
public int processThin(ImageProcessor ip) {
int sum = 0;
// first iteration
int[][] mask = new int[ip.getWidth()][ip.getHeight()];
for (int i = 1; i < ip.getWidth() -1; i++)
for (int j = 1; j < ip.getHeight() -1; j++) {
int[] neighbors = selectNeighbors(ip, i, j);
if (G1(neighbors) == 1 && G2(neighbors) >= 2 && G2(neighbors) <= 3 && G3(neighbors) == 0)
mask[i][j]++;
}
// second iteration
for (int i = 1; i < ip.getWidth() -1; i++)
for (int j = 1; j < ip.getHeight()-1; j++) {
int[] neighbors = selectNeighbors(ip, i, j);
if (G1(neighbors) == 1 && G2(neighbors) >= 2 && G2(neighbors) <= 3 && G3prime(neighbors) == 0)
mask[i][j]++;
}
for(int i = 0; i < ip.getWidth(); i++)
for(int j = 0; j < ip.getHeight(); j++) {
if (mask[i][j] != 0) sum++;
ip.putPixel(i, j, mask[i][j] > 0 ? 0 : ip.getPixel(i,j));
}
return sum;
}
The problem in your original code is that you write into your input image. In the very first iteration, moving left to right, you remove successive pixels because each has, after modifying the previous pixel, a background pixel as neighbor.
There are different ways to implement the thinning operation, but the simplest one that works in-place like your code does requires two passes through the image for each iteration of the thinning:
Go through the image and mark all candidate pixels. These are the pixels that have a background neighbor. Marking a pixel can be as simple as setting the pixel value to a given constant, for example 42 (assuming background is 0 and foreground is 1 or 255 or whatever you decided on).
Go through the image again and for each marked pixel, determine if removing it would change the geometry of the foreground. If not, remove it. In this test, take the marked pixels that haven't been removed yet as foreground.
I'm currently try to print below pattern in java,please help me in solving it.
Input: 3, abcdefghijklm
output:
c
bjd
aimke
hlf
g
I build diamond pattern with star, stuck in print values from array in spirally in diamond shape show above.
public static void rhombus() {
int n = 3;
int size = 2 * n - 1;
char[][] sol = new char[size][size];
for (int i = 0; i < size; i++) {
for (int j = 0; j < size; j++) {
sol[i][j] = ' ';
}
}
int i = size / 2;
int j = 0;
String s = "abcdefghijklmnop";
int len = s.length();
int in = 0;
int left = 0, top = 0, right = size - 1;
int bottom = size - 1;
boolean flag = false;
while (i != j) {
while (i >= top && !flag) {
sol[i][j] = s.charAt((in++) % len);
if (i == size / 2 && j == size / 2)
flag = true;
i--;
j++;
}
if (flag == true)
break;
i += 2;
top++;
left++;
while (j <= right && !flag) {
sol[i][j] = s.charAt((in++) % len);
i++;
j++;
}
j -= 2;
right--;
while (i <= bottom && !flag) {
sol[i][j] = s.charAt((in++) % len);
i++;
j--;
}
bottom--;
i -= 2;
while (j >= left && !flag) {
sol[i][j] = s.charAt((in++) % len);
i--;
j--;
}
j++;
}
sol[i][j] = s.charAt((in++) % len);
for (int a = 0; a < size; a++) {
for (int b = 0; b < size; b++) {
System.out.print(sol[a][b]);
}
System.out.println();
}
}
Here's the code:
public static int maxPathLengthHelper(int[][] paths, int x, int y){
int maxLength = 0;
if(x > 0 && paths[x-1][y] == 1){
int currentLength = 1 + maxPathLengthHelper(paths,x-1,y);
if(currentLength > maxLength){
maxLength = currentLength;
}
}
if(y > 0 && paths[x][y-1] == 1){
int currentLength = 1 + maxPathLengthHelper(paths,x,y-1);
if(currentLength > maxLength){
maxLength = currentLength;
}
}
if(x < paths.length - 1 && paths[x+1][y] == 1){
int currentLength = 1 + maxPathLengthHelper(paths,x+1,y);
if(currentLength > maxLength){
maxLength = currentLength;
}
}
if(y < paths[0].length - 1 && paths[x][y+1] == 1){
int currentLength = 1 + maxPathLengthHelper(paths,x,y+1);
if(currentLength > maxLength){
maxLength = currentLength;
}
}
return maxLength;
}
In the if statements where the y value is changed, a Stack Overflow error is caused, yet there is no error in the parts where the x value is changed. I was wondering why this was; if both were wrong, I would change the whole thing, but it's just in the second and fourth if statements that Stack Overflow errors are caused by the recursive call. The first and third if statements have no issues, and I have absolutely no idea what is different about them.
This is because when your code moves from 0,0 to 1,0 it again checks for 0,0 as first if condition is satisfied
public static int[][] visitedNodes;
public static void main(String args[]){
// when you call the recursive method, also initiate the visitedNodes
visitedNodes = new int[totalX][totalY];
for(int i = 0; i < totalX; i++)
for(int j = 0; j < totalY; i++)
visitedNodes[i][j] = 0;
maxPathLengthHelper(myPathList,0,0);
}
public static int maxPathLengthHelper(int[][] paths, int x, int y){
int maxLength = 0;
visitedNodes[x][y] = 1;
if(x > 0 && visitedNodes[x-1][y] == 0 && paths[x-1][y] == 1){
int currentLength = 1 + maxPathLengthHelper(paths,x-1,y);
if(currentLength > maxLength){
maxLength = currentLength;
}
}
if(y > 0 && visitedNodes[x][y-1] == 0 && paths[x][y-1] == 1){
int currentLength = 1 + maxPathLengthHelper(paths,x,y-1);
if(currentLength > maxLength){
maxLength = currentLength;
}
}
if(x < paths.length - 1 && visitedNodes[x+1][y] == 0 && paths[x+1][y] == 1){
int currentLength = 1 + maxPathLengthHelper(paths,x+1,y);
if(currentLength > maxLength){
maxLength = currentLength;
}
}
if(y < paths[0].length - 1 && visitedNodes[x][y+1] == 0 && paths[x][y+1] == 1){
int currentLength = 1 + maxPathLengthHelper(paths,x,y+1);
if(currentLength > maxLength){
maxLength = currentLength;
}
}
return maxLength;
}
i'm a bit stuck with the Sudoku algorithm, i coded it using backtrack, and following the theorical steps this should work, and i tried to debuge it, but is too hard (and yes, it solve some numbers and does things)
i paste the code, i hope that you can help me, i really can't see where the problem is...
public void backtracking(int row,int col){
if(row > 8){
System.out.println("Solution Found!!");
printSudoku();
}
if (m[row][col] != 0){
next(row, col);
}
else {
for(int i =1; i < n;i++)
if(row(row, i) && col(col, i)) {
m[row][col] =i;
next(row, col);
}
m[row][col] = 0;
}
}
public void next( int row, int col ) {
if( col < 8)
backtracking( row, col + 1 ) ;
else
backtracking( row+ 1, 0 ) ;
}
public boolean region(int x, int y, int numReg) {
x = (x / 3) * 3 ;
y = (y / 3) * 3 ;
for( int r = 0; r < 3; r++ )
for( int c = 0; c < 3; c++ )
if( m[x+r][y+c] == numReg )
return false ;
return true ;
}
public boolean row(int x, int k){
for(int i =0; i < 9; i++)
if(m[x][i] == k)
return false;
return true;
}
public boolean col(int x, int k){
for(int i =0; i < 9; i++)
if(m[i][x] == k)
return false;
return true;
}
I ommited the "printSudoku" method, is just a double for and you know.
The code seems almost right.
As far as i can see you just forgot to call the region method. And I can't see where the variable n is coming from.
Try it with this slightly modified backtracking method:
public static void backtracking(int row, int col) {
if (row > 8) {
System.out.println("Solution Found!!");
printSudoku();
System.exit(0); //exiting after solution is found
}
if (m[row][col] != 0) {
next(row, col);
} else {
for (int i = 1; i <= 9; i++) //replaced i < n with i<=9
if (row(row, i) && col(col, i) && region(row, col, i)) { //calling region method too
m[row][col] = i;
next(row, col);
}
m[row][col] = 0;
}
}
I wonder if it is possible to have minimal code for this:
for (int x = 1; x < 10; x++){
/*I want to replace this condition with (x%number == 0)
instead of writing out condition for every number, but
it did not work with for (int number = 1; number <= 3; number++)
in (x%number == 0), as it prints out every x and number
*/
if ((x%1) == 0 && (x%2) == 0 & (x%3) == 0){
System.out.println(success!);
}
}
I think
x % a == 0 && x % b == 0 && x % c == 0
is equalent to
x % (a * b * c) == 0
UPDATE
Multiplication is incorrect, you need to use LCM: x % lcm(a, b, c)
Have a look :
for (int x = 1; x < 10; x++){
boolean flag = false;
for(int num = 1; num <= 3; num++){
if ((x%num) == 0 ){
flag = true;
}else{
flag = false;
break;
}
}
if(flag){
System.out.println(x + " success!");
}
}
OUTPUT :
6 success!
I know the code is looking a little horrified but will work for any value of x and num
This is what you'd need to make a comp sci professor happy:
for (int x = 1; x < 10; x++){
boolean success = true;
for (int number = 1; number <= 3; number++) {
if ((x % number) != 0) {
success = false;
}
}
if (success) {
System.out.println("success!");
}
}
although note: (x % 1) is always 0.
This is what you'd need to make me happy, according to my rule of "avoid nested loops":
for (int x = 1; x < 10; x++) {
if (testNumber(x))
System.out.println(x + " success!");
}
}
private static boolean testNumber(int x) {
for (int number = 1; number <= 3; number++) {
if ((x % number) != 0) {
return false;
}
}
return true;
}