Boolean method to determine consecutive numbers - java

Write a method named consecutive that accepts three integers as parameters and returns true if they are three consecutive numbers; that is, if the numbers can be arranged into an order such that there is some integer k such that the parameters' values are k, k+1, and k+2. Your method should return false if the integers are not consecutive. Note that order is not significant; your method should return the same result for the same three integers passed in any order.
For example, the calls consecutive(1, 2, 3), consecutive(3, 2, 4), and consecutive(-10, -8, -9) would return true. The calls consecutive(3, 5, 7), consecutive(1, 2, 2), and consecutive(7, 7, 9) would return false.
This is what I have so far and keep getting infinite loop error and skipped tests
public boolean consecutive(int x, int y, int z) {
Scanner kb = new Scanner(System.in);
x = kb.nextInt();
y = kb.nextInt();
z = kb.nextInt();
if (((x < y && x < z) && (y < z && ((y - x) == 1) && ((z - x) == 2))) 
||((z < y && ((z - x) == 1) && ((y - x) == 2)))) 
{
return true;
} else if (((y < x && y < z)&& (x < z && ((x - y) == 1) && ((z - y) == 2))) 
|| ((z < x && ((z - y) == 1) && ((x - y) == 2))))
{
return true;
} else if (((z < x && z < y)&& (y < x && ((y - z) == 1) && ((x - z) == 2))) 
||((x < y && ((x - z) == 1) && ((y - z) == 2))))
{
return true;
} else {
return false;
}

What you have there is serious overkill and pretty much unreadable to anyone who hasn't spent a large proportion of their career in C :-)
You should always strive for readability (and hence maintainability) first, reverting to less readable code only when absolutely necessary. Even if you do revert, you should then document why and what you've done so the next poor soul that has to maintain your code won't be cursing your name.
For this specific case, what you are attempting can be achieved in much simpler code such as the following (pseudo-code):
def areConsecutive(a, b, c):
if a > b: swap a, b
if b > c: swap b, c
if a > b: swap a, b
return (b - a == 1) and (c - b == 1)
The three if statements are simply an unrolled bubble sort to ensure a, b and c are in ascending order, then you simply check to ensure the difference between them is one in both cases.
There's no need to put them into a list or array to sort them since sorting three items is relatively easy (the swap can be done with int t = a; a = b; b = t;).
In terms of Java code (once you've moved the input to outside the function where it belongs), you'd end up with something like:
bool areConsecutive(int a, int b, int c) {
int t;
if (a > b) { t = a; a = b; b = t; }
if (b > c) { t = b; b = c; c = t; }
if (a > b) { t = a; a = b; b = t; }
return (b - a = 1) && (c - b == 1);
}

When you are passing value why using scanner?
Remove those lines and its working. You can use another logic to determine consecutive numbers.
public boolean consecutive(int x, int y, int z) {
if (((x < y && x < z) && (y < z && ((y - x) == 1) && ((z - x) == 2))) ||((z < y && ((z - x) == 1) && ((y - x) == 2)))) {
return true;
} else if (((y < x && y < z)&& (x < z && ((x - y) == 1) && ((z - y) == 2))) ||
((z < x && ((z - y) == 1) && ((x - y) == 2)))){
return true;
} else if (((z < x && z < y)&& (y < x && ((y - z) == 1) && ((x - z) == 2))) ||((x < y && ((x - z) == 1) && ((y - z) == 2)))){
return true;
} else
return false;
}

Just Remove these code:
Scanner kb = new Scanner(System.in);
x = kb.nextInt();
y = kb.nextInt();
z = kb.nextInt();
Or use Like this:
public class test{
public static void main(String[] args) {
Scanner kb = new Scanner(System.in);
x = kb.nextInt();
y = kb.nextInt();
z = kb.nextInt();
System.out.println("Result:" + consecutive(x, y, z));
}
public static boolean consecutive(int x, int y, int z) {
if (((x < y && x < z) && (y < z && ((y - x) == 1) && ((z - x) == 2))) || ((z < y && ((z - x) == 1) && ((y - x) == 2)))) {
return true;
} else if (((y < x && y < z) && (x < z && ((x - y) == 1) && ((z - y) == 2)))
|| ((z < x && ((z - y) == 1) && ((x - y) == 2)))) {
return true;
} else if (((z < x && z < y) && (y < x && ((y - z) == 1) && ((x - z) == 2))) || ((x < y && ((x - z) == 1) && ((y - z) == 2)))) {
return true;
} else {
return false;
}
}
}

Create a list with the numbers, sort it and do de diference between the elements:
public static boolean myConsecutive(int x, int y, int z) {
final List<Integer> list = new ArrayList<>();
list.add(x);
list.add(y);
list.add(z);
Collections.sort(list);
return (list.get(2) - list.get(1) == 1 && list.get(1) - list.get(0) == 1);
}

The consecutive method is passed with three values , then why you are reading from the console.
create an array with the size of 3 elements.
Sort the arrays using Arrays.Sort method
Check the difference between the second and the first number is 1 and difference between Third and the second number is 1.
Code :
public boolean consecutive(int x, int y, int z) {
int [] numbers = new int [3];
numbers[0] = x;
numbers[1] = y;
numbers[2] = z;
Arrays.sort(numbers);
boolean isConsecutive = (numbers[1]==numbers[0]+1)&&(numbers[2]==numbers[1]+1);
return isConsecutive;
}

Related

return statements are not coming out right

I need to code a method that checks if:
A = all numbers are equal.
B = no numbers are equal.
C = at least two numbers are equal.
Im just beginning to learn all this in uni but I cant seem to figure out what i am doing wrong in this method which needs to return the given conditions e.g("A", "B", "C").
public static int checkNumbers(int x, int y, int z)
{
int A,B,C;
A = 'A';
B = 'B';
C = 'C';
if((x == y) && (y == z))
{
return A;
}
else if ((x == y) || (x == z) || (y == z))
{
return C;
}
else
{
return B;
}
}
You have declared A, B and C as integers and then assigned to them a 'Char'.
Maybe try
public static char checkNumbers(int x, int y, int z)
{
char A,B,C;
A = 'A';
B = 'B';
C = 'C';
if((x == y) && (y == z))
{
return A;
}
else if ((x == y) || (x == z) || (y == z))
{
return C;
}
else
{
return B;
}
}
Alternatively, use a String
public static String checkNumbers(int x, int y, int z)
{
String A,B,C;
A = "A";
B = "B";
C = "C";
if((x == y) && (y == z))
{
return A;
}
else if ((x == y) || (x == z) || (y == z))
{
return C;
}
else
{
return B;
}
}
return the given conditions e.g("A", "B", "C")
Then you should return a String (or char), not int.
public static String checkNumbers(int x, int y, int z) {
if (x == y && y == z) {
return "A";
} else if (x == y || x == z || y == z) {
return "C";
} else {
return "B";
}
}
public static void main(String[] args) {
System.out.println(checkNumbers(0, 0, 0)); // A
System.out.println(checkNumbers(0, 0, 1)); // C
System.out.println(checkNumbers(0, 1, 2)); // B
}
Otherwise, you need to print (char) checkNumbers(...) to cast the int return value into a printable character

How to avoid StackOverflow Error in Recursive MazeSolver

Like many other java students in college, I need to develop a maze program that solves the maze. My solveMaze method that implements recursion returned a stackoverflow runtime error. How do I solve this problem please? Does this have to do with my algorithm? Thanks in advance.
A) I created a solution maze that array that's going to hold the path to the exit.
B) Then, I implemented a method solveMaze() that took a step toward the exit everytime it's called.
Note: The isWall() method checks if the position you're moving to is a wall or not.
public void showPath() {
int[][] sol = new int[m.length][m[0].length];
for (int j = 0; j < sol.length; j++) {
for (int i = 0; i < sol[0].length; i++) {
sol[j][i] = m[j][i];
}
}
if (solveMaze(sol, m.length - 1, 0, exitCords) == false)
System.out.println("Solution doesn't exist");
else {
for (int y = 0; y < sol.length; y++) {
for (int x = 0; x < sol[0].length; x++) {
if (sol[y][x] == exitCords[0] && sol[y][x] == exitCords[1]) {
System.out.print("E ");
} else {
if (sol[y][x] == 1) {
System.out.print(" ");
} else if (sol[y][x] == 3) {
System.out.print("~");
} else {
System.out.print("# ");
}
}
}
System.out.println();
}
}
}
public boolean solveMaze(int[][] sol, int y, int x, int[] exitCords) {
//exitCords[] is a one-dimensional array that holds the x and y coordinate of the exit point on a maze.
if (y == exitCords[1] && x == exitCords[0]) {//Base Case
return true;
}
//North
if (!isWall(x, y - 1) && sol[y - 1][x] != 3) {
sol[y][x] = 3;//3 is assigned to positions you already visited.
y--;
sol[y][x] = 3;
//Implement recursion to call the solveMaze again on this line.
solveMaze(sol, y, x, exitCords);
return true;
}
//South
else if (!isWall(x, y + 1) && sol[y + 1][x] != 3) {
sol[y][x] = 3;
y++;
sol[y][x] = 3;
solveMaze(sol, y, x, exitCords);
return true;
}
//East
else if (!isWall(x + 1, y) && sol[y][x + 1] != 3) {
sol[y][x] = 3;
x++;
sol[y][x] = 3;
solveMaze(sol, y, x, exitCords);
return true;
}
//West
else if (!isWall(x - 1, y) && sol[y][x - 1] != 3) {
sol[y][x] = 3;
x--;
sol[y][x] = 3;
solveMaze(sol, y, x, exitCords);
return true;
}
/*The following line of code are to get out of dead ends and replace every position near a dead end with a wall*/
else if ((isWall(x, y - 1) && isWall(x, y + 1) && isWall(x + 1, y)) || (isWall(x, y - 1) && isWall(x, y + 1) && isWall(x - 1, y))
|| (isWall(x - 1, y) && isWall(x, y + 1) && isWall(x + 1, y)) || (isWall(x - 1, y) && isWall(x, y - 1) && isWall(x + 1, y))) {
if (isWall(x, y - 1) && isWall(x, y + 1) && isWall(x + 1, y)) {
sol[y][x] = 0;
solveMaze(sol, y, x - 1, exitCords);
return true;
}
if (isWall(x, y - 1) && isWall(x, y + 1) && isWall(x - 1, y)) {
sol[y][x] = 0;
solveMaze(sol, y, x + 1, exitCords);
return true;
}
if (isWall(x - 1, y) && isWall(x, y + 1) && isWall(x + 1, y)) {
sol[y][x] = 0;
solveMaze(sol, y - 1, x, exitCords);
return true;
}
if (isWall(x - 1, y) && isWall(x, y - 1) && isWall(x + 1, y)) {
sol[y][x] = 0;
solveMaze(sol, y + 1, x, exitCords);
return true;
}
}
return false;
}
You have different ways to solve the problem:
The first one is to rewrite your code without using recursion (no luck for tail recursion - Java doesn't have optimization for it)
Another way is to increase stack size using -Xss option
Or you can add actual depth check to solveMaze method, e.g.:
public void showPath() {
// ...
if (solveMaze(sol, m.length - 1, 0, exitCords , 0) == false) {
// ...
}
public boolean solveMaze(int[][] sol, int y, int x, int[] exitCords, int depth) {
if (depth > 64) {
return false;
}
// ...
solveMaze(sol, y, x, exitCords, depth + 1);
// ...
}
A stack overflow error means that your recursion has gone deeper than the language allows. For a small maze, this shouldn't happen, unless you are revisiting locations in the maze. As your code does not seem to make any effort to avoid that, you might want to fix that.

Error message "Operator '&&' cannot be applied to 'int' 'boolean'

public class LargestEven {
public int largestEven(int x, int y, int z) {
if(x % 2 = 0 && x > y && x > z) {
return x;
} else if (y % 2 = 0 && y > x && y > z) {
return y;
} else if (z % 2 = 0 && z > x && z > y) {
return z;
} else {
return 0;
}
}
public static void main(String[] args) {
LargestEven l = new LargestEven();
System.out.println(l.largestEven(1, 3, 5)); //prints 0
System.out.println(l.largestEven(2, 4, 9)); //prints 4
System.out.println(l.largestEven(2, 1001, 1003)); //prints 2
}
}
I have to make a program that finds the largest even number out of 3 given numbers. However I can't seem to get it to work because I keep getting this error message. What exactly am I doing wrong here?
Sorry for the beginner question, but I've never seen this error message before and have no idea what it means or how to fix it.
Thank you in advance.
You have to use == to compare & use = for assignment
if (x % 2 == 0 && x > y && x > z) {
return x;
} else if (y % 2 == 0 && y > x && y > z) {
return y;
} else if (z % 2 == 0 && z > x && z > y) {
return z;
} else {
return 0;
}
You have to check even and odd condition of individual as well as in group for each condition and then check for largest and return.
public int largestEven(int x, int y, int z) {
if (x % 2 == 0 && (y%2!=0 && z%2!=0)) {
return x;
}else if(y%2==0 && (x%2!=0 && z%2!=0) ){
return y;
}else if(z%2==0 && (x%2!=0 && y%2!=0) ){
return z;
}else if(x%2==0 && y%2==0 && z%2!=0){
return x>y?x:y;
}else if(x%2==0 && z%2==0 && y%2!=0){
return x>z?x:z;
}else if(y%2==0 && z%2==0 && x%2!=0){
return y>z?y:z;
}else if(x%2==0 && y%2==0 && z%2==0 ){
return x > y ? (x > z ? x : z) : (y > z ? y : z) ;
}else{
return 0;
}
}
public static void main(String[] args) {
System.out.println(largestEven(6, 3, 4)); //prints 6
System.out.println(largestEven(2, 4, 8)); //prints 8
System.out.println(largestEven(2, 1006, 1003)); //prints 1006
}
In your if and else if statements you have the following lines:
x % 2 = 0
Try changing it to this
x % 2 == 0 // Multiple ==
The single = is used to assign values, like this:
int i = 0;
And two == is used for compares like in your if and else if:
if (i == 0){
...
}
The statement inside the if is an boolean. This would do exactly the same, but assigning it to a boolean first:
boolean x = (i == 0);
if (x){ // OR if (x == true){
...
}
I hope the difference is clear now. I also suggest looking a bit more into the basics of Java or programming in general.
You have used assignment operator = in your conditions instead of == equality operator. Please follow the logic below. I have also given a optimized version of it.
When you are looking at x then make sure other variable (y,z) are not divisible by 2 and if they do then they are less then x. Then replicate the same for other conditions.
public int largestEven(int x, int y, int z) {
if(x % 2 == 0 && ((y % 2 != 0) || (y%2 == 0 && y < x)) && ((z % 2 != 0) || (z % 2 == 0 && z < x))) {
return x;
} else if (y % 2 == 0 && ((x % 2 != 0) || (x%2 == 0 && x < y)) && ((z % 2 != 0) || (z % 2 == 0 && z < y))) {
return y;
} else if (z % 2 == 0 && ((x % 2 != 0) || (x%2 == 0 && x < z)) && ((y % 2 != 0) || (y % 2 == 0 && y < z))) {
return z;
} else {
return 0;
}
}
You can further optimize the conditions check using the information you have gained in your previous checks.
public int largestEven(int x, int y, int z) {
if(x % 2 == 0 && ((y % 2 != 0) || (y%2 == 0 && y < x)) && ((z % 2 != 0) || (z % 2 == 0 && z < x))) {
return x;
} else if (y % 2 == 0 && ((z % 2 != 0) || (z % 2 == 0 && z < y))) {
return y;
} else if (z % 2 == 0) {
return z;
} else {
return 0;
}
}
Once comparing for x when we come to y then we need to worry about x. because it can not be higher y and divisible by 2 so we can remove that from condition. similarly for z.

The values in the if statement is not returning, only returning the else statement (can't run it in the main class)

This subclass won't go through the if statements but only return the else statement so it only returns 0. Also, the main class and subclass are separate java classes.
public class LargestEven {
int largestEven(int x, int y, int z) {
if(x % 2 == 0 && x >= y && x >= z) {
return x; // this part won't return
}
if(y % 2 == 0 && y >= x && y >= z) {
return y; //this part also won't return
}
if(z % 2 ==0 && z >= x && z >= y) {
return z; //this too won't return
}
else {
return 0;
}
}
}
Your code requires that a number is both the largest and even. In your example with values (2, 4, 9), you will not get back 4, because 4 is the largest even between these numbers, but not the largest, i.e. this is not true: y>=z.
You would need to change your checks, so that you only check the valid cases:
public class LargestEven {
int largestEven(int x, int y, int z) {
boolean xIsEven = x%2 == 0;
boolean yIsEven = y%2 == 0;
boolean zIsEven = z%2 == 0;
//checks that x is even and greater from y and z if y and z are
//even respectively
if (xIsEven && (!yIsEven || x>=y) && (!zIsEven || x >= z)) {
return x; // this part won't return
}
//we know for sure that x is not the largest even
//so we skip checking it
if (yIsEven && (!zIsEven || y>=z)) {
return y;
}
//we know that neither x or y are the largest evens
//so return either z if z is even, or 0
return zIsEven ? z : 0;
}
}
It does not appear to be an issue with your function logic... see below, the same function in JS.
function largestEven(x, y, z) {
if (x % 2 == 0 && x >= y && x >= z) {
return x; // this part won't return
}
if (y % 2 == 0 && y >= x && y >= z) {
return y;
}
if (z % 2 == 0 && z >= x && z >= y) {
return z;
} else {
return 0;
}
}
var ele = document.getElementById("result");
ele.innerHTML += "<p>Sending 2, 3, 4 (position z): " + largestEven(2,3,4)+"</p>";
ele.innerHTML += "<p>Sending 3, 4, 2 (position y): " + largestEven(3,4,2)+"</p>";
ele.innerHTML += "<p>Sending 4, 3, 2 (position x): " + largestEven(4,3,2)+"</p>";
ele.innerHTML += "<p>Sending 2, 2, 2 (position x): " + largestEven(2,2,2)+"</p>";
ele.innerHTML += "<p>Sending 3, 3, 3 (no largest): " + largestEven(3,3,3)+"</p>";
<div id="result"></div>

random numbers 1-10 without repeating. Why does this code not work. It compiles but still repeats

This code repeats numbers and with the if statement I wrote in I don't think it should
class RandomNumber {
public static void main(String[] args) {
int y = 0;
int z = 0;
int[] q = new int[10];
while(y != q.length) {
int x = (int) (Math.random() * 10);
if (x != q[0] || x != q[1] || x != q[2] || x != q[3] || x != q[4] || x != q[5]
|| x != q[6] || x != q[7] || x != q[8] || x != q[9]) {
q[z] = x;
System.out.println(q[z]); // or you could print x it doesn't matter
y++; // I just chose this one to make sure each
z++; // q[] was getting set to a value
}
}
}
}
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
Collections.shuffle(list);
Problem solved. And it's also more efficient.
You should use AND and not OR in your condition, since x must be different then all elements in the array.
That said, you should note that the array would be initialized to 0s, so if 0 is one of the valid values you wish to have in the random array, the loop will never terminate.
I would check for duplicates only in the sub-array that was already initialized :
int z = 0;
while(z != q.length) {
int x = (int) (Math.random() * 10);
boolean isDup=false;
for (int i=0;i<z&&!isDup;i++) {
if (x==q[i])
isDup=true;
}
if (!isDup) {
q[z] = x;
System.out.println(q[z]);
z++;
}
}
BTW, y and z are always the same, so you don't need them both.
if (x != q[0] || x != q[1] || x != q[2] || x != q[3] || x != q[4] || x != q[5]
|| x != q[6] || x != q[7] || x != q[8] || x != q[9])
It will be false always . so the your code inside if block is not executed

Categories