int function(int a, int b, int c){
if(a==c)
return a;
else
return b;
}
Question is to achieve a same o/p without using if, while, do, for, switch,conditional expression(?:) and other general inbuilt methods like equals
Please tell me the logic and code..
Here's one fairly straightforward option:
int function(int a, int b, int c) {
java.util.HashMap<Boolean, Integer> map = new java.util.HashMap<Boolean, Integer>();
map.put(true, a);
map.put(false, b);
return map.get(a == c);
}
Using maps to emulate switch statements in languages that don't have them is pretty common. Using them to emulate if statements is probably an abuse.
Here's an approach using operators only:
int function(int a, int b, int c) {
//If a == c: result = 0x00000000
//Else: result = 0xFFFFFFFF
int result = (a - c | c - a) >> 31;
//If a == c: result = 0x00000000 & (a ^ b) = 0
//Else: result = 0xFFFFFFFF & (a ^ b) = a ^ b
result &= a ^ b;
//If a == c: result = 0 ^ a = a
//Else: result = (a ^ b) ^ a = b
result ^= a;
return result;
}
I really wish I came up with Cairnarvon's solution. Here's what I got, but in any case you'll end up using conditional statements somewhere hidden in a function call, unless you can figure out how to do this with bitwise operators.
public static int fn(int a, int b, int c) {
Boolean equal = (a == c);
//if equal is false, compareTo will return 0.
//if equal is true, compareTo will return any positive integer, thus we take mod 2 to ensure this is 1
int ret_a = equal.compareTo(Boolean.FALSE) % 2;
//if ret_a is 0, make ret_b = 1
//if ret_a is 1, make ret_b = 0
int ret_b = (ret_a + 1) % 2;
//one of these two terms is guaranteed to be zero, therefore you will only
//return the value of a, or b.
return (ret_a * a) + (ret_b * b);
}
Here is my attempt at a solution with no comparison or bit twiddling. Sadly as #Pshemo pointed out my logic is flawed.
public static int fn(int a, int b, int c) {
//I assumed this will return 1 if not a != c
//See Pshemo's comment about why this is wrong.
int not_equal = ((a - c) * (a - c) ) % 2;
int ret_a = (not_equal + 1) % 2;
int ret_b = not_equal;
//one of these two terms is guaranteed to be zero, therefore you will only
//return the value of a, or b.
return (ret_a * a) + (ret_b * b);
}
There are a number of possible approaches, including:
Do the test in native code. That's cheating.
Find some library class that can used to do the job. There are probably lots of variations on this approach; e.g. see #Cairnarvon's answer.
Do something tricky to generate an exception (or not) depending on the inputs. My initial idea was to use division by zero, but here's another way ...
int insanelyStupidConditional (int a, int b, int c) {
int[] dummy = new int[1];
try {
int foo = dummy[a - c];
} catch (ArrayIndexOutOfBoundsException ex) {
return b;
}
return a;
}
Bit twiddling ... like #Vlad's answer
Anyway, the point of the interview question is not the answer, but whether you are able to think outside of the box to arrive at something. The most practical answer is "change the requirements ... this is insane".
Another way
Base idea return b * f(a,c) + a * (1 - f(a,c)) where
f(a,c) -> 1 for a != c
f(a,c) -> 0 for a == c
so
for a!=c we will return b*(1) + a*(0);
and for a==c we will return b*(0) + a*(1);
code
public static int test(int a, int b, int c) {
// (a - c) | (c - a) will give
// for a != b negative value
// for a == c zero
// to get sign of that value we need to get highest bit
// so >>>31 will do the trick
int signum = ((a - c) | (c - a)) >>> 31;
//for a == c -> signum = 0
//for a != c -> signum = 1 (it indicates that (a - c) | (c - a) was negative)
return b * signum + a * (1 - signum);
}
There you go, no if, while, do, for, switch, inline if (?:), or any other operator (==, !=, >, <, >=, etc.):
int function(int a, int b, int c){
int[] result = {-1, a, b};
return result[new TreeSet<Integer>(Arrays.asList(a, c)).size()];
}
Logic: Adds both a and c to a Set. If they are equal, they'll be added only once, and the set's size will be 1. If they are different, the size will be 2.
Related
I am trying to work out this problem on codingbat and the problem is Given 2 positive int values, return the larger value that is in the range 10..20 inclusive, or return 0 if neither is in that range. The solution has been given below but I can not understand the first part as the comment says larger value is a, but the code says( b > a ) and what does this mean: int temp = a; a = b; b = temp;. Can anyone please explain it...
public int max1020(int a, int b) {
// First make it so the bigger value is in a
if (b > a) {
int temp = a;
a = b;
b = temp;
}
// Knowing a is bigger, just check a first
if (a >= 10 && a <= 20) return a;
if (b >= 10 && b <= 20) return b;
return 0;
}
The first if statement makes sure that a is not smaller than b (if a is smaller than b, it swaps a and b - that's what the 3 assignment statements involving the temp variable do).
The second if statement returns a if it's in the required range (and at this point we know a >= b).
If not, the third if statement returns b if it's in the required range.
Otherwise 0 is returned (when both a and b are not in the required range).
It says that if the value of b is greater than that of a, switch the 2 values. So, for example, if a = 10 and b = 15:
if (b > a) { is true so will get in the if
int temp = a; temp will take the value 10
a = b; a will take the value 15
b = temp; b will take the value 10
So, the values of a and b will be switched, if the value of b is greater than that of a. Therefore, a will have the bigger value.
The code that I have written is as follows :
/*
Program to find the 3rd largest no from 4 nos without using arrays and
only using 3 comparators or comparisons
*/
package d;
public class thirdlargest {
public static void main(String args[]) {
int a=1,b=2,c=3,d=4,soln;
soln= Math.min(Math.max(a,b),Math.max(c,d));
System.out.println("Third largest=" +soln);
}
}
/*
Output:
Third largest=2
*/
But this only works for the used pattern of input if I change the pattern the output will be wrong. How can I fix this code with only using 3 comparators or comparisons strictly and we can use any programming language
IMO it is not possible to find third largest number out of 4 numbers using only three comparisons:
public static void main(String[] args) throws IOException {
int a=1,b=2,c=3,d=4,soln;
int maximum1 = Math.max(a,b);
int maximum2 = Math.max(c,d);
if(maximum1 < maximum2) {
// either c or d and we need more comparisons
}
else {
// either a or b and we need more comparisons
}
}
Edit: Actually we can find the largest number or smallest number using 3 comparisons but probably not the third largest etc.
Also check this answer for finding kth largest number in O(n) time.
This answer on the Math StackExchange site discusses the problem of finding the 2nd largest of N values. It states (with proof) that the lower (tight) bound is N + ceiling(log2N) - 2
For N == 4, that evaluates to 4.
(This applies here because the 3rd largest of 4 is also the 2nd smallest of 4.)
I don't think the proof excludes (hypothetical) solutions with less than 4 comparisons that rely on the N numbers being unique. But that was not part of the problem statement.
Thanks to #invisal for link to algorithm to find the maximum of two numbers without using comparison operator.
I flipped it to return minimum instead, then used as follows to find second lowest value, aka third highest:
private static int thirdHighest(int a, int b, int c, int d) {
int lowest = min(min(a,b),min(c,d));
if (a == lowest)
return min(min(b,c),d);
if (b == lowest)
return min(min(a,c),d);
if (c == lowest)
return min(min(a,b),d);
return min(min(a,b),c);
}
private static int min(int a, int b) {
return b - (((a - b) >> 31) & 0x1) * (b - a);
}
Exactly 3 == comparisons.
Works for input numbers in any order and also works if duplicate numbers are given.
Note: If inputs are constrained to be distinct, then the answer by #ajb can truly do it without any comparisons, by using the min/max bit manipulation of the link provided by #invisal.
I'm not sure what the exact definition of "comparator" is, the way they're using it. But assuming that Math.min and Math.max don't count as comparators, here's a way to compute it using no comparisons or comparators:
public static int thirdLargest(int a, int b, int c, int d) {
int min = Math.min(a, Math.min(b, Math.min(c,d)));
int offset = min + 1 - Integer.MIN_VALUE;
a -= offset;
b -= offset;
c -= offset;
d -= offset;
min = Math.min(a, Math.min(b, Math.min(c,d)));
return min + offset;
}
Computing the third largest number is the same as computing the second smallest number. The trick in this code is that it computes the smallest number, then subtracts from each number the exact offset needed to make the smallest number wrap around and become Integer.MAX_VALUE, while not wrapping around for the other values. The smallest of the remaining numbers is now the second smallest of the original numbers, minus the offset, which we'll add back.
However, I'll concede that this only works if all four numbers are distinct--or, at least, if the lowest two numbers are distinct. It fails if you give it a=1, b=1, c=2, d=3--it outputs 2 instead of 1. At least this should get you points for your problem-solving skill, which is what I assume the question is intended to find out. It had better not be to find out how you would actually solve this in a production situation, because putting restrictions like this on production code (no arrays) would be lunacy.
EDIT:
Here's another solution. There's one comparison in the code, but it's in a method that's executed three times, so that should count as three comparisons.
public static int thirdLargest(int a, int b, int c, int d) {
if (isThirdLargest(a, b, c, d)) {
return a;
}
if (isThirdLargest(b, a, c, d)) {
return b;
}
if (isThirdLargest(c, a, b, d)) {
return c;
}
return d;
}
public static boolean isThirdLargest(int a, int b, int c, int d) {
int z = 3 + ((b - a) >> 31) + ((c - a) >> 31) + ((d - a) >> 31);
// z = number of other parameters that are >= a. Note that all of the
// shift operations will return either 0 or -1.
int y = 3 + ((a - b) >> 31) + ((a - c) >> 31) + ((a - d) >> 31);
// y = number of other parameters that are <= a
int x = -y >>> 31;
// x = 1 if there are any other parameters <= a, 0 if not. Note that
// x can be 0 only if z == 3.
int w = z & (x << 1);
// This will be 2 if a is the third largest. If z == 2, then x == 1
// and w will be 2. If z == 3, and x == 1, that means that a is the
// smallest but is equal to at least one of the other parameters;
// therefore a is also the third largest. But if x == 0, a is
// strictly smaller than all other parameters and is therefore not the
// third largest.
return w == 2;
}
Note: This may suffer from overflow problems, if there are two numbers that differ by 231 or greater. Converting all the parameters to long should avoid the problem (also all the 31's would be changed to 63), but I haven't tested it.
The solution posted by #Andreas is very clean and readable. There is another solution that is less clean and less efficient. The solution relies on catching errors when dividing by zero. We keep on adding 1 to each number and then use the following expression to see if an error occurred:
1 / (currentNumber - Integer.MAX_VALUE)
The second number that threw an error will be the third largest number out of the four. Even though the code has 4 comparison operators =. It will only run two of these statements: One for the first error, and one for the second error. For a total of two comparison statements. This method works for any set of input integers, both positive and negative.
public class thirdlargest
{
public static void main(String args[])
{
System.out.println("Third highest number: " + thirdHighest(1, 2, 3, 4));
System.out.println("Third highest number: " + thirdHighest(4, 3, 2, 1));
System.out.println("Third highest number: " + thirdHighest(-5, -4, -3, -2));
System.out.println("Third highest number: " + thirdHighest(0, 0, 0, 0));
}
private static int thirdHighest(int a, int b, int c, int d)
{
int testa = a, testb = b, testc = c, testd = d;
int divisionResult;
int numberFound = 0;
while(true)
{
try
{
divisionResult = 1 / (testa++ - Integer.MAX_VALUE);
}
catch(Exception ex)
{
numberFound++;
if(numberFound == 2)
{
return a;
}
}
try
{
divisionResult = 1 / (testb++ - Integer.MAX_VALUE);
}
catch(Exception ex)
{
numberFound++;
if(numberFound == 2)
{ return b;
}
}
try
{
divisionResult = 1 / (testc++ - Integer.MAX_VALUE);
}
catch(Exception ex)
{
numberFound++;
if(numberFound == 2)
{
return c;
}
}
try
{
divisionResult = 1 / (testd++ - Integer.MAX_VALUE);
}
catch(Exception ex)
{
numberFound++;
if(numberFound == 2)
{
return d;
}
}
}
}
}
import java.util.Scanner;
public class TmaxFourNo {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("Enter no.'s:");
int w = sc.nextInt();
int x = sc.nextInt();
int y = sc.nextInt();
int z = sc.nextInt();
int m1 = Math.min(Math.max(w, x), Math.max(y, z));
int m2 = Math.max(Math.min(w, x), Math.min(y, z));
if (m1 < m2) {
System.out.println("Tmax=" + m1);
} else {
System.out.println("Tmax=" + m2);
}
sc.close();
}
}
private static int setGCD()
{
int a, b;
gCD(a,0) = a; //here -the left-hand side of the assignment must be a variable//
gCD(a,b) = gCD(b,a%b); //here -the left-hand side of the assignment must be a variable//
finalNumer = enterNumer/gCD; //here -cannot make static reference to finalNumer, enterNumer, or gCD//
finalDenom = enterDenom/gCD;//here -cannot make static reference to finalDenom, enterDenom, gCD
}
This method’s purpose is to find the Greatest Common Denominator (GCD) of a numerator and denominator entered by the user in the above programming. But I keep getting the stated errors (in the comments), which is confusing me because that was the way my teacher wrote it on the board, but it made absolutely no sense to me! Please help!
There are 2 implementations for the Euclidean algorithm:
Iterative (pseudocode):
function gcd(a, b)
while a ≠ b
if a > b
a := a − b
else
b := b − a
return a
Recursive (pseudocode):
function gcd(a, b)
if b = 0
return a
else
return gcd(b, a mod b)
I believe that you want the latter, based on what you have written:
public static int gcd(int a, int b) {
if (b == 0)
return a;
else
return gcd(b, a % b);
}
Pretty easy to turn pseudocode into proper Java.
This function returns what you are looking for, then you can use its output to set gcd wherever you like:
public static int gcd(int a, int b)
{
while (a != b)
{
if (a > b)
{
a = a - b;
}
else
{
b = b - a;
}
}
return a;
}
See the wiki article on Euclidean Algorithm.
How do I write this code in Java?
def gcd(a, b):
"""
Calculate the Greatest Common Divisor of a and b.
Unless b==0, the result will have the same sign as b (so that when
b is divided by it, the result comes out positive).
"""
while b:
a, b = b, a%b
return a
It seems I can't do while (b) { in Java because of Type mismatch error. It seems I also can't do the line a, b = b, a%b exactly in Java as well.
public static int gcd(int a, int b) {
int temp;
while(b != 0) {
temp = a;
a = b;
b = temp % b;
}
return a;
}
Java expects the condition of the while to be a boolean, not an int.
The a, b = b, a%b syntax will not work in Java. You need to do the assignments individually.
So you can set a = b, and then set b = a % b. I used a temp variable to hold the old value of a so that I can compute a % b (before I overwrote a with a = b).
Do you really need a while? It can be as simple as-
public static int gcd(int a, int b) {
if (b == 0) return a;
return gcd(b, a % b);
}
Ok I'm doing this programming assignment and need a little help.
Here is the problem:
Given three ints, a b c, return true if it is possible to add two of the ints to get the third.
twoAsOne(1, 2, 3) → true
twoAsOne(3, 1, 2) → true
twoAsOne(3, 2, 2) → false
Here's the what I have gotten so far:
public boolean twoAsOne(int a, int b, int c) {
return a + b != c;
}
It keeps saying it is not fully correct and I do not know where I am going wrong.
The question asks if it is possible to add any two to get the remaining one. Your code tests only if the first two add to the third.
Thus, twoAsOne(3,1,2) should return true because 3 = 1 + 2; but you are only checking whether 3 + 1 = 2, which is false.
You're only checking one of the possibilities and, on top of that, you're checking it wrongly since you'll return false if a + b == c (because you're using the != operator).
I'm not going to do you homework for you, but the full list of possibilities is:
n1 = n2 + n3
n2 = n1 + n3
n3 = n1 + n2
It should be a simple matter: the result should be true if any of those is true. Otherwise the result should be false.
Or, to provide even a more obvious clue: it should be true if one or more of those conditions are met. Else it should be false.
I don't know how much more obvious I can make it without writing the code for you :-)
Update: And now that more than enough time has probably elapsed to make the homework point moot, here's my solution:
public boolean twoAsOne (int n1, int n2, int n3) {
if (n1 == n2 + n3) return true;
if (n2 == n1 + n3) return true;
if (n3 == n1 + n2) return true;
return false;
}
Although those last two lines could be replaced with:
return (n3 == n1 + n2);
I prefer the (to me, anyway) more readable version.
Besides the answers provided by itowlson and Pax, since you are dealing with ints, there is a possibility that they will overflow, e.g.
Integer.MAX_VALUE + 1 == Integer.MIN_VALUE
Which is not mathematically true
You may want to check this kind of scenarios to make your program complete.
Your code only takes into consideration the sum of int a and int b. The solution requires all possibilities to be covered i.e. "sum of int a and int c" and "sum of int b and int c". Refer to the code mentioned below, hope it helps!
public boolean twoAsOne(int a, int b, int c) {
return ((a + b == c) || (b + c == a) || (c + a == b));
}
Dude I hope you got the answer by now... if you haven't
public boolean twoAsOne(int a, int b, int c) {
return ((a+b==c) || (a+c==b) || (b+c==a));
}
I might be very late yet I have minimized it. twoAsOne
public boolean twoAsOne(integer a, integer b, integer c){
return ((a+b) == c ? true : (a+c) == b ? true : (b+c == a)? true : false);
}
package get_third;
public class Get_third {
int a , b ,c ;
boolean third_value(int a , int b , int c){
if(a+b==c||b+c==a||c+a==b)
{
return true;
}
else
return false ;
}
public static void main(String[] args) {
Get_third obj =new Get_third();
System.out.println(obj.third_value(1, 2, 3));
System.out.println(obj.third_value(3, 1, 2));
System.out.println(obj.third_value(3, 2, 2));
}
}
// start
public boolean twoAsOne(int a, int b, int c) {
if (a + b == c) {
return true;
}
else if (a + c == b) {
return true;
}
else if (b + c == a) {
return true;
}
else {
return false;
}
}
// end