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
Related
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);
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
I am trying to solve this : Given an integer, return 1 if the number is between -5 and 5 exclusive and/or if it is an odd integer. If neither properties apply, return 0.
Here is what I have tried:
int rangeOrOdd(int val) {
if (val < 5)
return 1;
else if (val > 5)
return 1;
else if ((val%2)!=0)
return 0;
else
return 0;
}
The problem is that you are checking the different conditions individually. For instance, as soon as your number is smaller than 5, you return 1, which is wrong, because you would then return 1 for numbers like -1000.
Also, you are returning 0 for an odd number. You were supposed to return 1 in that case.
You have to combine your conditions using ANDs (&&) and ORs (||).
Here is a one liner that combines the different conditions correctly:
return ((val < 5 && val > -5) || val % 2 == 1) ? 1 : 0;
And if you don't like it in one line, you can always split it like this (but it's the same thing):
if ((val < 5 && val > -5) || val % 2 == 1) {
return 1;
} else {
return 0;
}
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
This is my task:
Given a string, does "xyz" appear in the middle of the string? To define middle, we'll say that the number of chars to the left and right of the "xyz" must differ by at most one.
The problem description and the failures in others use case can be seen by using the code below here
xyzMiddle("AAxyzBB") → true
xyzMiddle("AxyzBB") → true
xyzMiddle("AxyzBBB") → false
My solution is below. Since I can't see what 'other tests' are, please help me spot the problem. My method is to check if 'y' appears in the middle for odd or even a String.
public boolean xyzMiddle(String str) {
if (str.indexOf("xyz") < 0) return false;
int l = str.length();
int m = l / 2;
if (l % 2 != 0) {
if (str.charAt(m) != 'y') return false;
}
else {
if (str.charAt(m) != 'y' && str.charAt(m - 1) != 'y') return false;
}
return true;
}
The problem with your solution is that you are simply returning false in case the string in question has odd length
Which is actually not true, the pass use-cases for this task can be mathematically divided like below:
1)With xyz present in the middle and there is a string of length x + 1 and x to either the left or right of it.
taking length of string xyz as 3 the total length comes out to be:
(x) + 3 + (x + 1) = 2x + 4 --->Always even
so in the case above we just check is xyz is in the middle or not and return accordingly which is already handled in your code.
2) With xyz present in the middle and there are strings of length x to the left or right of it.
Again taking length of string xyz as 3 the total length comes out to be:
(x) + 3 + (x) = 2x + 3 --->Always odd
Hence as per your solution to return true in this case(last line of code) you need to filter out the cases when length is odd but xyz is not in the middle as below:
if (!(str.substring((m - 1), m + 2).equals("xyz")))
return false;
With this included your solutions looks like as below:
public boolean xyzMiddle(String str) {
if (str.indexOf("xyz") < 0) return false;
int l = str.length();
int m = l / 2;
if (l % 2 != 0) {
if (!(str.substring((m - 1), m + 2).equals("xyz")))
return false;
}
else {
if (str.charAt(m) != 'y' && str.charAt(m - 1) != 'y') return false;
}
return true;
}
Now it passes all the tests on codingBat.
if(str.length() <3) return false;
int ind = str.indexOf("xyz", str.length()/2 - 3) ;
String first = str.substring(0, ind);
String second = str.substring(ind+3);
return (first.length() == second.length() || first.length() +1 == second.length() || first.length() == second.length() + 1);