For further help with Coding Bat (Java), please check out my books. I am also available for tutoring.
no14:
public boolean no14(int[] nums) { int ones = 0; int fours = 0; for (int i = 0; i < nums.length; i++) { if (nums[i] == 1) ones++; if (nums[i] == 4) fours++; } return ones == 0 || fours == 0; }
isEverywhere:
public boolean isEverywhere(int[] nums, int val) { boolean flag1 = true; boolean flag2 = true; for (int i = 0; i < nums.length; i += 2) if (nums[i] != val) flag1 = false; for (int i = 0; i < nums.length - 1; i += 2) if (nums[i + 1] != val) flag2 = false; return flag1 || flag2; }
either24:
public boolean either24(int[] nums) { Boolean twos = false; Boolean fours = false; for (int i = 0; i < nums.length - 1; i++) { if (nums[i] == 2 && nums[i + 1] == 2) twos = true; if (nums[i] == 4 && nums[i + 1] == 4) fours = true; } return twos ^ fours; }
The caret (^) in the return statement represents the logical XOR operator.
matchUp:
public int matchUp(int[] nums1, int[] nums2) { int count = 0; for (int i = 0; i < nums1.length; i++) if (nums1[i] != nums2[i] && Math.abs(nums1[i] - nums2[i]) <= 2) count++; return count; }
has77:
public boolean has77(int[] nums) { for (int i = 0; i < nums.length - 1; i++) if (nums[i] == 7 && nums[i + 1] == 7) return true; for (int i = 0; i < nums.length - 2; i++) if (nums[i] == 7 && nums[i + 2] == 7) return true; return false; }
has12:
public boolean has12(int[] nums) { int one = 0; int two = 0; for (int i = 0; i < nums.length; i++) { if (nums[i] == 1) one = i; if (nums[i] == 2) two = i; } return two > one; }
The two variables keep track of the position of the number 1 and 2, respectively. After the for loop has finished, they will contain the position of the last 1 and last 2 in the array.
modThree:
public boolean modThree(int[] nums) { for (int i = 0; i <= nums.length - 3; i++) { boolean cond1 = nums[i] % 2 == 0 && nums[i + 1] % 2 == 0 && nums[i + 2] % 2 == 0; boolean cond2 = nums[i] % 2 == 1 && nums[i + 1] % 2 == 1 && nums[i + 2] % 2 == 1; if (cond1 || cond2) return true; } return false; }
haveThree:
public boolean haveThree(int[] nums) { int count = 0; int pos = -2; // in case nums[0] == 3 for (int i = 0; i < nums.length; i++) { if (nums[i] == 3) { count++; if (i - pos == 1) return false; pos = i; } } return count == 3; }
twoTwo:
public boolean twoTwo(int[] nums) { for (int i = 0; i < nums.length; i++) if (nums[i] == 2) { int count = 0; for (int j = i; j < nums.length; j++) if (nums[j] == 2) count++; else break; i += count; if (count < 2) return false; } return true; }
sameEnds:
public boolean sameEnds(int[] nums, int len) { for (int i = 0, j = nums.length - len; i < len; i++, j++) if (nums[i] != nums[j]) return false; return true; }
The for loop traverses the array from back to front and front to back simultaneously.
For further help with Coding Bat (Java), please check out my books. I am also available for tutoring.
Firstly, I’d like to thank you for taking the time to create meaningful solutions to the CodingBat exercises. My comment here is actually in response to your solution for the exercise “haveThree” in the section Array-2: http://codingbat.com/prob/p109783
While your solution is marked correct by CodingBats, I believe there is one problem with it that CodingBats didn’t check. This is your solution found at: http://gregorulm.com/codingbat-java-array-2-part-ii/
public boolean haveThree(int[] nums) {
boolean foundFirst = false;
int first3 = 0;
int last3 = 0;
int count = 0;
for (int i = 0; i = 4);
}
The point in question is the return statement. You check to see if the first “3” is far enough away from the last “3” for it to be possible to have a number in between each 3. It does not actually check if there is a 3 next to any other three, however. So if the array were to be initialized to {3, 3, 1, 1, 3} your program would return true when it should return false. CodingBats never initializes the array as such, which gives the illusion that your solution is correct.
Thanks again for your time, and I apologize if I am incorrect.
Hi Louis,
thank you very much for pointing this out! You are right indeed. Coding Bat does not cover the case you mentioned, and my solution didn’t account for it either. I have therefore rewritten the code, and updated the original post with a shorter and, in my opinion, cleaner solution. So, thanks again for letting me know.
On a related note, my first attempt to rewrite the solution consisted of a single traversal of the array, minus the very last element, and checking whether a “3” is immediately followed by another “3”. I had a counter variable to keep track of the number of occurrences of “3”, and of course I had to add one last check for the very last element of the array. This solution passed all tests on Coding Bat except the “other tests” part, so I had to find a workaround for this issue of the auto grader, which inspired the solution I posted. Unexpectedly, this problem therefore turned into a neat diversion.
Hi Gregor,
Thanks for your work!
I’ve got a remark about the has12 function. It is stated “Given an array of ints, return true if there is a 1 in the array with a 2 somewhere later in the array. “. However, as you check the position of the last 1 and of the last 2, you do not take into account something like {1,3,2,1}. This set should result in a true, however your function would return false, as there is a final 1. This case is not covered by the CodingBat tests.
My solution looks like this:
public boolean has12(int[] nums) {
int i = 0;
for(; i < nums.length; i++)
// a 1 is found
if(nums[i] == 1)
break;
//We start looking for a 2 from the position of the first found1
for (int j=i; j < nums.length; j++)
if(nums[j] ==2) return true;
return false;
}
Hi Frank,
thanks for your comment. Since I did not specify the requirements for has12, I can only rely on my own interpretation, based on the test cases Nick Parlante provides on his site. To me it therefore seems that his description on the problem — “return true if there is a 1 in the array with a 2 somewhere later in the array” — has to be understood as returning False if there is a 1 that is not followed by a 2 later in the array. Therefore, the case you provide, {1,3,2,1}, should result in False, not True.
I’m afraid we have to agree to disagree here, but please note that you’re writing code for a merely imagined test case. Based on Nick Parlante’s test cases, your solution is therefore needlessly complicated.
Thanks for the reply and let us indeed agree to disagree here.
Hi Gregor,
comparing my answers of the Codingbat problems to yours and I have learnt quite a bit form your examples.
However, here I have to agree with Frank. You solution on “has12” is flawed.
To quote: “if there is A 1 in the array with a 2 somewhere later” specifies a single possible case not a case for each ‘1’. Franks case is indeed needlessly complicated, and your needlessly checks the entire array and gives some incorrect outcomes.
This is clearer:
boolean has1=false;
for (int i : nums) {
if(i == 1)
has1 = true;
if(has1 && i == 2)
return true;
}
return false;
It doesn’t really matter what we think the specification means. Nick Parlante, I presume, wrote the test cases on the Coding Bat website, and he would need to be the final arbiter in this case. I think my interpretation is obvious, and the only plausible one. You think the same about yours. My code passes all test cases on the Coding Bat site; yours presumably does as well. Since the test cases permit at least two solutions who differ in a non-trivial aspect, this problem is therefore underspecified. (Please note that I do not want to encourage you, or anyone else, to email Nick Parlante about this matter.)
Hi Gregor,
Concerning the “modThree” exercise, I would have a remark/alternative solution. The solution below is slightly less verbose than yours, as it only checks that three consecutive elements have the same parity, without checking whether they are even or odd.
public boolean modThree(int[] nums) {
for(int i = 0; i < nums.length-2; i++)
if( nums[i] % 2 == nums[i+1] % 2 && nums[i+1] % 2 == nums[i+2] %2 ) return true;
return false;
}
Thank again for the great work provided.
This is a neat idea! Thanks for letting me know.
the modThree solution is elegant. You should have seen the 60 line “solution” that i spent so many days on that btw did not work all the way looked like. Thanks for uploading it…
Hi Gregor,
For twoTwo, I think your solution didn’t take into account the situation where three “2” are placed in the middle, for example {3,3,2,2,2,1,1,3}. Following is my solution:
public boolean twoTwo(int[] nums) {
for (int i=0; i<nums.length; i++) {
if (nums[i]==2) {
if ((i+10 && nums[i-1]==2)) {
i++;
}
else return false;
}
}
return true;
}
Thanks so much for your effort and time.
My solution could probably be rewritten a bit more nicely. I might have a go at it later today. However, your code looks odd to me. Did you paste all of it? For one, (i+10 && nums[i-1]==2) isn’t a legal statement, and ‘i+10’ is cryptic to begin with.
Aha, that’s weird, because I just copied and pasted. Now it should work.
public boolean twoTwo(int[] nums) {
for (int i=0; i<nums.length; i++) {
if (nums[i]==2) {
if ((i+10 && nums[i-1]==2)) {
i++;
}
else return false;
}
}
return true;
}
Okay, i don’t know what happened. Try one more time.
public boolean twoTwo(int[] nums) {
for (int i=0; i<nums.length; i++) {
if (nums[i]==2) {
if ((i+10 && nums[i-1]==2)) {
i++;
}
else return false;
}
}
return true;
}
/*
*Description of Code: In this approach, it takes the #s of ‘2’ and the number of
*’2′ next to each other and compares them to check if all ‘2’ are next to each
other
*I hope this ( ͡° ͜ʖ ͡°)
*/
public Boolean twoTwo(int[] nums) {
int count = 0;
int twos = 0;
for (int i = 0; i 0 && nums[i – 1] == 2){
count += 1;
} else if (i < nums.length – 1 && nums[i + 1] == 2){
count += 1;
}
}
}
return (count == twos);
}
/*
*Description of Code: In this approach, it takes the #s of ‘2’ and the number of
*’2′ next to each other and compares them to check if all ‘2’ are next to each other
*I hope this ( ͡° ͜ʖ ͡°)
*/
public Boolean twoTwo(int[] nums) {
int count = 0;
int twos = 0;
for (int i = 0; i 0 && nums[i – 1] == 2){
count += 1;
} else if (i < nums.length – 1 && nums[i + 1] == 2){
count += 1;
}
}
}
return (count == twos);
}
Oops seems like I posted the error code. My bad.
Strange copy and paste seems broken. Sorry.
Sorry for the spams. How can I delete my replies? The condition before i++ is:
(i+10 && nums[i-1]==2)
and the i++ should be removed. So the complete code is as following:
public boolean twoTwo(int[] nums) {
for (int i=0; i<nums.length; i++) {
if (nums[i]==2) {
if ((i+10 && nums[i-1]==2));
else return false;
}
}
return true;
}
I really hope it works this time……….
Your code still doesn’t make any sense. It doesn’t even compile. Anyway, I’ve rewritten my solution to TwoTwo, which takes your test case into account. It has the added benefit that it is easier to understand, compared to the previous one.
Thanks for your time and sorry for my spams. Every time I wrote the comment, everything worked, but once I posted, it has been changed without reasons. Of course the posted version cannot compile…
Really the last post, if it doesn’t work, then just ignore it. The condition is
if (nums[i+1]==2 when i is not the end) or (nums[i-1]==2 when i is not the start), then do nothing, so simply put a “;”
else return false;
Have a nice weekend!
Try pasting your code again with the
tag.
I have an interesting solution to either24.
public boolean either24 (int[] nums) {
String str=Arrays.toString (nums);
return str.indexOf (“2, 2”)!=-1^str.indexOf (“4, 4”)!=-1;
}
probably a background intensive means of doing it. but still….
For modThree here’s a solution that only does 3 comparisons per loop and only 1 variable added.
public boolean modThree(int[] nums) {
int count=0;
for (int x: nums) {
count=x%2==0? (count> 0? count+1:1):(count 3) return true;
}
return false;
}
Basically for line 4 of my code the less then sign which should follow the count in ….count 3) paired with a greater then sign in line 5.
public boolean modThree(int[] nums) {
int count=0;
for (int x: nums) {
count=x%2==0? (count> 0? count+1:1):(0>count? count-1:-1);
if Math.abs (count==3) return true;
}
return false;
}
hmm my code got whacked from the html tags… need some help to preserve the raw code.
You can use the “code” tag for that purpose.
Hey I just noticed that you guys don’t have a solution for fizzyArray2!?
No, that’s not correct. Just look around some more.
public int[] fizzArray3(int start, int end) {
int[] res = new int[end-start];
for (int i = 0; i < res.length; i++) // index 0
{
if (start < end) {
res[i] = start;
start++;
}
}
return res;
}
Hey thank you for providing the answer. i really appreciate it! it’s good to take a look at different perspective!
I just had a quick comment on sameEnds function:
for time complexity(to avoid using double for-loops), can’t you do something like:
public boolean sameEnds(int[] nums, int len) {
for(int i=0; i<len; i++) {
if(nums[i]!=nums[i+nums.length-len]) {
return false;
}
}
return true;
}
let me know what you think! thanks!
Hello. Thank you for all of these explanations and solutions.
Your Twotwo solution has two loops in it, the requirements on the CodingBat site under the Array-2 section state to use only one loop though..
There is a solution with one loop in the comment section.
Hey, found a much simpler one for isEverywhere, thought I’d share it 🙂
//basically checks every pair of numbers and sees if one is val
//since you’re checking in pairs and if you search to nums.length-1, no out of bounds and it covers everything
public boolean isEverywhere(int[] nums, int val) {
for(int i=0;i<nums.length-1;i++){
if(!(nums[i]==val||nums[i+1]==val))return false;
}
return true;
}
This is the approach I used, which is slightly easier to follow and uses the same logic:
public boolean isEverywhere(int[] nums, int val) {
for(int i = 0; i < nums.length – 1; i++){
if(nums[i] != val && nums[i+1] != val) return false;
}
return true;
}
Gregor’s solution for the isEverywhere problem may be flawed. Just one test case that doesn’t work with Gregor’s code:
[1, 2, 1, 2, 1, 1, 3, 1], 1
You are right. William as well as Richard provided a cleaner solution already, though.
My approach for “either24” was a bit different. I parsed int[] array to String and check if it contains 2s or 4s.
public boolean either24(int[] nums)
{
if( Arrays.toString( nums ).contains( “2, 2” ) &&
!Arrays.toString( nums ).contains( “4, 4” ) )
return true;
if( Arrays.toString( nums ).contains( “4, 4” ) &&
!Arrays.toString( nums ).contains( “2, 2” ) )
return true;
return false;
}
Beginner’s Solution to sameEnds 🙂
Your solution to has12 is nicely thought out! Here’s mine. This is just my initial approach after reading the problem. I program just for fun, btw. Total newbie.
I had a similar idea as well, however inverted in logic:
public boolean has12(int[] nums) {
boolean isOne = false;
for (int i=0;i<nums.length;i++) {
if (nums[i] == 1) isOne = true;
if (isOne && nums[i] == 2) return true;
}
return false;
}
I am also a new programmer, but attempting to leave the realm of "programming for fun"
For has 77, I have done with one FOR statement but with short-circuit AND’s.
public boolean has77(int[] nums) {
for (int i=0; i<nums.length-1; i++){
if (nums[i]==7 && nums[i+1]==7) return true;
if (nums[i]==7 && i <nums.length-2 && nums[i+2]==7) return true;
}
return false;
}
Hi Gregor.
It’s a very nice site you’ve made. However, your solution to “has12” isn’t you at your best performance, if I may be the judge of it. Not only do i agree with those who critizise you for your interpretation of the wording of the task – worse, if I insert your solution into codingbat.com and press “Go”, I get an error. Namely, if there’s no 1’s in the array at all – as in {3, 2}, which it tests for. Your “opponents” code don’t get that same error.
Myself, I got an error in “other tests” for the following code. And I don’t seem to be able to find any input that’ll make err. :/
public boolean has12(int[] nums) {
int i = 0;
while (true){
if (nums[i]==1)
for (int j = i+1; j < nums.length; j++)
if (nums[j]==2) return true;
i++;
if (i==nums.length) break;
}
return false;
}
Oh – and Henrik's code I found very elegant. Thank you!
It could be a bit clearer, I have to admit. I’m an eternal beginner. And I haven’t yet found out how to insert indented code clearly into my comment.
… and I fight a bit with the spam prevention. And to get email updates. Sorry.
My solution
public boolean has12(int[] nums) {
for(int i=0; i<nums.length; i++){
if(nums[i]==1){
for(int j=i; j<nums.length; j++)
if(nums[j]==2) return true;
}
}
return false;
}
Hello! For your has12 code, it does not work for all test cases. To make it work, all you need to do is set the initial positions of one and two to -1 initially and have return two > one && one > -1;.
Otherwise, if the array was [3, 2], let’s say, it would return true even though there are no ones.
Thanks! 🙂
//alternative solution to modThree that i think is easier to understand
public boolean modThree(int[] nums) {
int even =0;
int odd =0;
for(int i=0;i<nums.length;i++){
if(nums[i]%2==0){
even++;
odd=0;
}
else{
odd++;
even=0;
}
if(even==3||odd==3)
return true;
}
return false;
}
public int countClumps(int[] nums) {
int count =0;
boolean clump = false;
for (int i=0; i < nums.length -1; i++){
if (nums[i] == nums[i+1] && !clump){
count++;
clump = true;
}else if (nums[i] != nums[i+1])
clump = false;
}
return count;
}
For the sameEnds problem is there a way to solve it with out putting the two variables in the for loop? For example have two different for loops.
Hey, found a easier to understandr one for either24, thought I’d share it 🙂(I am a novice.)
public boolean either24(int[] nums) {
int two=0;
int four=0;
for(int i=0;i<nums.length-1;i++){
if(nums[i]==2&&nums[i+1]==2) two++;
if(nums[i]==4&&nums[i+1]==4) four++;
}
return two==0&&four!=0||two!=0&&four==0;
}