Having trouble understanding why this code does what it does - java

int x = 0;
boolean b = true;
int[] nums = { 3, 1, 3, 1, 3 };
for (int i = 0; i < nums.length - 1; i++) {
if (nums[i] == 3 && nums[i + 1] == 3)
b = false;
if (nums[i] == 3)
x++;
}
if (nums[nums.length - 2] != 3 && nums[nums.length - 1] == 3)
x++;
System.out.print(x == 3 && b);
In this code, x gets a ++ every time the for loop finds a 3, which gives x a value of 3. by the time the loop is finished. Under the loop however, there is an if statement, that asks if the is a !=3 at -2 and a 3 at |-1, which is a true statement,-2 is 1and-1 is 3, thenx++, which makesx = 4, so why then does it print true in the print statement if it saysx == 3 && bifx == 4`?

What you missed is that the loop doesn't iterate over the last element of the array, so it increments x just twice (since if (nums[i] == 3) is not executed for the last element of the array). Therefore x is 3 at the end (incremented twice by the loop and a third time by the last condition).
for (int i = 0; i < nums.length - 1; i++) // the if (nums[i] == 3) condition is not
// tested on the element whose index is
// nums.length - 1 (and whose value is 3)
// since i doesn't reach nums.length - 1

What happens is the condition is the for loop is: i < nums.length - 1 which means i will have values from 0 (first element) to nums.length - 1 (second last element). As a result, it will only count 2 of the 3s in the array (it will miss out the last one) and thus x will be 2 at this stage.
Finally, the statement:
if (nums[nums.length - 2] != 3 && nums[nums.length - 1] == 3)
x++;
Is satisfied by the array and will thus make x have a value of 3
As a result x == 3 && b is true

It works that way because the loop runs and ends without running over the last index. The statement which is checked is nums[i] == 3 and if it's true, it'll incerement x. However, your code runs only until the index before the last index. Meaning, it'll incerement x only twice.
In the end you increment x to 3.

x does equal 3 the for loop only checks the first 4 elements of the nums array. If you want to to equal to 4, then change the loop to:
for (int i = 0; i < nums.length; i++) {
if (i != nums.length-1 && nums[i] == 3 && nums[i + 1] == 3)
b = false;
if (nums[i] == 3)
x++;
}
Run here

The program iterates the array from index 0 to index (length -1), increasing the value of X for each 3 found.
Since there are not two consecutive 3 in the array, b will remain true.
It will find two 3's, so at the end of the for loop x will be 2.
The if statement will check if the second last (nums.length - 2) is not a 3 (true) and if the last one is a 3 (also true), so x goes up once more to a 3.
Then it prints true because x=3 and b= true

Related

Array-1 CodingBat unlucky1 (java) Challenge

I’m a senior in high school taking a computer science class. For homework, we have to create solutions to certain CodingBat (practice coding website) problems. I am experiencing problems with this question, some of which include OutOfBounds for the array. Based on my code, I can’t quite figure out why this is happening. The following attached code (below) is what I have created as a solution to the CodingBat problem for unlucky1 in Array-1 (java), which describes the challenge as: “We'll say that a 1 immediately followed by a 3 in an array is an "unlucky" 1. Return true if the given array contains an unlucky a in the first 2 or last 2 positions in the array.
public boolean unlucky1(int[] nums) {
int i = 0;
for(i = 0; i < nums.length; i++)
if(nums[i-1] == 1 && nums[i] == 3)
{
return true;
}
return false;
}
The problem statement is "Return true if the given array contains an unlucky a in the first 2 or last 2 positions in the array.", so you don't even need a loop - you just need to examine the first two and last two elements of the array:
public boolean unlucky1(int[] nums) {
return nums != null &&
nums.length >= 2 &&
(nums[0] == 1 && nums[1] == 3 ||
nums[nums.length - 2] == 1 && nums[nums.length -1] == 3);
}
The following code is the correct method.
0.public static boolean unlucky1(int[] nums){ //Firstly,declare the method
"static"
1. int length = nums.length;//Get the array length.
2.if((nums[0] == 1 && nums[1] == 3) && ( nums[length - 2] == 1 &&
nums[length] -1 == 3)){
3. return true;
}
4. return false;
}
In row 2,your code was: "if(nums[i-1] == 1 && nums[i] == 3)";
It showed arrayoutofbound because the starting array index is 0 and you decalred in the if statement
" if(nums[0-1]...)which says if nums[-1] which is out of bounds."
Also to check the last 2 numbers of the array you do the following:
( nums[length - 1] == 1 && nums[length] == 3)) where :
" nums[length - 2] == 1"
checks 1 value before the last array value
and
" nums[length] - 1 == 3 "
checks the last array value

Solution codewars to car Mileage problem, running out of ideas?

I am trying to work out a solution to the CodeWars challenge Catching Car Mileage Numbers:
Write the function that parses the mileage number input, and returns a 2 if the number is "interesting" (see below), a 1 if an interesting number occurs within the next two miles, or a 0 if the number is not interesting.
Interesting numbers are 3-or-more digit numbers that meet one or more of the following criteria:
Any digit followed by all zeros: 100, 90000
Every digit is the same number: 1111
The digits are sequential, incementing†: 1234
The digits are sequential, decrementing‡: 4321
The digits are a palindrome: 1221 or 73837
The digits match one of the values in the awesomePhrases array
† For incrementing sequences, 0 should come after 9, and not before 1, as in 7890.
‡ For decrementing sequences, 0 should come after 1, and not before 9, as in 3210.
I can pass all tests in the first batch, but fail to pass the second batch.
Any feedback would be very much appreciated, not only on a possible solution but also to the way I'm thinking about the exercise.
public static int isInteresting(int number, int[] awesomePhrases) {
for (int offSet = 0; offSet <= 2; offSet++) {
int testNumber = number;
testNumber += offSet;
boolean isYellow = testNumber != number;
int yellowOffset = 0;
if (isYellow) {
yellowOffset = 1;
}
//check three or more digit number
boolean greaterThan99 = testNumber > 99;
int[] numbers = Integer.toString(testNumber).chars().map(c -> c - '0').toArray();
int zeroCounter = 0;
int identicalCounter = 0;
int incrementingCounter = 0;
int decrementingCounter = 0;
int palindromeCounter = 0;
boolean endsInZero = numbers[numbers.length - 1] == 0;
for (int i = 0; i < numbers.length; i++) {
//check digit followed by zeros
if (numbers[i] == 0) {
zeroCounter++;
}
if (i + 1 < numbers.length) {
//check every digit is the same
if (numbers[i] == numbers[i + 1]) identicalCounter++;
//check ascending order
if (numbers[i + 1] - numbers[i] == 1) incrementingCounter++;
//check descending order
if (numbers[i] - numbers[i + 1] == 1) decrementingCounter++;
}
}
if (greaterThan99) {
//check awesomePhrases
for (int phrase : awesomePhrases) {
if (phrase == testNumber) return 2 - yellowOffset;
}
//check palindrome
int reversedIndex = numbers.length - 1;
for (int i = 0; i < numbers.length; i++) {
if (numbers[reversedIndex] == numbers[i]) {
palindromeCounter++;
}
reversedIndex--;
}
if (zeroCounter == numbers.length - 1) return 2 - yellowOffset;
if (identicalCounter == numbers.length - 1) return 2 - yellowOffset;
if (incrementingCounter == numbers.length - 1) return 2 - yellowOffset;
if (incrementingCounter == numbers.length - 2 && endsInZero) return 2 - yellowOffset;
if (decrementingCounter == numbers.length - 1) return 2 - yellowOffset;
if (decrementingCounter == numbers.length - 2 && endsInZero) return 2 - yellowOffset;
if (palindromeCounter == numbers.length) return 2 - yellowOffset;
}
}
return 0;
}
I've tried pretty much all I know but to no result, all the tests I try pass, would love to know what I'm doing wrong.
The problem is in how your code tests for increasing sequences that end in a zero. It is not enough to test that the sequence has n-2 increments and the last digit is a zero, because that will give a false positive on numbers like 6780. It is required that the one-but-last digit is a 9.
A similar issue exist for the decreasing sequence logic, however, there you would not need a special test for an ending zero at all. This condition is covered by counting n-1 decrements, where the ending could be a 1 followed by a zero. There is no special case to be handled here.
To fix the first problem, I would suggest you not only check whether the last digit is a zero, but whether the last two digits are 9 and 0, or in other words, that the number modulo 100 is equal to 90.
You could replace this:
boolean endsInZero = numbers[numbers.length - 1] == 0;
by this:
boolean endsInNinety = testNumber % 100 == 90;
and then replace:
if (incrementingCounter == numbers.length - 2 && endsInZero) return 2 - yellowOffset;
by:
if (incrementingCounter == numbers.length - 2 && endsInNinety) return 2 - yellowOffset;
and finally remove this test:
if (decrementingCounter == numbers.length - 2 && endsInZero) return 2 - yellowOffset;
This will fix it.
Note that it can be helpful to have your function print the input it gets, so that when a test fails, at least you can know for which input there was a problem:
System.out.println("input " + number);

what does x % 2 > 0 mean in java?

I'm currently learning java in my online classes and I'm learning about loops (specifically continue and break statements). The example given to me was:
int j = 0
while (true){
System.out.println();
j++;
System.out.print(j);
if (j%2 > 0) continue
System.out.print(" is divisible by 2");
if (j >= 10) break;
}
I don't understand why its (j%2 > 0) and not (j%2 == 0) because what if 'j' is 5 for example and you do 5%2. Wouldnt the number you get be 1? Or am I missing something? Can someone please explain this to me?
(sorry is I'm not my question is a little confusing. I've never used this site before and I'm pretty young)
Let me explain to you. See the comments next to each line.
int j = 0
while (true){
System.out.println();
j++; //increases the value of j on the next line by 1.
System.out.print(j); //prints 1, the first time because of above, 0 + 1.
if (j%2 > 0) continue //using modulus operator(%) we are doing 1 % 2, answer is 1
//since 1 % 2(if 1 is divisible by 2) > 0 we are
//continue statement breaks the iteration in the
//loop, so anything below this line won't be
//executed.
System.out.print(" is divisible by 2");//this line will only be executed
//if j is divisible by 2. that is
//j is divisible by 2 (j%2 == 0)
if (j >= 10) break; //when j is equal or greater than
//0 we are stopping the while loop.
}
Continue means "go to the top of the loop, skipping the rest of the loop's code" not "continue with the code". So since 5%2 is 1, and 1 > 0, the continue will execute, going directly to the top of the loop and skipping the rest of the body.
Why do they use > 0 instead of != 0? There isn't any technical reason, its a style difference. I personally would have used the latter as its more clear in my mind. But either works.
int j = 0;
while (true){
System.out.println();
j++;
System.out.print(j);
// in this case you won't print any message and you
// are sure that the next number is even (j will be incremented by "continue;").
if (j%2 > 0) continue;
System.out.print(" is divisible by 2");
if (j >= 10) break;
}
X % 2 means the remainder when is x is divided by 2. So if the remainder of x/2 is more than 0, it means that x is an odd number. When x%2 == 0, then x is a positive number

Java For Loop Confusion (iteration) "Don't know why it still went through!" [duplicate]

This question already has answers here:
What is a debugger and how can it help me diagnose problems?
(2 answers)
Closed 5 years ago.
So I was trying to figure out if the the first iteration in a for loop does not go through the termination condition.
Since when I called it in the main method with an input of 4 IsPrime(4) the for loop still went through. I was expecting it to not go through since i = 2 and n/2 = 4/2 = 2 which will be 2 == 2 which will meet the condition to terminate but it went through and I got the right output but I don't get why it did not fail.
Please help.
public static boolean isPrime(int n){
if(n <= 1){
return false;
}
for(int i = 2; i <= n/2; i++){
if(n % i == 0){
return false;
}
}
return true;
}
Your for loop condition says continue while i <= n/2.
If you start with n == 4 then n/2 == 2. On the first iteration i == 2 so the for loop condition 2 <= 2 is true and it will iterate once.
Then i++ is executed so now i == 3 and fails the condition so there is no second iteration.
You seem to have a confusion around how for loop works. Let's see the operation on a per-iteration basis :
Iteration 1 :
i = 2
i <= 2 ? --> True
n % i == 0 ? --> 2 % 2 == 0? True
return false
End of function
Now let's assume your for loop looked something like this :
for(int i = 2; i <= n/2; i++){
if(n % i == 0){
System.out.println("Remainder is 0");
}
}
Then the following will the iteration sequence :
Iteration 1
i = 2
i <= 2 ? --> True
n % i == 0 ? --> 2 % 2 == 0? True
print --> Remainder is 0
i++ --> i = 3 now
Iteration 2
i = 3
i <= 3 ? --> False
Cannot proceed further. For loop condition failed.
End of function

Postincrement in java expressions

In this example:
int i = 1;
while(i < 10)
if(i++%2 == 0)
System.out.println(i);
Why is the output 3,5,7,9 and not 2,4,6,8?
The condition is performed on the previous value of i, before it is incremented (which is even), but the output is done on the incremented value of i (which is odd).
The ++ operator applied after a variable returns the value of the variable and increments the variable after the expression is evaluated. The semantic is the same than this:
int i = 1;
while(i < 10) {
boolean cond = i % 2 == 0;
i = i + 1;
if(cond) {
System.out.println(i);
}
}
The post-increment operator, uses the current value of its operand in the expression and then increments it.
We can break this down using a literal value of '2' for example.
Basically this is what your present code is doing:
int i = 2;
if (i % 2 == 0) //true, 2 % 2 = 0
i = i + 1; //i now becomes 3
System.out.println (i);
OR to make it simpler, if we remove the loop and put back your code
int i = 1;
if (i++ % 2 == 0) //1 % 2 != 0
System.out.println (i); //Nothing will print for the if statement
System.out.print i; //Will print 2, because this print statement is outside
//the body of the if-statement
to get the output that you are looking for, you will have to use the prefix-increment operator (++i)
int i = 1;
if ( ++i % 2 == 0)
System.out.println (i);
this is equivalent to
int i = 1
if ( (i + i) % 2 == 0) //++i increments i and then uses it in the expression
System.out.println (i);

Categories

Resources