I'm given the problem below, however I'm unable to have it pass all the tests no matter what approach I take. Could anyone point out where I'm going wrong?
The problem has to be solved using Math.abs() and IF statements, no loops/functions/etc.
////////////////////////////// PROBLEM STATEMENT //////////////////////////////
// Given three ints, a b c, print true if one of b or c is "close" //
// (differing from a by at most 1), while the other is "far", differing //
// from both other values by 2 or more. Note: Math.abs(num) computes the //
// absolute value of a number. //
// 1, 2, 10 -> true //
// 1, 2, 3 -> false //
// 4, 1, 3 -> true //
///////////////////////////////////////////////////////////////////////////////
My code:
if ((Math.abs(a-b) <= 1 || Math.abs(a+b) <= 1) && (Math.abs(a-c) >= 2 || Math.abs(a+c) >= 2)) {
if (Math.abs(a-c) >= 2 || Math.abs(a+c) >= 2) {
System.out.println("true");
} else {
System.out.println("false");
}
} else if (Math.abs(a-c) <= 1 || Math.abs(a+c) <= 1) {
if (Math.abs(a-b) >= 2 || Math.abs(a+b) >= 2) {
System.out.println("true");
} else {
System.out.println("false");
}
} else {
System.out.println("false");
}
Seems overly complex, you might want to go for something more simple:
boolean abIsClose = Math.abs(a-b) <= 1;
boolean acIsClose = Math.abs(a-c) <= 1;
boolean bcIsClose = Math.abs(b-c) <= 1;
boolean result = abIsClose && !acIsClose && !bcIsClose;
result = result || (!abIsClose && acIsClose && !bcIsClose);
result = result || (!abIsClose && !acIsClose && bcIsClose);
Abs always gives a positive number, that way you don't need to confirm a value is between -1 and 1, you only need to confirm <= 1.
You can break this down into two possible situation when it's true
b is close and c is far
c is close and b is far
Now, what does 1. mean?
b is close - Math.abs(a-b) <= 1
c is far - Math.abs(a-c) >= 2 && Math.abs(b-c) >= 2
So we end up with
if (Math.abs(a - b) <= 1 && Math.abs(a - c) >= 2 && Math.abs(b - c) >= 2) {
return true;
}
Now apply the same logic to the second condition:
if (Math.abs(a - c) <= 1 && Math.abs(a - b) >= 2 && Math.abs(b - c) >= 2) {
return true;
}
So the final method looks like:
public static boolean myMethod(int a, int b, int c) {
if (Math.abs(a - b) <= 1 && Math.abs(a - c) >= 2 && Math.abs(b - c) >= 2) {
return true;
}
if (Math.abs(a - c) <= 1 && Math.abs(a - b) >= 2 && Math.abs(b - c) >= 2) {
return true;
}
return false;
}
Output:
public static void main(String[] args) {
System.out.println(myMethod(1, 2, 10));
System.out.println(myMethod(1, 2, 3));
System.out.println(myMethod(4, 1, 3));
}
true
false
true
Related
I'm unable to get the do-while loop below work in Java. Thanks for your help.
do{
//User enters a value for x
//User enters a value for y
}while(x==-1 && y==-1 || x==5 || y==10);
What I'm trying to do is simply:
a) If x and y BOTH are -1 then terminate the loop
b) If x is 5 OR y is 10 then terminate the loop
You took the problem on the wrong side. There your loop will continue where you want to stop.
You should simply do the following and reverse the condition
do {
} while (!(x == -1 && y == -1 || x == 5 || y == 10));
Demo
public static void main (String[] args) {
System.out.println(conditionTesting(0, -1)); // true
System.out.println(conditionTesting(-1, -1)); // false
System.out.println(conditionTesting(5, -1)); // false
System.out.println(conditionTesting(-1, 10)); // false
System.out.println(conditionTesting(6, 9)); // true
}
public static boolean conditionTesting(int x, int y) {
return !(x == -1 && y == -1 || x == 5 || y == 10);
}
DeMorgan
If you want to go and represent it using DeMorgan's Law, you can do it using the following steps
¬((P ∧ Q) ∨ R ∨ S)
≡¬(P ∧ Q) ∧ ¬R ∧ ¬S
≡(¬P ∨ ¬Q) ∧ ¬R ∧ ¬S
So your final translation would be
(x != -1 || y != -1) && x != 5 && y != 10
Ideone Demo
Maybe I am swatting flies with a sledgehammer but...
I was doing this exerice on CodingBat;
Given 2 ints, a and b, return their sum. However, "teen" values in the range [13, 19] are extra lucky. So if either value is a teen, just return 19.
and this is the answer I came up with;
public int teenSum(int a, int b)
{
if (a >= 13 && a <= 19) return 19;
if (b >= 13 && b <= 19) return 19;
else return a + b;
}
I was wondering if there was a way to solve this problem in just one "if" statement... is there?
If you use a ternary operator (? :) you could do it with zero if statements. Something like,
public int teenSum(int a, int b)
{
return (a > 12 && a < 20) || (b > 12 && b < 20) ? 19 : a + b;
}
You can have a logically equivalent expression using logical OR:
if ((a >= 13 && a <= 19) || (b >= 13 && b <= 19)) return 19;
Sure. By putting two if statements as guard clauses, what you're really doing is a logical OR. So:
if ((a >= 13 && a <= 19) || (b >= 13 && b <= 19)) return 19;
would also work.
By the way, the else is redundant.
You can do it entirely without if statements, using the ?: ternary operator.
return (a >= 13 && a <= 19) || (b >= 13 && b <= 19) ? 19 : a + b;
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I have three if statements:
if (!(a == 0 && b == 0)) {...}
if (!(a == 0 && b != 0)) {...}
if (!(a != 0 && b != 0)) {...}
I would like to combine them in one code block such as a method.
I don't want the other statements to run if one has run. There are workarounds if I want to avoid coming up with some good logic but I'd like to know if there is a beautiful way to write that.
if (!(a == 0 && b b == 0)) {...}
truth table
a b r
z n T
n n T
z z F
n z T
for
if (!(a == 0 && b b != 0)) {...}
truth table
z n F
n n F
z z T
n z T
for
if (!(a != 0 && b b != 0)) {...}
truth table
z n T
n n F
z z T
n z T
common case
n z T
so result that works on all 3 condition is
a != 0 && b == 0
note that: all 3 conditions are totally different, this will only work if you care to execute if
(first && second && third) is true
validate all case by yourself
(z = zero, n = non zero, a, b variables, r = result, T = true, F = false)
Simplest way to express this:
public int foo(boolean a, boolean b) {
int result;
if (a) {
if (b) { result = 1; }
else { result = 2; }
else {
if (b) { result = 3; }
else { result = 4; }
return result;
}
(notice that this evaluates a and b once each, which is the minimum you can expect here)
To keep #DavidWallace happy, here's a translation to the particular form of the original question:
public int foo(int a, int b) {
int result;
if (a==0) {
if (b==0) { result = 1; } // or whatever should happen, not specified in the question
else { result = 2; }
else {
if (b==0) { result = 3; }
else { result = 4; }
return result;
}
Just to re-word your question. You say that if one block runs, the others shouldn't. So when you wrote
if (!(a == 0 && b == 0)) {...}
if (!(a == 0 && b != 0)) {...}
if (!(a != 0 && b != 0)) {...}
You actually meant
if (!(a == 0 && b == 0)) {
// first ...
}
else if (!(a == 0 && b != 0)) {
// second ...
}
else if (!(a != 0 && b != 0)) {
// third ...
}
But this is equivalent to
if (a != 0 || b != 0) {
// first ...
}
else if (b == 0) {
// second ...
}
Notice that the third ... can never run, as I stated in my comment.
This is code from Cracking the Coding Interview 5th Edition
I got this from
https://code.google.com/p/ctci/source/browse/trunk/Java/Introduction/CompareBinaryToHex/CompareBinaryToHex.java?spec=svn18&r=3 (didn't want to take and upload a picture of a few pages from the book)
Here's the code
public class CompareBinaryToHex {
public static int digitToValue(char c) {
if (c >= '0' && c <= '9') {
return c - '0';
} else if (c >= 'A' && c <= 'F') {
return 10 + c - 'A';
} else if (c >= 'a' && c <= 'f') {
return 10 + c - 'a';
}
return -1;
}
public static int convertToBase(String number, int base) {
if (base < 2 || (base > 10 && base != 16)) return -1;
int value = 0;
for (int i = number.length() - 1; i >= 0; i--) {
int digit = digitToValue(number.charAt(i));
if (digit < 0 || digit >= base) {
return -1;
}
int exp = number.length() - 1 - i;
value += digit * Math.pow(base, exp);
}
return value;
}
public static boolean compareBinToHex(String binary, String hex) {
int n1 = convertToBase(binary, 2);
int n2 = convertToBase(hex, 16);
if (n1 < 0 || n2 < 0) {
return false;
} else {
return n1 == n2;
}
}
public static void main(String[] args) {
System.out.println(compareBinToHex("111001011", "1CB"));
}
}
Basically a method inside this class compareBinToHex, takes in String representations of a binary number and a hex number and returns whether or not they are equal or not(in decimal value). It uses the method convertToBase to convert from that base to decimal.
My question is for the convertToBase method, why are base inputs in the range 2-9 and 16 allowed, but
base inputs from 11-15 are not? (Base inputs in range 2-9 and 16 will not go in the return -1 if block) Gayle, the author later summarized that it's better to write code that is more flexible and general-purpose which I would agree with and is the reasoning behind my argument for the allowance of 11-15 base inputs. Say if you're working with base 11. I believe convertToBase should still work for this because you're counting to 'A' which should still work behind the logic(range 'A' to 'F') in digitToValue. Is there a reason why she disallowed those inputs?
Because very few people need a base (or radix) 11, 12, 13, 14 or 15 calculator. It's important to note that base 8 is octal, base 2 is binary, base 10 is decimal and base 16 is hexadecimal. I would go further and suggest you explicitly check it's one of those,
if (base != 2 && base != 8 && base != 10 && base != 16) return -1;
I am trying to learn Dynamic Programming and one of the examples they give in Wikipedia of what is not Dynamic Programming, is a recursive way of getting Fibonacci sequence up to certain number. I.E.
Given a recursive function, say:
fib(n) = 0 if n = 0
1 if n = 1
fib(n - 1) + fib(n - 2) if n >= 2
We can easily write this recursively from its mathematic form as:
function fib(n)
if(n == 0 || n == 1)
n
else
fib(n-1) + fib(n-2)
But I cannot get the pseudo code to work.
when I do this method in Java, I get an error the operator + is undefined for methods void:
public void fib(int n) {
if (n == 0 || n == 1) {
System.out.println(n);
} else
return fib(n - 1) + fib(n - 2);
}
in the line with return fib(n - 1) + fib(n - 2), you add the return values of the fib() function. So you should actually return a (int) value, even if n==0||n==1.
public int fib(int n) {
if (n == 0 || n == 1) {
return n;
}
else {
return fib(n - 1) + fib(n - 2);
}
}
you then call and print you result from outside the function:
System.out.println(fib(42));
It has no return type so you can't mathematically add it to anything, let alone itself.
public void fib(int n) //returning void
Give it a return type
public int fib(int n) //yey \o/
Try this.
public class Test
{
public static int fib( int n )
{
if ( n == 0 || n == 1 )
return n;
else
return fib( n - 1 ) + fib( n - 2 );
}
public static void main( String[] args )
{
System.out.println(fib( 6 ));
}
}
Just change return type of fib function to int.
and in function change
if (n == 0 || n == 1){return n; }