How to write a LessThan method without using the operator - java

How would you recursively write a method that checks if a number is less than the other without using the '<' operator?
You can only use the plus, minus, times, and equals operators.
It must be recursive
x and y will always be 0 or greater
Should return boolean
If needed, you can make other methods but they must follow rules above.
Cove I've got so far:
public static boolean isLessThan(int x, int y) {
if(x == y - 1) return true;
if(x == y + 1) return false;
if(x == y) return false;
return isLessThan((x), (y-1)) || isLessThan((x-1), y);
}

Because you have made a good-faith attempt by writing your own code, and because I see this is a kind of puzzle, I'm offering you below code which has only a single recursive call rather than having two recursive calls like in your code.
I think this is as simple as it gets while satisfying the constraints.
What it does: it counts down both numbers to zero, and checks which one reaches zero first. If both reach zero at the same time, the result should be false, but simply checking whether y is zero already includes that check.
public static boolean isLessThan(int x, int y) {
if (y == 0) {
return false;
}
if (x == 0) {
return true;
}
return isLessThan(x - 1, y - 1);
}
#Andreas' answer is more efficient than the above. My aim initially was for a short, clean answer.
I've tried to create a shorter bitshift approach.
Although harder to grasp than the counting example, it has a better complexity and it has an equal amount of lines as the above code (I'm not counting that constant as I could include it inside the code at the expense of readability).
Note that this code shifts left rather than right and - it checks the most significant bit first.
public static final int HIGH_BIT = 1 << 31;
public static boolean isLessThan(int x, int y) {
if (x == y) {
return false;
}
if ((x & HIGH_BIT) != (y & HIGH_BIT)) {
return (y & HIGH_BIT) == HIGH_BIT;
}
return isLessThan(x << 1, y << 1);
}
Note: if != is disallowed, you can change the second if statement to:
if (((x ^ y) & HIGH_BIT) == HIGH_BIT)
Also note that the complexity is really O(1) as, although the algorithm is theoretically O(log n), Java ints are 32 bits so the upper bounds is O(32) which is the same as O(1).

You could do it like the answer to this question:
Bitwise operations equivalent of greater than operator
However that doesn't honor rule 2: It must be recursive.
According to comment, rule 1 should be:
You can only use plus, minus, multiply, equals, and bitwise operators.
With the use of the right-shift operator, we can get a solution in O(log n) time, unlike answer by Erwin Bolwidt, which is O(n) time, and likely to cause StackOverflowError.
public static boolean isLessThan(int x, int y) {
return compare(x, y) == -1;
}
private static int compare(int x, int y) {
if (x == y)
return 0; // x == y
if (x == 0)
return -1; // x < y
if (y == 0)
return 1; // x > y
// Compare higher bits. If different, then that is result
int cmp = compare(x >> 1, y >> 1);
if (cmp != 0)
return cmp;
// Only bit 0 differs, so two choices:
// x0 == 1 && y0 == 0 -> return 1
// x0 == 0 && y0 == 1 -> return -1
return (x & 1) - (y & 1);
}
If != is not allowed, code can be changed to:
// same code up to and including recursive call
if (cmp == 0)
return (x & 1) - (y & 1);
return cmp;

Related

Writing recursive method to compare even and odd digits within number

Basically, I am trying to write a method where a number is inputted and if there are more odd digits than even digits in the number, it returns "true", and else, false. I think I need to use tail recursion but I cannot figure it out.
public static boolean moreOddThanEven(int x) {
if (x == 0) {
return false;
}
if (x % 2 == 0) {
return moreOddThanEven(x / 10);
} else {
return moreOddThanEven(x / 10);
}
}
public static boolean moreOddThanEven2(int x) {
return moreOddThanEvenTR(x, 0, 0);
}
public static boolean moreOddThanEvenTR(int x, int odd, int even) {
if (x == 0) {
return false;
}
if (x%2==0) {
return moreOddThanEvenTR(x / 10, odd, even+1);
}
if (x%2!=0) {
return moreOddThanEvenTR(x / 10, odd+1, even);
}
if (odd <= even) {
return false;
} else {
return true;
}
}
I think using tail recursion is the right idea. Here is my attempt, assuming we can use more than one parameter in the recursive function:
public static boolean compareOddEven(int x, int count) {
//This is when we reach the end of the recursion (ones place).
if(x<10) {
//if odd, add 1, if even subtract 1
count += (x%2==1) ? 1 : -1;
return count>0;
}
else{
int digit = x;
//We use this loop in order to get the leftmost digit and read whether it is odd or even.
//Subsequently, we add or subtract 1 to the count based on the digit's parity and we pass this count into the next recursion in order to keep track.
while (digit > 9) {
digit /= 10;
}
count += (digit%2==1) ? 1 : -1;
//Get rid of the first digit to get next number to use in recursive call.
int removedFirstDigit = x % (int) Math.pow(10, (int) Math.log10(x));
//tail recursion
return compareOddEven(removedFirstDigit, count);
}
}
Explanation. We can accomplish this with just one method if we keep track of the count of odd and even digits the second parameter of the method. It will be less cumbersome to keep track of the count rather than keeping track of both counts of the odd and even numbers (and avoids the comparisons at the end which would not make it a tail recursion).
With this in mind, our approach is to start at the leftmost digit of the number we input and move to the right with each new recursive call. It is possible to start from right and go left in counting the parity of the digits as well.
So with every new recursive call, we pass in the count to the function as an argument. When we finally reach the ones digit, the nonnegativity of the count tells us whether there are more odd or even digits. To see this more clearly, I recommend printing out some of the arguments right before the recursive call is made.
Further note that when we reach the ones place, the truth value of count>0 will be propagated up the chain of recursive calls to give the final result that we desire.
Example call:
System.out.println(compareOddEven(21468233, 0));
Output:
false
There is a simple reason why you are stuck: you have to count the evens/odds like in 77778888888999. In fact you need to count the sum of (odds - evens), the oddity.
public static boolean moreOddThanEven(int x) {
assert x >= 0;
return x != 0 && oddity(x) > 0;
}
private static int oddity(int x) {
if (x == 0) {
return 0;
}
if (x % 2 == 0) {
return oddity(x / 10) - 1;
} else {
return oddity(x / 10) + 1;
}
}
Recursion is not needed (nor is more than one line):
public static boolean moreOddThanEven(int x) {
return (""+x).replaceAll("[02468]", "").length() > ((int) Math.log10(x)+1) / 2;
}
or the longer, but non-mathy version:
public static boolean moreOddThanEven(int x) {
return (""+x).replaceAll("[02468]", "").length() > ((int) (""+x).replaceAll("[13579]", "").length();
}
If you have an easier time thinking about loops than tail recursion, it's worth knowing that you can translate any loop into tail recursion (and vice versa, but that's different topic). First, we need to get the loop into this shape:
initialize a, b, ...
while (<some condition on a, b, ...>) {
Update a, b, ... using old values of a, b, ...
}
return <any function of a, b ...>
it translates to:
TypeOfReturn while_loop(TypeOfA a, TypeOfB b, ...) {
if (!(<some condition on a, b, ...>)) {
return <any function of a, b, c ...>;
}
Update a, b, ... using old values of a, b, ...
return while_loop(a, b, ...);
}
Let's apply this to your problem. As a loop:
// x is the input
int oddMinusEven = 0;
while (x) {
oddMinusEven += 2 * (x % 2) - 1;
x /= 10;
}
return oddMinusEven > 0;
We get:
bool hasMoreOddThanEvenDigits(int x, int oddMinusEven) {
if (!x) return oddMinusEven > 0;
oddMinusEven += 2 * (x % 2) - 1;
x /= 10;
return hasMoreOddThanEvenDigits(x, oddMinusEven);
}
We can clean this up a bit to make it less verbose:
int hasMoreOddThanEvenDigits(int x, int oddMinusEven) {
return x ? hasMoreOddThanEvenDigits(x / 10, oddMinusEven + 2 * (x % 2) - 1) : oddMinusEven > 0;
}
We run the loop with a "top level" function call that initializes variables:
return getMoreOddThanEvenDigits(x, 0) > 0;
It's fun to see what a good compiler does with the two codes. As you'd expect, they lead to nearly identical machine code. If we can do a rule-based transformation, so can the compiler.

Comparing Even/Odd numbers w/ java and boolean [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 5 years ago.
Improve this question
I am writing a method that takes in two numbers and will return true if they are both even or both odd... and will return false if only one is odd and one is even.
It needs to return a boolean statement, but it is not working.. Any help is appreciated! Thanks...
public static boolean compareEvenOdd(int x, int y) {
if((x % 2 ==0) && ( y% 2==0))||((x%2 != 0) && (y%2 != 0)){
return true;
} else
return false;
}
You can do the following (possibly the shortest version):
public static boolean compareEvenOdd(int x, int y) {
return ((x + y) % 2) == 0;
}
The sum of two odd numbers and the sum of two even numbers is even, the sum of one odd and one even number is odd. So you add the numbers and check if the solution is dividable by 2.
This is a really good opportunity to use a bitwise operator. You can use the binary AND (&) operator with the number 1 to reduce an integer to just its last binary digit. This last digit is always 0 for an even number and 1 for an odd number. If your two numbers have the same last binary digit, then they have the same parity - that is, they're both even or both odd. So I would write the method like this.
public boolean sameParity(int x, int y) {
return (x & 1) == (y & 1);
}
Note that the parentheses are important, because the usual Java order of operations puts == above &.
Seems you are missing an additional pair of parentheses around the condition in the if-statement.
This works for me:
public static boolean compareEvenOdd(int x, int y) {
if (((x % 2 ==0) && ( y% 2==0))||((x%2 != 0) && (y%2 != 0))){
return true;
} else
return false;
}
if this is not to your liking, yould you further specify what is not working? Is it throwing errors as you run it, is the output wrong,...?
Explication :
x and y are odd : x+y are even
x and y are even : x+y are even
x is odd and y is odd : x+y are odd
x is even and x is even : x+y are odd
public static boolean compareEvenOdd(int x, int y) {
return (x+y)%2==0
}
An if-statement always has the form if (...) with its own parentheses around the condition. Hence you missing just that.
So (with unneeded braces removed):
public static boolean compareEvenOdd(int x, int y) {
if ((x % 2 == 0 && y % 2 == 0)
|| (x%2 != 0 && y % 2 != 0)) {
return true;
} else
return false;
}
And as shown in the other answers this should be simplified,
as if+return boolean means using boolean redundantly, not to the fullest (like == true):
return (x % 2 == 0 && y % 2 == 0)
|| (x % 2 != 0 && y % 2 != 0);
return (x % 2) == (y % 2);
return (x - y) % 2 == 0;

ceil conterpart for Math.floorDiv in Java?

Is there any ceil counterpart for Math.floorDiv()
How to calculate it fastest way with what we have?
UPDATE
The code for floorDiv() is follows:
public static long floorDiv(long x, long y) {
long r = x / y;
// if the signs are different and modulo not zero, round down
if ((x ^ y) < 0 && (r * y != x)) {
r--;
}
return r;
}
Can we code ceil the similar way?
UPDATE 2
I saw this answer https://stackoverflow.com/a/7446742/258483 but it seems to have too many unnecessary operations.
There is none in the Math class, but you can easily calculate it
long ceilDiv(long x, long y){
return -Math.floorDiv(-x,y);
}
For example, ceilDiv(1,2) = -floorDiv(-1,2) =-(-1)= 1 (correct answer).
I'd also just use the negation of floorMod, but if you are going to define your own function, you could simply adapt the above code:
public static int ceilDiv(int x, int y) {
int r = x / y;
// if the signs are the same and modulo not zero, round up
if ((x ^ y) >= 0 && (r * y != x)) r++;
return r;
}
You can make use of the floorDiv function and fiddle with that:
int ceilDiv(int x, int y) {
return Math.floorDiv(x, y) + (x % y == 0 ? 0 : 1)
}

Multiplication using increments

My assignment is to write a recursive function to multiply two numbers together, using only an addition function, ++, and --. My addition function is:
public static int peanoplus(int x, int y) {
if(y==0) return x;
else return peanoplus(++x,--y);
}
What I have so far for my multiplication function is:
public static int peanotimes(int x, int y)
{
if(y==0) return x;
else return peanotimes(peanoplus(x,x),--y);
}
I am not exactly sure what to put in the first parameter for the peanotimes function. Right now the issue is that I'm doubling the number, rather than adding it to the original number. I know that I need to maintain the x variable so that the recursive calls can continue adding the original number (instead of doubling every time), but then where would I actually add the numbers?
I found this which is very similar to my question, but even with those tips I am unable to find a solution.
if( y == 0 || x == 0 ) { return 0; }
else { return peanoplus(x, peanotimes(x,--y)); }
This version closest matches the formal Peano axiom of x * S(y) = x + (x * y)
public static int peanotimes(int x, int y)
{
if (y == 0) {
return 0; // terminate recursion, NB: not "x"
} else {
return peanoplus(x, peanotimes(x, --y));
}
}

Java - Recursive function of the Euclidean Algorithm

I can't seem to convert the following algorithm into Java successfully, please forgive the horrible picture quality but a question I'm working on asks:
I have tried to use the following code to represent the Euclidean Algorithm, but it doesn't seem to work. I don't really know how I would go about representing it in Java code. Any help?
public static int gcd(int x, int y) {
if (y == 0) {
return x;
} else if (x >= y && y > 0) {
return gcd(y, (x % y));
}
}
Thank you.
There is no arbitrary order between x and y.
Your code is not complete!
What if x < y? Your code does not return a value then!
What the book fails to mention is that the two parameters to the function do not necessarily need to be in descending order (ie x >= y). What you need to do is compute the gcd considering this fact.
Simply you can do the following:
public static int gcd ( int x , int y )
{
if ( y == 0 )
return x;
else if ( x >= y && y > 0)
return gcd ( y , x % y );
else return gcd ( y , x ); // if x < y then go ahead and switch them around.
}
You are almost there. You need to consider what happens when y > x, and return the result from the final else branch (hint: x and y can freely switch places).
You are almost there.
Your code does not compile, because there is no catch all clause that return from the function.
It really depends on whether you are going to pass negative values of y into this function. If you expect only positive values, just throw an exception.
public static int gcd(int x, int y) {
if (y == 0) {
return x;
} else if (x >= y && y > 0) {
return gcd(y, (x % y));
}
throw
new IllegalArgumentException(
String.format(
"Unexpected values for x(%d) and y(%d)",
Integer.valueOf( x ),
Integer.valueOf( y )
)
);
}
Here's what I have that accounts for negative numbers:
public static int gcd(int x, int y)
{
if (y == 0)
return x;
if (x < 0)
return gcd(x * -1, y); //turns the first parameter to a positive if it's initally negative
if (y < 0)
return gcd(x, y * -1); //turns the second parameter to a positive if it's initally negative
if (y <= x && x % y == 0)
return y;
return gcd(y, x%y);
}
Note with negative numbers, if you try to find the greatest common divisor, and either of the numbers is negative, you can just change it to a positive and the result would be the same.
If both of the numbers are negative, then I'm not sure what the gcd should be. 1? -1? idk so I left that out. The code I have just treats it as if they were both positive.

Categories