I have to use only Boolean and if statements to determine if a number is between 141 and 185 and whether it is lower or higher than that number. I am stumped.
double maxHR= 220- Double.parseDouble(yearsOld); //maximum heart rate
double reserveHR= maxHR- Double.parseDouble(restingHR); //heart rate reserve
double upperEndZone= (reserveHR*.85)+Double.parseDouble(restingHR);
double lowerEndZone= (reserveHR*.50)+Double.parseDouble(restingHR);
boolean isTargetRateLow= lowerEndZone<= Double.parseDouble(restingHR) ;
Is there a way to put two operators within one boolean statement? I think that would solve my issue.
By two operators in one boolean statement do you mean :
boolean bool = a <= b && c >= d
As in the AND operator (&&)
Is this what you need?
boolean isInbetween = (x >= lowerEndZone) && (x <= upperEndZone);
Do you mean something like
// determine if x is in [a,b]
bool in_fully_closed_interval = (a <= x) && (x <= b);
// determine if x is in [a,b)
bool in_closed_left_open_right_interval = (a <= x) && (x < b);
// determine if x is in (a,b]
bool in_open_left_closed_right_interval = (a < x) && (x <= b);
// determine if x is in (a,b)
bool in_open_interval = (a < x) && (x < b);
Yes, I KNOW other people have posted this. I do it to show what I consider more readable variations.
Related
Hey guys I started programming a year ago and recently discovered streams. So I decided to complete my old tasks using streams whenever I could just to get used to them. I know it might not be smart to force using them but it's just practice.
One of my old tasks was to program Minesweeper and right now I try to find a better solution for counting adjacent mines whenever I click a field.
Some details:
I saved a bunch of mines in a Mine[] (arsenal.getArsenal()) and each of the mines has an x and y value. Whenever I click on a field I need to count all mines around the clicked field (from x-1,y-1 till x+1,y+1).
My current solutions are:
private int calculateNearby(int x, int y) {
return (int) Arrays.stream(arsenal.getArsenal())
.filter(mine -> mine.getX() == x + 1 && mine.getY() == y
|| mine.getX() == x && mine.getY() == y + 1
|| mine.getX() == x - 1 && mine.getY() == y
|| mine.getX() == x && mine.getY() == y - 1
|| mine.getX() == x - 1 && mine.getY() == y - 1
|| mine.getX() == x - 1 && mine.getY() == y + 1
|| mine.getX() == x + 1 && mine.getY() == y - 1
|| mine.getX() == x + 1 && mine.getY() == y + 1)
.count();
}
private int calculateNearby(int x, int y) {
return (int) Arrays.stream(arsenal.getArsenal())
.filter(mine ->
{
boolean b = false;
for (int i = -1; i < 2; ++i) {
for (int j = -1; j < 2; ++j) {
if ((x != 0 || y != 0) && mine.getX() == x + i && mine.getY() == y + j) {
b = true;
}
}
}
return b;
})
.count();
}
Both solutions work fine but the first looks "wrong" because of all the cases and the seconds uses for-loops which I basically tried to avoid using.
It would be nice if you could show me a better (ideally shorter) solution using streams. :D
I'm sorry if there's already a thread about this. I really tried to find anything related but there either isn't anything or I searched for the wrong keywords.
You can simplify your stream condition. Instead of checking each case if getX() equals x, x-1 or x+1 you can just check if getX() is greater or equals than x-1 and smaller or equals x+1. The same for getY().
return (int) Arrays.stream(arsenal.getArsenal())
.filter(mine -> mine.getX() >= x - 1 && mine.getX() <= x + 1
&& mine.getY() >= y - 1 && mine.getY() <= y + 1)
.count();
You could also create a method for the check to make the code more readable.
private int calculateNearby(int x, int y) {
return (int) Arrays.stream(arsenal.getArsenal())
.filter(mine -> inRange(mine.getX(), x)
&& inRange(mine.getY(), y))
.count();
}
private boolean inRange(int actual, int target) {
return actual >= target - 1 && actual <= target + 1;
}
Another way is to check if the absolute distance in each direction is less than or equal to 1:
private int calculateNearby(int x, int y) {
return (int) Arrays.stream(arsenal.getArsenal())
.filter(mine -> Math.abs(mine.getX() - x) <= 1 && Math.abs(mine.getY() - y) <= 1)
.count();
}
Note that this also counts a mine which is at the point (x, y) which is not the case with the code in the question.
When is a mine adjacent? When its only one field horizontally or vertically away.
Horizontal distance is Math.abs(mine.getX() - x), vertical distance is Math.abs(mine.getY() - y). It doesn't matter if its -1 or 1, just that it is one field away.
But it shouldn't be more than one field, either vertical or horizontal be away, so max(dx, dy) == 1.
Predicate<Mine> isAdjacent = mine ->
Math.max(
Math.abs(mine.getX() - x)
Math.abs(mine.getY() - y)
) == 1;
return (int) Arrays.stream(arsenal.getArsenal())
.filter(isAdjacent)
.count();
Binary search divide array in 2 parts. But what if I want to divide the array in 4 parts ?
Here is my approach
while (low <= h){
quartal = (low + high) / 4;
if (array[quartal] == x) return quartal;
if (array[2*quartal] == x) return 2*quartal;
if (array[3*quartal] == x) return 3*quartal;
if (array[4*quartal] == x) return 4*quartal;
if (array[quartal] > x) high = quartal-1;
if (array[quartal] < x && array[2*quartal] > x){
low = quartal + 1;
high = 2*quartal-1;
}
if (array[2*quartal] < x && array[3*quartal] > x){
low = quartal + 1;
high = 2*quartal -1;
}
if (array[3*quartal] < x && array[4*quartal] > x){
low = 2*quartal + 1;
high = 3*quartal -1;
}
if (array[4*quartal] < x){
low = 3*quartal + 1;
}
that work but not for all values.
can someone tell me what wrong with my approach?
To answer your question:
Is your array sorted? Binary search only works on sorted arrays.
In the last if-statement, you check if array[4*quartal] < x. Note that this can lead to errors, as quartal is an integer, and therefore 4*quartal will not be equal to (low + high) but rather 4*floor((low+high)/4). Therefore, you may be dividing into 5 segments instead of 5 depending on if (low+heigh) is multiple of 4.
Because 4*quartal should be the end of the segment in your array which you are searching in, I would suggest replacing 4*quartal by (low+high).
I hope this does help.
In addition to what CodingTil has said.
You will have to do the following when doing your checks. Try to think of what would happen with edge cases like a length of 103 or just an array of [0,1]. In your code if we had an array length of 103, we would divide by 4 and get quartels of length 25.75. This can be problematic if we floor the quartel at the start as you'll miss out on values at index 101 and above. You'll have to adjust your other if statements in a similar manner.
if (array[floor(quartal)] == x) return floor(quartal);
if (array[floor(2*quartal)] == x) return floor(2*quartal);
if (array[floor(3*quartal)] == x) return floor(3*quartal);
if (array[high] == x) return high; // should be a whole number so no need to round
Your seventh if statement has an error (your eighth if statement will also have to be adjusted), it should read as follows. And I believe you'll be able to get rid of the ninth if statement altogether.
if (array[floor(2*quartal)] < x && array[floor(3*quartal)] > x){
low = floor(2*quartal) + 1;
high = floor(3*quartal) -1;
}
// high remains unchanged, as we are in the highest quartal
if (array[floor(3*quartal)] < x && array[floor(4*quartal)] > x){
low = floor(3*quartal) + 1;
}
I have some problems with my java code here. When I try to compile I get the error:
"bad operand types for binary operator '&&'" for the if statement
which I usually get when I made an error in the boolean logic. For the past half hour I've tried to find the mistake in my code but I'm not able to find it.
Any pointers?
code below
public String toString(){
double x1 = this.ecke1.getX();
double y1 = this.ecke1.getY();
double x2 = this.ecke2.getX();
double y2 = this.ecke2.getY();
double[] Y = {y1,y2,0};
double[] X = {x1,x2,0};
for (int y = 0; y <= Utils.max(y1,y2,0); y++)
for(int x = 0; x <= Utils.max(x1,x2,0); x++)
if ( ((x=0) && (y=0) ) || ( ( (y/x) <= (Utils.min(X)/Utils.max(Y)) ) && ( (y/x) >= (Utils.min(Y)/Utils.max(X)) ) && ( (y/x) <= ((Utils.max(Y)-Utils.min(Y)) / (Utils.min(X) - Utils.max(X))) ) ) )
System.out.print("#");
else system.out.print("-");
}
Change
(x=0) && (y=0)
to
(x==0) && (y==0)
x=0 is an assignment, so it doesn't evaluate to a boolean. x==0 is a comparison, and returns a boolean.
Use double equal to sign(==) instead of single(=)
if (((x==0) && (y==0) )...)
You use single equal sign for assignment and double for comparison.
= is an assignment operator while == is a comparison operator.
So you need to use x == 0 && y == 0.
I have to make a multiplication function without the * or / operators. I have already made a method like this.
for(int i=0; i < number1; i++){
result += number2;
}
System.Out.println(result);
Now, here is my problem: It was fine until my lecturer change the topic, where the multiplication method must be can multiply decimal value. I had no idea how I can make multiplication method which can work on decimal value with just + and - operator.
yeah you can use log for the multiplication.
log(a*b)=log(a)+log(b)
and then find out the exponential value of log(a)+log(b)
and then you can convert the sign..
for example:
-9*8=-72
log(9*8)=log(9)+log(8)=2.19+2.07=4.27
e^4.27=72
now there is only one -ve no. then it is -72
else it's 72
I'm writing the function for:
void multiply(int num1,int num2)
{
int counter=0;
if(num1<0)
{counter++;num1+=num1+num1;}
if(num2<0)
{counter++;num2+=num2+num2;}
double res=Math.log(num1)+Math.log(num2);
int result=(int)Math.exp(res);
if(counter%2==0)
System.out.println("the result is:"+result);
else
System.out.println("the result is:-"+result);
}
hope this will help you....
You take the decimal numbers and move the decimal point step by step until there is an int left: 0.041 -> 1. step 0.41 -> 2. step 4.1 -> 3. step 41
multiplying 0.041 * 3 could be done by doing the above step 3 times, multiplying 41 * 3 = 123. For the result you take the 123 and undu the steps: 1. 12.3, 2. 1.23, 3. 0.123. There is your result: 0.123 = 0.041 * 3.
Edit:
To determine the number of decimals for each number, you might find the answer in this question: How many decimal Places in A Double (Java)
Answers show within others two ways to solve this quite easy: putting the number to a String and checking where in this String the "."-DecimalPoint occurs, or using the BigDecimal type which has a scale()-Method returning the number of decimals.
You shouldn't expect whole perfect code: But here is a hint to achieve this.
Try to use recursion technique instead for loops.
public double multiplyMe(double x, double y)
{
if(y == 0 || x == 0)
return 0;
if(y > 0 && x > 0 )
return (x + multiplyMe(x, y-1)); // multiply positive
if(y < 0 || x < 0 )
return - multiplyMe(x, -y); // multiply negative
}
one more way by using log:
10 raise to power ( sum of log10(x) and log10(y) )
This approach might be easier to understand. You have to add a b times, or equivalently, b a times. In addition, you need to handle 4 different cases where a and b can be either positive or negative.
public int multiply(int a, int b){
int result = 0;
if (a < 0 && b < 0){
for (int i = a; i <= -1; i++)
result-=b;
}
else if (a < 0){
for (int i = 1; i <= b; i++)
result+=a;
}
else if (b < 0){
for (int i = 1; i <= a; i++)
result+=b;
}
else {
for (int i = 1; i <= b; i++)
result+=a;
}
return result;
}
public static void main(String[] args){
System.out.println(multiply(3,-13)); // -39
}
Is this possible guys? This is homework I have, and my teacher obviously believes it is, but it seems to me that it's impossible not to use addition or multiplication outside of the short-multiplication method.
Write (and provide a tester for) a recursive algorithm:
int multiply(int x, int y)
to multiply two positive integers together without using the *
operator. Do not just add x to itself y times!!!
(Hint: Write a recursive method that will multiply an integer by a
value in the range 0 .. 10. Then write a second recursive method to
implement the multiplication algorithm you learned to multiply
multi-digit numbers in elementary school.)
My issue is that once you break down any multi digit number and starting adding those together you have to use multiplication of numbers greater than 10, i.e 22 * 6 is 2 * 6 + 20 * 6 ... so am I totally missing something?
EDIT
I guess I should have added this is the code I have,
public int mult(int x, int y){
return x == 0 ? 0 : (mult(x-1, y) + y);
}
which is perfect, but as far as I understand the instructions, that's breaking do not just add x to itself y times. I personally believe it isn't, but my teacher hasn't been very clear, and I'd like to know if there's some other way that I havn't thought of, sorry for the confusion.
Yes, it's possible. Yes, I think you're missing something. Try writing down the steps you'd follow to manually multiply two numbers, the way you learned in elementary school.
Then turn those steps into code.
My interpretation of the assignment is that the teacher would like the student to implement a recursive algorithm to perform Grid method multiplication (the kind we learn in elementary school).
For example, multiplying 34 x 13 would be done like so...
34
* 13
====
12
90
40
+300
====
442
I didn't have easy access to a Java development environment, so I wrote the code in C# but the algorithm should be simple enough to convert into Java.
public int Multiply(int x, int y)
{
if (x < 0) throw new ArgumentException("must be positive integer", "x");
if (y < 0) throw new ArgumentException("must be positive integer", "y");
if (x == 0 || y == 0) return 0; // obvious quick-exit condition
// integer division
int xDivBy10 = x / 10;
int yDivBy10 = y / 10;
bool xIsSingleDigit = xDivBy10 == 0;
bool yIsSingleDigit = yDivBy10 == 0;
// base case
if (xIsSingleDigit && yIsSingleDigit)
{
return MultiplySingleDigits(x, y);
}
// otherwise, use grid multiplication recursively
// http://en.wikipedia.org/wiki/Grid_method_multiplication
if (xIsSingleDigit) // y must not be a single digit
{
return (Multiply(x, yDivBy10) * 10) + Multiply(x, y % 10);
}
if (yIsSingleDigit) // x must not be a single digit
{
return (Multiply(xDivBy10, y) * 10) + Multiply(x % 10, y);
}
// else - x and y are both numbers which are not single digits
return (Multiply(x, yDivBy10) * 10) + Multiply(x, y % 10); // the same code as the "if (xIsSingleDigit)" case
}
// technically, this algorith can multiply any positive integers
// but I have restricted it to only single digits as per the assignment's requirements/hint
private int MultiplySingleDigits(int x, int y)
{
if (x < 0 || x > 9) throw new ArgumentException("must be in range 0 - 9 (inclusive)", "x");
if (y < 0 || y > 9) throw new ArgumentException("must be in range 0 - 9 (inclusive)", "y");
if (x == 0 || y == 0) return 0; // base case
return x + MultiplySingleDigits(x, y - 1);
}
NOTES:
This approach still uses the * operator but not for actually multiplying x and y, it is used to increase other sub-products by multiples of 10
Many parts of this code could be simplified/refactored but I specifically left them expanded to make the steps more obvious
Of course you can do it.
First of all, think about the condition. If some number is 0, then the result is? Right.. zero.
So.. You'll have if x is zero or y is zero return 0
Now.. saying X * Y is like saying "X, Y times", which is like writing: X + .... + X (Y times).
So, you'll have something like:
x + multiply(x, y - 1);
You'll have to consider the case in which one of the numbers is negative (But if you understand the basic, I believe you can easily do it).
This solution will work for both when y>=0 and y<0
public int multiply(final int x, final int y) {
if (y != 0 && x != 0) {
if (y > 0) {
return multiply(x, y - 1) + x;
} else {
return multiply(x, y + 1) - x;
}
}
return 0;
}
Easily possible.
int multiply(int x, int y) {
if(y == 0) {
return 0;
}
return x + multiply(x, y - 1);
}
The above fails to take into account the case where y is negative, but you wouldn't want me to do all your work for you . . .
static int Multiply(int x, int y)
{
if (y > 0 && x > 0)
return (x + Multiply(x, y - 1));
if (y < 0 && x > 0)
return -Multiply(x, -y);
if (x < 0 && y > 0)
return -Multiply(-x, y);
if (x < 0 && y < 0)
return Multiply(-x, -y);
return 0;
}