Go Premium for a chance to win a PS4. Enter to Win

x
Solved

# twoTwo  challenge

Posted on 2016-08-08
Medium Priority
161 Views
Hi,

I am working on below challenge

http://codingbat.com/prob/p102145

Psedo code description of approach :
1. Loop throguh given array
2. check if array element 2 with adjacent one also 2
3. if yes return true
4. if no return false

I wrote my code as below
``````public boolean twoTwo(int[] nums) {
boolean result=false;
for(int i=0;i<nums.length-1;i++){
if((nums[i]==nums[i+1])||(nums[i]==nums[i-1])){
result=true;

}
else{
result=false;
}
}
return result;

}
``````

I am not passing all tests as below and failing edge cases
Expected      Run
twoTwo([4, 2, 2, 3]) → true      Exception:java.lang.ArrayIndexOutOfBoundsException: -1 (line number:4)      X
twoTwo([2, 2, 4]) → true      true      OK
twoTwo([2, 2, 4, 2]) → false      false      OK
twoTwo([1, 3, 4]) → true      Exception:java.lang.ArrayIndexOutOfBoundsException: -1 (line number:4)      X
twoTwo([1, 2, 2, 3, 4]) → true      Exception:java.lang.ArrayIndexOutOfBoundsException: -1 (line number:4)      X
twoTwo([1, 2, 3, 4]) → false      Exception:java.lang.ArrayIndexOutOfBoundsException: -1 (line number:4)      X
twoTwo([2, 2]) → true      true      OK
twoTwo([2, 2, 7]) → true      true      OK
twoTwo([2, 2, 7, 2, 1]) → false      false      OK
twoTwo([4, 2, 2, 2]) → true      Exception:java.lang.ArrayIndexOutOfBoundsException: -1 (line number:4)      X
twoTwo([2, 2, 2]) → true      true      OK
twoTwo([1, 2]) → false      Exception:java.lang.ArrayIndexOutOfBoundsException: -1 (line number:4)      X
twoTwo([2]) → false      false      OK
twoTwo([1]) → true      false      X
twoTwo([]) → true      false      X
twoTwo([5, 2, 2, 3]) → true      Exception:java.lang.ArrayIndexOutOfBoundsException: -1 (line number:4)      X
twoTwo([2, 2, 5, 2]) → false      false      OK
other tests
X
Your progress graph for this problem

0
Question by:gudii9
• 17
• 8
• 7

LVL 7

Author Comment

ID: 41748219
``````public boolean twoTwo(int[] nums) {
boolean result=false;
for(int i=1;i<nums.length-1;i++){
if((nums[i]==nums[i+1])||(nums[i]==nums[i-1])){
result=true;

}
else{
result=false;
}
}
return result;

}
``````

above approach of starting at index 1 fixed some test cases as below
Expected      Run
twoTwo([4, 2, 2, 3]) → true      true      OK
twoTwo([2, 2, 4]) → true      true      OK
twoTwo([2, 2, 4, 2]) → false      false      OK
twoTwo([1, 3, 4]) → true      false      X
twoTwo([1, 2, 2, 3, 4]) → true      false      X
twoTwo([1, 2, 3, 4]) → false      false      OK
twoTwo([2, 2]) → true      false      X
twoTwo([2, 2, 7]) → true      true      OK
twoTwo([2, 2, 7, 2, 1]) → false      false      OK
twoTwo([4, 2, 2, 2]) → true      true      OK
twoTwo([2, 2, 2]) → true      true      OK
twoTwo([1, 2]) → false      false      OK
twoTwo([2]) → false      false      OK
twoTwo([1]) → true      false      X
twoTwo([]) → true      false      X
twoTwo([5, 2, 2, 3]) → true      true      OK
twoTwo([2, 2, 5, 2]) → false      false      OK
other tests
X

But not sure on how to handle index 0 element
0

LVL 36

Expert Comment

ID: 41748228
Ok, a few pointers to get you started...

• Your code does NOT contain the number 2 anywhere, that would be a first clue as to something wrong
• You don't need to check both AHEAD and BEHIND the current index, just check AHEAD. You don't need to check behind because you would have just compared those two numbers in the previous loop iteration
• Look at the structure of your if/else inside the loop, it will ALWAYS set the result variable to either true or false. This means that anything it does in the initial loop iterations, will ALWAYS be overwritten in later loop iterations, ie. the last loop iteration and ONLY the last iteration will determine the result

Maybe, stating the problem in a different light might help. This is how I might read the problem...

Always return TRUE except if we find ANY 2 that does NOT have an adjacent 2.

I've bolded a few keyword for these reasons... The default return value is TRUE, and only if you find a particular condition do we return false. Also, we only need to find ANY 2 not adjacent to another 2, which means as soon as we find the first 2 that isn't adjacent to another 2, we can stop processing right there and return false, because nothing else in the input could change what we want to return. Finally the main condition that we are looking for is where a 2 does NOT have an adjacent 2, that should help you with your code.

Try thinking about the pseudo-code again, and then when you have that nailed down, then we can look at the code.
0

LVL 28

Expert Comment

ID: 41749715
mccarl has posted some good points. I used some of them to create my code.
``````public boolean twoTwo(int[] nums) {
boolean result = true;
int consecutiveTwos = 0;
for(int num: nums){
if(num == 2){ // found a two
if(consecutiveTwos > 0){ // found twos adjacent to each other
consecutiveTwos++;
result = true;
}
else{ // found a single two
consecutiveTwos = 1;
result = false;
}
}
else{ // found a number that was not a two
if(consecutiveTwos == 1){ // there was a single two
result = false;
break; // break out of for loop
}
else{
consecutiveTwos = 0; // reset variable
}
}
}
return result;
}
``````
0

LVL 7

Author Comment

ID: 41749733
twoTwo([1, 3, 4]) → true      false      X

i thought above should be true as there is no 2 following next to other 2

Given an array of ints, return true if every 2 that appears in the array is next to another 2.

twoTwo([4, 2, 2, 3]) → true
twoTwo([2, 2, 4]) → true
twoTwo([2, 2, 4, 2]) → false

or as challenge did not talk about below i should just blindly assume it is always true?

twoTwo([1, 3, 4])
0

LVL 28

Expert Comment

ID: 41749745
The challenge  was stated as
Given an array of ints, return true if every 2 that appears in the array is next to another 2.

I assumed that if there was not any two in the array, then we would return true.
or as challenge did not talk about below i should just blindly assume it is always true?

twoTwo([1, 3, 4])]
Yes, I think that is what they had in mind. That is what the tests confirm.
0

LVL 7

Author Comment

ID: 41749762
``````public boolean twoTwo(int[] nums) {
boolean result=false;
for(int i=1;i<nums.length-1;i++){
if( (nums[i]==2) && (nums[i]==nums[i+1])||(nums[i]==nums[i-1])){
result=true;

}
else{
result=false;
}
}
return result;

}
``````

changed my code as above and failing 5 tests
Expected      Run
twoTwo([4, 2, 2, 3]) → true      true      OK
twoTwo([2, 2, 4]) → true      true      OK
twoTwo([2, 2, 4, 2]) → false      false      OK
twoTwo([1, 3, 4]) → true      false      X
twoTwo([1, 2, 2, 3, 4]) → true      false      X
twoTwo([1, 2, 3, 4]) → false      false      OK
twoTwo([2, 2]) → true      false      X
twoTwo([2, 2, 7]) → true      true      OK
twoTwo([2, 2, 7, 2, 1]) → false      false      OK
twoTwo([4, 2, 2, 2]) → true      true      OK
twoTwo([2, 2, 2]) → true      true      OK
twoTwo([1, 2]) → false      false      OK
twoTwo([2]) → false      false      OK
twoTwo([1]) → true      false      X
twoTwo([]) → true      false      X
twoTwo([5, 2, 2, 3]) → true      true      OK
twoTwo([2, 2, 5, 2]) → false      false      OK
other tests
X

i am not clear how to handle below logic

or as challenge did not talk about below i should just blindly assume it is always true?
twoTwo([1, 3, 4])]

tried else if() but not working
0

LVL 7

Author Comment

ID: 41749765
``````public boolean twoTwo(int[] nums) {
boolean result=false;
for(int i=0;i<nums.length-1;i++){
if( (nums[i]==2) && (nums[i]==nums[i+1])||(nums[i]==nums[i-1])){
result=true;

}
else{
result=false;
}
}
return result;

}
``````

if i start for loop with i=0 edge cases failing

Expected      Run
twoTwo([4, 2, 2, 3]) → true      Exception:java.lang.ArrayIndexOutOfBoundsException: -1 (line number:4)      X
twoTwo([2, 2, 4]) → true      true      OK
twoTwo([2, 2, 4, 2]) → false      false      OK
twoTwo([1, 3, 4]) → true      Exception:java.lang.ArrayIndexOutOfBoundsException: -1 (line number:4)      X
twoTwo([1, 2, 2, 3, 4]) → true      Exception:java.lang.ArrayIndexOutOfBoundsException: -1 (line number:4)      X
twoTwo([1, 2, 3, 4]) → false      Exception:java.lang.ArrayIndexOutOfBoundsException: -1 (line number:4)      X
twoTwo([2, 2]) → true      true      OK
twoTwo([2, 2, 7]) → true      true      OK
twoTwo([2, 2, 7, 2, 1]) → false      false      OK
twoTwo([4, 2, 2, 2]) → true      Exception:java.lang.ArrayIndexOutOfBoundsException: -1 (line number:4)      X
twoTwo([2, 2, 2]) → true      true      OK
twoTwo([1, 2]) → false      Exception:java.lang.ArrayIndexOutOfBoundsException: -1 (line number:4)      X
twoTwo([2]) → false      false      OK
twoTwo([1]) → true      false      X
twoTwo([]) → true      false      X
twoTwo([5, 2, 2, 3]) → true      Exception:java.lang.ArrayIndexOutOfBoundsException: -1 (line number:4)      X
twoTwo([2, 2, 5, 2]) → false      false      OK
other tests
X
Your progress graph for this problem
0

LVL 28

Expert Comment

ID: 41749773
I don't think you will be successful with your present approach to solving this problem. I think trying to keep track of indexes is too difficult. It is unnecessary. In my code above here, I created the variable "consecutiveTwos" to keep track of the twos as I looped through the array using the for loop.
Also, you should reread mccarl's suggestions.
0

LVL 7

Author Comment

ID: 41749778
``````int consecutiveTwos = 0;
for(int num: nums){
if(num == 2){ // found a two
if(consecutiveTwos > 0){ // found twos adjacent to each other
``````

below is always 0 right and always false as we are initializing to 0 as  int consecutiveTwos = 0;?
if(consecutiveTwos > 0){ // found twos adjacent to each other[/code]
0

LVL 28

Expert Comment

ID: 41749804
below is always 0 right and always false as we are initializing to 0 as  int consecutiveTwos = 0;?

No, it is not always 0.
If a first two is found then it will execute the line
``````consecutiveTwos = 1;
``````
On a subsequent pass through the loop, if another two is found then
``````consecutiveTwos > 0
``````
will be true
0

LVL 28

Assisted Solution

rrz earned 1000 total points
ID: 41749813
It is probably clearer this way.
``````public boolean twoTwo(int[] nums) {
boolean result = true;
int consecutiveTwos = 0;
for(int num: nums){
if(num == 2){ // found a two
if(consecutiveTwos == 0){ // found a single two
consecutiveTwos = 1;
result = false;
}
else{ //  found twos adjacent to each other
consecutiveTwos++;
result = true;
}
}
else{ // found a number that was not a two
if(consecutiveTwos == 1){ // there was a single two
result = false;
break; // break out of for loop
}
else{
consecutiveTwos = 0; // reset variable
}
}
}
return result;
}
``````
0

LVL 36

Accepted Solution

mccarl earned 1000 total points
ID: 41749832
Since we are posting code blindly, this is how I would do it...

``````public boolean twoTwo(int[] nums) {
for (int i = 0; i < nums.length; i++) {
if (nums[i] == 2) {
if (i == (nums.length - 1) || nums[++i] != 2) {
return false;
}
while (i < nums.length && nums[i] == 2) {
i++;
}
}
}
return true;
}
``````

Basic description...

We only need to care if we find a 2, if it is at the end of the array or there is no 2 following it, return false. If it was followed by a 2, the "while" loop skips however many 2's are next to each other (so that it caters for 2, 2 and 2, 2, 2, 2, 2 in the same way)
0

LVL 36

Expert Comment

ID: 41749834
Or another version that may make it easier to understand...

``````public boolean twoTwo(int[] nums) {
for (int i = 0; i < nums.length; i++) {
if (accessArray(nums, i) == 2) {
if (accessArray(nums, i - 1) != 2 && accessArray(nums, i + 1) != 2) {
return false;
}
}
}
return true;
}

private int accessArray(int[] arr, int index) {
return index >= 0 && index < arr.length ? arr[index] : 0;
}
``````
0

LVL 7

Author Comment

ID: 41750703
We only need to care if we find a 2, if it is at the end of the array or there is no 2 following it, return false. If it was followed by a 2, the "while" loop skips however many 2's are next to each other (so that it caters for 2, 2 and 2, 2, 2, 2, 2 in the same way)
private int accessArray(int[] arr, int index) {
return index >= 0 && index < arr.length ? arr[index] : 0;
}

what above method does?

``````for (int i = 0; i < nums.length; i++) {
if (accessArray(nums, i) == 2) {
if (accessArray(nums, i - 1) != 2 && accessArray(nums, i + 1) != 2) {
return false;
}
}
}
``````

above verifies if given number at i index is 2 if true check if last indexed element not 2 and next i+1 element not 2 then return false

all other cases true?
0

LVL 7

Author Comment

ID: 41750709
``````public boolean twoTwo(int[] nums) {
for (int i = 0; i < nums.length; i++) {
if (nums[i] == 2) {
if (i == (nums.length - 1) || nums[i++] != 2) {
return false;
}
while (i < nums.length && nums[i] == 2) {
i++;
}
}
}
return true;
}
``````

instead of ++i if i take i++ i am failing 2 test cases as below. i wonder why(just because increment is after assigment?)
``````Expected	Run
twoTwo([4, 2, 2, 3]) → true	true	OK
twoTwo([2, 2, 4]) → true	true	OK
twoTwo([2, 2, 4, 2]) → false	false	OK
twoTwo([1, 3, 4]) → true	true	OK
twoTwo([1, 2, 2, 3, 4]) → true	true	OK
twoTwo([1, 2, 3, 4]) → false	true	X
twoTwo([2, 2]) → true	true	OK
twoTwo([2, 2, 7]) → true	true	OK
twoTwo([2, 2, 7, 2, 1]) → false	true	X
twoTwo([4, 2, 2, 2]) → true	true	OK
twoTwo([2, 2, 2]) → true	true	OK
twoTwo([1, 2]) → false	false	OK
twoTwo([2]) → false	false	OK
twoTwo([1]) → true	true	OK
twoTwo([]) → true	true	OK
twoTwo([5, 2, 2, 3]) → true	true	OK
twoTwo([2, 2, 5, 2]) → false	false	OK
other tests
OK
``````
0

LVL 28

Expert Comment

ID: 41751376
Mr. Wolfe,
Where can we read EE policy?
Where can we discuss policy?  Do we still have the  "Community Support"  topic area? I could not find it.
0

LVL 36

Expert Comment

ID: 41751428
instead of ++i if i take i++ i am failing 2 test cases as below. i wonder why(just because increment is after assigment?)

Yes, i++ and ++i are a little bit different in how they work, they are called post-increment operator and pre-increment operator (respectively). To understand, run this code somewhere...

``````int i,j;

i = 3;
j = i++;
System.out.println("i = " + i + "     j = " + j);

i = 3;
j = ++i;
System.out.println("i = " + i + "     j = " + j);
``````

As you can see the operator does the same thing to i, in that it will increment it so the new value is 4 in both cases. The difference is in what that expression evaluates to. Because we are assigning the result to j, we get to see what happens.

In the first case, the post-increment operator, the value that was in i gets assigned to j first, and THEN i gets incremented, ie. the increment happens AFTER the value gets assigned to j (the word "post" means "after").

In the second case, the pre-increment operator, the value that was in i gets incremented FIRST, and THEN the new value gets assigned to j, ie. the increment happens BEFORE the value gets assigned to j (the word "pre" means "before").

So in the code above, because we are not only doing the incrementing of i, but we are using that expression as the index in the array, then it matters whether the increment happens before or after we use the value to index the array...

If i = 2, then...
nums[i++]   -   Means get the value of nums at index 2 and then increment i to be 3.
nums[++i]   -   Means increment i to be 3 and then get the value of nums at index 3.

So, yes, it changes the logic of the code that I wrote and definitely would change the test results.
0

LVL 28

Expert Comment

ID: 41751518
@Mr. Wolfe, thank you for responding.
/ Self study
I don't see any mention of it in  "Experts Exchange Terms of Use". In section 6p; "Code of Conduct" there is the phrase "academic honesty"  but gudii9  is(to use your term) "Self Study".   I think we should let him decide how he wants to learn.  His unorthodox way of learning does frustrate a lot of us but maybe that is our problem.

@gudii9
One lesson to learn from this challenge should be the excellent point made by mccarl
we only need to find ANY 2 not adjacent to another 2 ... and return false
compare that to the challenge given by CodingBat
Given an array of ints, return true if every 2 that appears in the array is next to another 2.

You should see the logical equivalency of those two statements.
0

LVL 7

Author Comment

ID: 41752433
I think we should let him decide how he wants to learn.

I am learning a lot from all the experts. All the questions i am asking are for self study only. Explaining and understanding a technical challenge without code is almost next to impossible. Every challenge has n number of approaches and going through each expert code approach opens up new perspective towards that area. I personally prefer solutions with code rather than solutions without code which saves so much  of time for me and and to experts.
0

LVL 28

Expert Comment

ID: 41752609
I personally prefer solutions with code rather than solutions without code which saves so much  of time for me and and to experts.
I agree. I definitely agree.  That is the way I like to learn.  I think having a bunch of solutions from a bunch of people is a very valuable  resource. Given such a resource, I study each and every approach and try to learn how each contributor thinks.  My favorite example is
https://www.experts-exchange.com/questions/20263076/Most-elegant-solution-for-creating-a-star.html
In that discussion, the author(nebeker) created a challenge for the community. The competition was healthy. It was very educational and FUN for everybody involved .  Maybe it is a technique that you could consider using.
0

LVL 7

Author Comment

ID: 41752647
sure, I will check that link.
0

LVL 7

Author Comment

ID: 41755737
``````public boolean twoTwo(int[] nums) {

boolean result=true;

for (int i = 0; i < nums.length; i++) {
if (nums[i] == 2) {
int count = 0;
for (int k = i; k < nums.length; k++) {
if (nums[k] == 2)
count++;
else
break;
}
i = i+count;
if (count < 2)
result=false;
}
}
return result;
}
``````

above also passes all tests
0

LVL 7

Author Comment

ID: 41755739
``````public boolean twoTwo(int[] nums) {
for (int i = 0; i < nums.length; i++) {
if (nums[i] == 2) {
if (i == (nums.length - 1) || nums[++i] != 2) {
return false;
}
while (i < nums.length && nums[i] == 2) {
i++;
}
}
}
return true;
}

Select all

Open in new window

Basic description...

We only need to care if we find a 2, if it is at the end of the array or there is no 2 following it, return false. If it was followed by a 2, the "while" loop skips however many 2's are next to each other (so that it caters for 2, 2 and 2, 2, 2, 2, 2 in the same way)
``````

now above solution is clear
0

LVL 7

Author Comment

ID: 41755742
public boolean twoTwo(int[] nums) {
for (int i = 0; i < nums.length; i++) {
if (accessArray(nums, i) == 2) {
if (accessArray(nums, i - 1) != 2 && accessArray(nums, i + 1) != 2) {
return false;
}
}
}
return true;
}

private int accessArray(int[] arr, int index) {
return index >= 0 && index < arr.length ? arr[index] : 0;
}

0

LVL 36

Expert Comment

ID: 41755837

Ok, so, in a few of the other code examples, a lot of the code is there to deal with bounds of the array, ie. the start and the end, and dealing with these specially to avoid your ArrayIndexOutOfBoundsException.

So what the above method does, is provide a view of the array that pads before the start and after the end with ZERO. So an array with 1, 2, 3 looks like, ... 0, 0, 0, 1, 2, 3, 0, 0, 0, 0 ... However, the 0 index still points to the first element, ie. 1 and the length of the array is still 3. So now we just do a standard loop and check if the number is 2, check if both numbers on either side are NOT 2 and if so, return false.
0

LVL 7

Author Comment

ID: 41755875
is this good idea to use above approach for all array chalenges as i quite often get array out of bound exceptin?

what are we doing in these 2 if loops?

``````if (accessArray(nums, i) == 2) {//check to see if nums[i] is 2 or not?
if (accessArray(nums, i - 1) != 2 && accessArray(nums, i + 1) != 2) {////check to see if nums[i-1] is not 2 and nums[i+1] os not 2 by calling that method which does some padding?
return false;
}
}
``````
0

LVL 36

Expert Comment

ID: 41755883
I think it reads pretty well, and I've already stated this... check the last sentence of my last post. But it is again...

If the value we are looking at (based on i) is a 2 and the value before is NOT a 2 and the value after is NOT a 2, then return false. Or in different words, if the value pointed at by i is a 2 that is surrounded by non-2, return false.
0

LVL 7

Author Comment

ID: 41755885
If the value we are looking at (based on i) is a 2 and the value before is NOT a 2 and the value after is NOT a 2, then return false. Or in different words, if the value pointed at by i is a 2 that is surrounded by non-2, return false.

make sense..all other cases return true
0

LVL 7

Author Comment

ID: 41755887
pads before the start and after the end with ZERO.

pads with how many zero's before and after?
0

LVL 7

Author Comment

ID: 41755890
return index >= 0 && index < arr.length ? arr[index] : 0;

if index >= 0 && index < arr.length is true then return arr[index]
otherwise if false then return 0?
0

LVL 36

Expert Comment

ID: 41755895
if index >= 0 && index < arr.length is true then return arr[index]
otherwise if false then return 0?

Exactly!

pads with how many zero's before and after?

An infinite number... It is not really padding the array at all, it just APPEARS as though it is. ie. you can ask for     accessArray(nums, -12568234969986234)      and it will still return 0. Theoretically, all you need is 1 ZERO at the start and 1 at the end, because you only ever do i - 1 and i + 1, but that would actually be harder to code for than what I did above.
0

LVL 7

Author Comment

ID: 41756870
if index >= 0 && index < arr.length is true then return arr[index] otherwise if false then return 0?

Exactly!

otherwise if false means when index<0 (index can never be less than zero right?
it is 0 or more always in arrays?
and also index>arr.length then it is false so return 0?
is sounds bit complicated to me somehow?
0

## Featured Post

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

In this post we will learn different types of Android Layout and some basics of an Android App.
In real business world data are crucial and sometimes data are shared among different information systems. Hence, an agreeable file transfer protocol need to be established.
This video teaches viewers about errors in exception handling.
In this fourth video of the Xpdf series, we discuss and demonstrate the PDFinfo utility, which retrieves the contents of a PDF's Info Dictionary, as well as some other information, including the page count. We show how to isolate the page count in a…
###### Suggested Courses
Course of the Month11 days, 13 hours left to enroll