misunderstanding of Boolean result - java

Can somebody help me a bit? I have trouble understanding why Boolean here doesn't work the way I want to. The idea is when i(firstnum) is odd, l(lastnum) to be equal and vice verse. Some help with how to use Boolean also will be a help, I can't understand it.
Input 3 and 5.
Expected output : 4333 4353 4443 4533 4553 5334 5354 5444 5534 5554
Actual output: 4333 4353 4443 4533 4553 5333 5334 5353 5354 5443 5444 5533 5534 5553 5554
int startNum = Integer.parseInt(scan.nextLine());
int endNum = Integer.parseInt(scan.nextLine());
boolean isItEqual = false;
boolean isItOdd= false;
int countDebugOperations = 0;
for (int i = startNum; i <=endNum ; i++) {
if (i % 2==0){
isItEqual =true;
}
for (int j = startNum; j <=endNum ; j++) {
for (int k = startNum; k <=endNum ; k++) {
for (int l = startNum; l <=endNum ; l++) {
if (l % 2 == 1){
isItOdd = true;
}
boolean flag =(i > l) && (j+k) % 2 ==0;
if(!isItEqual && (!isItOdd) && flag){
countDebugOperations+=1;
System.out.printf("%d%d%d%d ",i,j,k,l);
}
if (isItEqual && isItOdd && flag) {
countDebugOperations += 1;
System.out.printf("%d%d%d%d ", i, j, k, l);
}

You are trying to print numbers i, j, k and l in exactly two cases:
When i is even AND l is odd
When l is even AND i is odd
If we translate those cases to code (boolean expressions), we get:
i % 2 == 0 && l % 2 == 1
l % 2 == 0 && i % 2 == 1
Now, when we iterate through for loops, we can ask if our "number state" matches one of those 2 cases (first case OR second case).
int startNum = Integer.parseInt(scan.nextLine());
int endNum = Integer.parseInt(scan.nextLine());
for (int i = startNum; i <= endNum; i++) {
for (int j = startNum; j <= endNum; j++) {
for (int k = startNum; k <= endNum; k++) {
for (int l = startNum; l <= endNum; l++) {
boolean firstCase = i % 2 == 0 && l % 2 == 1;
boolean secondCase = l % 2 == 0 && i % 2 == 1;
// now when we print, we can ask if we are in the first OR the second case
if (firstCase || secondCase) {
System.out.printf("%d%d%d%d ",i,j,k,l);
}
}
}
}
}

Related

matlab bwmorph(img, 'thin') implementation in Java gone wrong

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.

find all subsets of array having subset of size greater than or equal to 2

The below code prints all subsets, but I need of size greater than or equal to 2.
public static void printSubsets(char set[])
{
int n = set.length;
for (int i = 0; i < (1<<n); i++)
{
System.out.print("{ ");
for (int j = 0; j < n; j++)
if ((i & (1 << j)) >0 )
System.out.print(set[j] + " ");
System.out.println("}");
}
}
A subset of size 0 corresponds to i == 0. To eliminate the empty subset start at i = 1.
A subset of size 1 corresponds to i having exactly one bit set; or, equivalently, when it is a power of 2. A positive number i is a power of two if (i & (i - 1)) == 0.
for (int i = 1; i < (1<<n); i++) {
if ((i & (i - 1)) == 0) {
continue;
}
System.out.print("{ ");
for (int j = 0; j < n; j++) {
if ((i & (1 << j)) != 0) {
System.out.print(set[j] + " ");
}
}
System.out.println("}");
}
Alternatively, you could keep your original loop and simply insert this check:
if (Integer.bitCount(i) < 2) {
continue;
}
It's not as clever or efficient, but it is nice and readable.

Is there a way to combine incrementing and decrementing for loops?

int j = 0;
for (int i = 1; i < 4; i++)
{
if ((columnIndex + i) > 6 || this.isWinningCondition(columnIndex, i, j, colSlot, isRed))
{
break;
}
else
{
pieces++;
}
}
for (int i = -1; i > -4; i--)
{
if ((columnIndex + i) < 0 || this.isWinningCondition(columnIndex, i, j, colSlot, isRed))
{
break;
}
else
{
pieces++;
}
}
Basically, it is apart of a Connect4 program that searches for three in a row on the left and right side of a specific column (in this case, it is searching for horizontal wins), hence the incrementing (for the right side) and the decrementing (for the left side) for loops. Is there a way I can combine these for loops into one, so I don't have to repeat myself?
If your MaxValue ( 4 )is always the same for both for loop, you can always do :
for( int i = 1; i < 4; ++i)
{
//verify i version 1
int i2 = i * -1;
// verify i2 version 2
}
Try the mixed for loop.
for(int i = 0, j = 4; i <= 4 && j >=0; i ++, j --)
{
System.out.println(i + " " + j);
}
Output:
0 4
1 3
2 2
3 1
4 0

Making a hollow diamond with a word in it

What I need is a little modification to my code so that every part of my hollow diamond prints a letter of the word "HURRICANE"
My code is:
String st1 = "HURRICANE";
int a = 0;
for (int i = 5; i >= 1; i--) {
for (int j = 1; j <= 9; j++) {
if (j == i || (10 - i) == j) {
System.out.print(st1.charAt(a)); //needs change
} else {
System.out.print(' ');
}
}
System.out.println();
}
for (int i = 2; i <= 5; i++) {
for (int j = 1; j <= 9; j++) {
if (j == i || (10 - i) == j) {
System.out.print(st1.charAt(a)); //needs change
} else {
System.out.print(' ');
}
}
System.out.println();
}
The output comes out as:
H
H H
H H
H H
H H
H H
H H
H H
H
I need to modify my "charAt" statement a little so it comes out to be:
H
U U
R R
R R
I I
C C
A A
N N
E
How should I make my print statement?
It's worth noting that the example provided only works for Strings the same length as "HURRICANE". A superior solution would work for all strings.
Partial solution for you to complete, since I guess it's your coursework and I don't want you to copy / paste / fail exams :P
public static void main(String[] args) {
String st1 = "HURRICANE";
char[] st1CharArray = st1.toCharArray();
int maxSpaces = st1CharArray.length / 2 + 1;
for (int i = 0; i <= st1CharArray.length / 2; i++) {
if (i == 0) {
System.out.println(getSpacesString(maxSpaces) + st1CharArray[i]);
} else {
System.out.println(getSpacesString(maxSpaces - i)
+ st1CharArray[i] + getSpacesString(i * 2 - 1)
+ st1CharArray[i]);
}
}
// Loop from st1CharArray.length / 2 + 1 and get the second half done.
}
private static String getSpacesString(int numberOfSpaces) {
StringBuilder strBuilder = new StringBuilder();
for (int i = 0; i < numberOfSpaces; i++) {
strBuilder.append(" ");
}
return strBuilder.toString();
}
//: Playground - noun: a place where people can play
import UIKit
var name : String = "HURRICANE"
var dimensions : Int = name.count - 1
var k : Int = 0
for rows in 0...dimensions{
for columns in 0...dimensions{
k = abs( (dimensions/2) - rows )
if columns == k || columns == dimensions - k{
print(Array(name)[rows], terminator: "")
}
else{
print(" ", terminator: "" )
}
}
print("")
}
String st1 = "HURRICANE";
int a = 0;
for (int i = 5; i >= 1; i--) {
for (int j = 1; j <= 9; j++) {
if (j == i || (10 - i) == j) {
System.out.print(st1.charAt(5 - i));
} else {
System.out.print(' ');
}
}
System.out.println();
}
for (int i = 2; i <= 5; i++) {
for (int j = 1; j <= 9; j++) {
if (j == i || (10 - i) == j) {
System.out.print(st1.charAt(3 + i));
} else {
System.out.print(' ');
}
}
System.out.println();
}
Let's assume that a word has an odd number of characters, otherwise we get a crooked diamond.
Try it online!
public static void main(String[] args) {
String str = "abrahadabra";
int n = str.length() / 2;
for (int i = -n, ch = 0; i <= n && ch < str.length(); i++, ch++) {
for (int j = -n; j <= n; j++)
if (Math.abs(i) + Math.abs(j) == n)
System.out.print(str.charAt(ch));
else
System.out.print(" ");
System.out.println();
}
}
Output:
a
b b
r r
a a
h h
a a
d d
a a
b b
r r
a

Java several conditions with the help of for loop

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;
}

Categories