I was wondering how to check if two out of three values are the same. My code right now is:
public static boolean twoOutOfThree(int a, int b, int c) {
if ((a == b) || (b == c) || (a == c)) {
return true;
}
return false;
}
This passes all of the tests that are true however when I test it for (0,0,0), it comes back as true instead of false. Any suggestions on what I'm doing wrong?
When all 3 are the same, then a == b obviously is also true. So each 3 of the cases also needs to check that the 3rd one is different. So you need to change
(a == b || b == c || a == c)
to
(a == b && b != c) || (b == c && a !=c ) || (a == c && b != c))
Additional tip
Functions of this form:
if (condition) {
return true;
} else {
return false;
}
Can be written much shorter by just doing
return condition;
So the end result is this:
public static boolean twoOutOfThree(int a, int b, int c) {
return ((a == b && b !=c ) || (b == c && a !=c ) || (a == c && b !=c));
}
Here is a non-optimized solution.
The Set will get rid of duplicates, then just check its final size.
return new HashSet<Integer>(Arrays.asList(a,b,c)).size() == 2;
You could add an extra case to your if statement:
((a==b) || (b==c) || (a==c) && !(a == b & b == c))
There is probably a more efficient way to do this.
You can add a variable called "count" for example , if any value is equal to another then you increment the count by 1 and then you can check if count is equal to 2
You can count as the following solution
public static boolean twoOutOfThree(int a, int b, int c) {
int count = 0;
if (a == b) {
count += 1;
}
if (b == c) {
count += 1;
}
if (c == a)
count += 1;
}
if (count == 2) {
return true;
} else {
return false;
}
}
Just create a Set and add your values in the set. Set always holds unique values only. So if you have 3 numbers and add them to a set and your set length is 3 that none of the numbers are equal to each other. If the length is 2 then 2 numbers where equal and if the length is 1 then all 3 are equal
return !(
(
(a==b)&&(b==c)
) ||
(
(a!=b)&&(b!=c)&&(a!=c)
)
);
Only 10 operators made of
3 AND
1 OR
1 NOT
5 comparisons
I don't know if this is fastest. But if CPU core has multiple ALUs each doing comparisons in parallel, then this could get a boost.
Related
I'm learning to code in Java and I'm doing some online exercises where the answer is not explained too much, so I was just curious why my code is incorrect when it seems to be similar to the solution.
The exercise says -
"Given 2 int values, return true if one is negative and one is positive. Except if the parameter "negative" is true, then return true only if both are negative."
public boolean posNeg(int a, int b, boolean negative) {
if (negative && (a < 0 && b < 0)) {
return true;
}
return (a < 0 && b > 0 || a > 0 && b < 0);
} // This is my code that yields unwanted results
public boolean posNeg(int a, int b, boolean negative) {
if (negative) {
return (a < 0 && b < 0);
}
else {
return ((a < 0 && b > 0) || (a > 0 && b < 0));
}
} // This is the solution code
When running posNeg(-4, 5, true); it comes out to be true even though it is supposed to be false. Whenever one int is negative and the other is positive and negative is true, it is supposed to be false but yields true.
public boolean posNeg(int a, int b, boolean negative) {
if (negative && (a < 0 && b < 0)) {
return true;
}
return (a < 0 && b > 0 || a > 0 && b < 0);
} // This is my code that yields unwanted results
Calling posNeg(-4, 5, true); makes the first condition false negative && (a < 0 && b < 0) <===> true && (true && false) <===> false.
Then the run jumps to the end of that if and evaluates the last condition (a < 0 && b > 0) || (a > 0 && b < 0) which is obviously true.
i need help on a verification on a string
I have to write a method that verify if 2 parameters of the method have the same length and if the second one have numbers between 0 and 3.
Let's see what i wrote :
public static boolean coupEstValide( String combinaison, String coup ){
boolean res = true;
if(combinaison.length() == coup.length()){
int i = 0;
while(i < coup.length() && res == true){
char t = coup.charAt(i);
if(t <= 0 && t >= 3)
res = false;
i++;
}
}
return res;
in my opinion, this should work... But if i do this :
coupEstValide("555", "104");
it should tell me false but it it's telling me it's true.
Do you guys see what's wrong ?
Thanks
When you compare Character with an integer actually ASCII value of that character gets compared with that integer. That's why you keep getting true.
So as already suggested in the comments you should compare it either as if(t >= '0' && t <= '3') or use any Utility method of java.lang such as Character.compare(char lhs, char rhs).
Hope this would be helpful.
Enjoy!
A few of problems in your code:
If the lengths are different, you are still returning true!
Strings are composed of characters. Their value is their character code. 0 to 3 are 48 to 51, respectively. Use character constants not integer constants: if (t == '0') will check if t is the character "0".
Your logic for the comparison isn't right anyways. Using your original (incorrect) example with integers, and correcting from <= and >= based on your comments: if (t < 0 && t > 3) will never be true, t cannot simultaneously be less than 0 and greater than 3. I'll leave the correct boolean statement as an exercise to the reader (hint: or).
Alright, i fixed the problem.
So as you said, i should've use
if(t < '0' || t > '3')
And to fix the problem of the time both are not the same size, i added an else.
So the full code is that :
public static boolean coupEstValide( String combinaison, String coup ){
boolean res = true;
if(combinaison.length() == coup.length()){
int i = 0;
while(i < coup.length() && res == true){
char t = coup.charAt(i);
if(t < '0' || t > '3')
res = false;
i++;
}
}
else
res = false;
return res;
}
Thanks for your help guys !
This would never true. A number can not be less and equal to zero and at the same time greater and equal to 3.
if(t <= 0 && t >= 3)
If you want to evaluate whether a character is between 0 and 3 you must use this:
if(t >= '0' && t <= '3')
Now if you want to evaluate if the character is not between 0 and 3 then try this:
if (t <'0' || t> '3')
String coup = "053";
boolean res = true;
int i = 0;
while (i < coup.length() && res == true) {
System.out.println(coup.length());
int t = Integer.parseInt(coup.charAt(i) + "");
System.out.println("T is " + t);
if (t <= 0 || t >= 3) {
res = false;
i++;
}
System.out.println("Value i " + i);
System.out.println("Value of the Res at last" + res);
}
may be this could be helpful try to convert it to the integer
according to your code
String coup = "053";
boolean res = true;
int i = 1;
while (i < coup.length() && res == true) {
System.out.println(coup.length());
//int t = Integer.parseInt(coup.charAt(i) + "");
char t = coup.charAt(i);
System.out.println("T is " + t);
if (t <= 0 || t >= 3) {
res = false;
i++;
}
System.out.println("Value i " + i);
System.out.println("Value of the Res at last" + res);
}
Here's the question: Given 2 int values greater than 0, return whichever value is nearest to 21 without going over. Return 0 if they both go over.
blackjack(19, 21) → 21
blackjack(21, 19) → 21
blackjack(19, 22) → 19
What I have so far:
public int blackjack(int a, int b) {
if (a>21 && b>21){
return 0;
}
if (a<21 && b>21){
return a;
}
if (b<21 && a>21){
return b;
}
if (21-a < 21-b){
return a;
}
return b;
}
This question is from codingbat.com, and for all the tests that it shows, this code works, but when it finishes and displays "other tests", this code fails. I suppose there's a certain situation where this wouldn't work, but I can't think of it right now. Any thoughts?
public int blackjack(int a, int b) {
// if both a and b are outside the valid range
if (a > 21 && b > 21)
return 0;
// if a is within the valid range but b is not
if (a <= 21 && b > 21)
return a;
// if b is within the valid range but a is not
if (b <= 21 && a > 21)
return b;
// if both a and be are within the valid range
return (a-b >= 0) ? a : b;
// Alternative: return Math.max(a, b); ---as per SimonT in the comment
}
So I guess your issue is that you didn't include 21 in your conditions.
If a=21, b=22, then it will return b which is not correct.
You forgot to specify the = operation in your condition. Change 2nd and 3rd condition to :
if (a<=21 && b>21){
return a;
}
if (b<=21 && a>21){
return b;
}
if I add or subtract two short values, how can I tell if I would need to flag a carry condition
You can do the addition or subtraction using a larger type such as int, cast it to a short, and test if the cast changes the value.
int i = s1 + s2;
short s = (short)i;
if (i != s) { /* overflow */ }
In the case of adding and subtracting only, arithmetic overflow has occurred when both operands are positive and the result is negative and vice versa.
class OverflowTest
{
public static void main (String[] args)
{
System.out.println(isOverflow((short)32767, (short)32767, '+'));
System.out.println(isOverflow((short)-32767, (short)-32767, '+'));
System.out.println(isOverflow((short)32767, (short)-32767, '+'));
}
private static boolean isOverflow(short a, short b, char op) {
short c = (op == '+') ? (short)(a+b) : (short)(a-b);
if((a > 0 && b > 0 && c < 0) || (a < 0 && b < 0 && c > 0))
return true;
return false;
}
}
Hi all I was wondering if there is a way to implement this method without casting to a wider data type (e.g. long, double, etc)?
CanTimes(int a, int b){
returns true if a * b is within the range of -2^31 to 2^31-1, else false;
}
For example, we could implement one for the method CanAdd (without casts) as such:
public static boolean CanPlus(int a, int b) {
if (b >= 0) {
return a <= Integer.MAX_VALUE - b
} else {
return a >= Integer.MIN_VALUE - b
}
}
Implementation language is Java, though of course this is more of a language-agnostic problem.
I was thinking if there's some logic we can employ to decide if a * b fits the range of an integer without casting it to a wider data type?
Solution ! based on Strelok's comment:
public static boolean CanTimes(int a, int b) {
if (a == 0 || b == 0) {
return true;
}
if (a > 0) {
if (b > 0) {
return a <= Integer.MAX_VALUE / b;
} else {
return a <= Integer.MIN_VALUE / b;
}
} else {
if (b > 0) {
return b <= Integer.MIN_VALUE / a;
} else {
return a <= -Integer.MAX_VALUE / b;
}
}
}
As per my comment, here is the adapted version, with some unit tests:
public static int mulAndCheck( int a, int b )
{
int ret;
String msg = "overflow: multiply";
if ( a > b )
{
// use symmetry to reduce boundry cases
ret = mulAndCheck( b, a );
}
else
{
if ( a < 0 )
{
if ( b < 0 )
{
// check for positive overflow with negative a, negative b
if ( a >= Integer.MAX_VALUE / b )
{
ret = a * b;
}
else
{
throw new ArithmeticException( msg );
}
}
else if ( b > 0 )
{
// check for negative overflow with negative a, positive b
if ( Integer.MIN_VALUE / b <= a )
{
ret = a * b;
}
else
{
throw new ArithmeticException( msg );
}
}
else
{
// assert b == 0
ret = 0;
}
}
else if ( a > 0 )
{
// assert a > 0
// assert b > 0
// check for positive overflow with positive a, positive b
if ( a <= Integer.MAX_VALUE / b )
{
ret = a * b;
}
else
{
throw new ArithmeticException( msg );
}
}
else
{
// assert a == 0
ret = 0;
}
}
return ret;
}
#Test( expected = ArithmeticException.class )
public void testOverflow()
{
mulAndCheck( Integer.MAX_VALUE, Integer.MAX_VALUE );
}
#Test( expected = ArithmeticException.class )
public void testOverflow1()
{
mulAndCheck( Integer.MIN_VALUE, Integer.MAX_VALUE );
}
#Test
public void testTimesMinus1()
{
Assert.assertEquals( Integer.MIN_VALUE + 1, mulAndCheck( Integer.MAX_VALUE, -1 ) );
Assert.assertEquals( Integer.MAX_VALUE, mulAndCheck( Integer.MIN_VALUE + 1, -1 ) );
}
You can do the multiplication and then check whether dividing by one factor still gives the other.
EDIT
The above doesn't work all the time, as Dietrich Epp points out; it fails for -1 and Integer.MIN_VALUE. I don't know if there are any other edge cases. If not, then it would be easy to check for this one case.
Since the multiplication of a*b is the same as a+a+a+... repeated b times (and vice-versa), you can do something like this:
(I renamed your CanMultiple() function to isIntMultiplication(), since I think its more clear )
public boolean isIntMultiplication(int a, int b) {
// signs are not important in this context
a = Math.abs(a);
b = Math.abs(b);
// optimization: I want to calculate a*b as the sum of a by itself repeated b times, so make sure b is the smaller one
// i.e., 100*2 is calculated as 100+100 which is faster than summing 2+2+2+... a hundred times
if (b > a) { int swap = a; a = b; b = swap; }
int n = 0, total = a;
while(++n < b) {
if (total <= Integer.MAX_VALUE - a) {
total += a;
} else {
return false;
}
}
return true;
}
You see it in action:
// returns true, Integer.MAX_VALUE * 1 is still an int
isIntMultiplication(Integer.MAX_VALUE, 1);
// returns false, Integer.MAX_VALUE * 2 is a long
isIntMultiplication(Integer.MAX_VALUE, 2);
// returns true, Integer.MAX_VALUE/2 * 2 is still an int
isIntMultiplication(Integer.MAX_VALUE/2, 2);
// returns false, Integer.MAX_VALUE * Integer.MAX_VALUE is a long
isIntMultiplication(Integer.MAX_VALUE, Integer.MAX_VALUE);
This solution does not use long types, as required.
Mathematically, the sum of the log-base-2 should be less than 232. Unfortunately, Math doesn't give us log base 2, but this is still simple enough:
static boolean canMultiply(int a, int b) {
return Math.log(Math.abs(a)) + Math.log(Math.abs(b)) <= Math.log(Integer.MAX_VALUE);
}
EDITED: Due to (fair) flak, how about this simple approach that addresses OP's question exactly?
static boolean canMultiply(int a, int b) {
return a == 0 || ((a * b) / a) == b;
}
If there's an overflow, dividing by the original number won't bring us back to starting number.
Importantly, this will work for longs, which can't be cast up.