how to get value of three numbers knowing three information - java

I am trying to solve a problem that I need to get value of three unknowns(x,y,z) knowing some info. their summation is equal to 70, x^2 + y^2 = z^2 and x < y < z.
Answer should be x = 20, y = 21, z = 29
I tried to solve it as two equations in three unknowns but I failed. Any hints to get the solution ? I want to find an algorithm or equation to build a java code that solve this problem

I'll assume that x, y, and z must be positive integers, since removing the integers restriction allows infinitely many solutions. Here is an algorithm--I'll leave the code to you.
Your second equation x^2 + y^2 = z^2 means that x, y, and z form a Pythagorean triple. All solutions to that equation have the form
x = k(m^2 - n^2), y = 2kmn, z = k(m^2 + n^2)
(with possibly x and y swapped) where m, n, and k are positive integers, m > n, one of m and n is even and the other is odd, and (m, n) are relatively prime. You can drop those last two restrictions on m and n, which is to make the triples have unique representation.
Your third limitation x < y < z merely makes a unique triple from the three values. Importantly, your first restriction x + y + z = 70 means that your solution has "small" values.
So in your code, vary the three parameters k, m, and n. There are only finitely many values that allow the sum of x, y, and z to be less than or equal 70, which places limits on k, m, and n. Find the ones that equal make the sum of x, y, and z to be 70. You can cut the number of trials in half by not letting m and n be both even or both odd. You can also avoid explicitly varying k by varying only m and n and calculating what k should be, since each of x, y, z vary proportionally with k, and accept only integral k.
This is somewhat of a brute-force solution, but it is easy to program and will be faster than just trying all values of x, y, and z.
EDIT: I now see that x, y, and z may also be zero. That theoretically means that you need to test for x = 0, but that is clearly impossible here since then y^2 = z^2 which contradicts y < z. So no change is needed to my algorithm.

Expanding on #RoryDaulton's answer, taking x = k(m^2 - n^2), y = 2kmn and z = k(m^2 + n^2) and applying the sum constraint gives us
2*k*m*(m + n) = 70
Or
k * m * (m + n) = 35 = 7 * 5 = 35 * 1
The important thing to note is that the RHS of the above has only two unique factors; the LHS has three. Thus at least one factor of the LHS (k, m, m + n) must be 1.
Since m and n are unique positive integers, m + n will always be greater than 1. Thus,
k = 1 or m = 1
And the only possible values for the remaining LHS factors are 7 and 5 or 35 and 1.
This makes the problem much easier to brute force.

I have solved the question and I want to thank all people who helped me.
This is My code to solve the problem
int x,y,z;
long mul=0;
for(int n=1;n<=sum;n++){
for (int m=2;m<=sum;m++){
x= (int) ((Math.pow(m,2)) - (Math.pow(n,2)));
y= 2*m*n;
z= (int) ((Math.pow(m,2)) + (Math.pow(n,2)));
if(x+y+z == sum){
mul = x*z*y;
}
}}
return mul; }}

Related

Algorithmic approach to find Maximal Product

If 2 integers are given say a and b. Find b positive integers, such that their sum is equal to a and their product is maximal. We have to return the maximum product as an output.
Constraints are -
0<=b<=20
b<=a<=100
What sort of algorithm or approach has to be used to solve this question ?
Suppose we have two integers x,y such that x < y.
(x+1)*(y-1) = x*y + y - x - 1 >= x*y
This is saying that we can make the product bigger by increasing x and decreasing y.
Therefore the optimal answer will have all numbers within 1 unit of each other (or else we can get a better answer).
So our numbers are all equal to either x or x+1 (for some x yet to be determined). Suppose we have k of the bigger numbers, we know there must be b-k of the smaller ones. We can now compute x and k as follows:
x*(b-k)+k*(x+1) = a
b*x - k*x + k*x + k = a
b*x + k = a
therefore x = a // b and k = a % b.
The final product will be x**(b-k)*(x+1)**k.
(Note that there appears to be something odd with the question if sum is equal to a and b > a, because this will be impossible to achieve with positive integers.)

Selecting points such that sum of x coordinates = sum of y coordinates

I have an array of Points. I need to select a subset of points from it, such that the sum of x coordinates of the points = sum of y coordinates of the points.
If there are many such subsets, the one with largest sum of x coordinates is required.
The sum of x coordinates needs to be reported.
I have written a brute force recursive method, which tests all possibilities.
Point[] a = new Point[n];
// ...
private int rec(int i, int x, int y) {
if (i == n - 1) {
if (x + a[i].x == y + a[i].y) return x + a[i].x;
return (x == y) ? x : -1;
}
return Math.max(rec(i + 1, x, y), rec(i + 1, x + a[i].x, y + a[i].y));
}
The answer is rec(0, 0, 0).
My questions are:
1) Is there a dynamic programming solution for this?
2) If yes, could anyone please explain
I have a bit better (than brute force) algorithm.
Divided all coordinates into three sets: 1: {(x,y): x>y}, 2: {(x,y):x==y}, 3:{(x,y): x lower-than y}
Set 2 have to be always included in the solution.
for each (x,y) from 1 define net=x-y and for each (x,y) form 3 define net=y-x
check all possible values you can obtained from nets in 1 and nets in 3.
then basing on the greatest match it is easy to construct the solution.
Does it make sense?
For each point, set its value to x - y.
Now we need to find a set of points whose values sum to 0.
This is exactly the subset sum problem.
It is NP-complete (i.e. there is no known polynomial time algorithm for the generic case of the problem), but there exists a pseudo-polynomial time DP solution, which is given on Wikpedia, linked above. A brief summary:
We define a function Q(i,s) to be the value (true or false) of
there is a nonempty subset of x1, ..., xi which sums to s
Then we have the following recurrence:
Q(1,s) := (x1 == s)
Q(i,s) := Q(i − 1, s) or (xi == s) or Q(i − 1, s − xi) for A ≤ s ≤ B
Unless there are unstated constraints, the problem is NP-Hard by polynomial-time reduction of Subset-Sum, an NP-Complete problem.
One of the decision forms of Subset-Sum asks, given a set of integers, X, and an integer s, does any non-empty subset sum to s.
For each element of X, construct a Point whose x value is the element, and whose y value is zero. Construct one additional Point, whose x value is 0 and whose y value is s.
If the result of the equal-sum problem applied to that set of points is 0 or -1, then reject the subset-sum problem. If the result is s, then accept the subset-sum.
Assuming P != NP, or at least that we don't have any polynomial algorithm for any NP-Hard problem, there is no known polynomial-time algorithm for your problem.
just trying to code in java which would be helpful i felt:
for all i , diffOfCoordinates[i] = Xi - Yi
list will have the max points.
public void fun(int[] diffOfCoordinates, int indexA, int[] b, int indexB, int sum, List<Integer> list){
if(indexA == diffOfCoordinates.length){
if(sum==0){
if(list.size()<indexB){
list.clear();
for(int i=0;i<indexB;i++){
list.add(b[i]);
}
}
}
return;
}
b[indexB] = diffOfCoordinates[indexA];
fun(diffOfCoordinates, indexA+1, b, indexB+1, sum+diffOfCoordinates[indexA], list);
fun(diffOfCoordinates, indexA+1, b, indexB, sum, list);
}

Modulus in Java

I want to get the value of an unknown number in equation containing modulus % in Java
For example:
x % 26 = y if I have the value of y how can I get x
The problem is that there are either zero solutions (if Math.abs(y) >= 26) or an infinite1 number of values of x that satisfy that equation for a given y. The general answer is:
x = 26 * k + y
for any integer value of k. You can pick whatever k you want.2
1 In practice, the range will be limited by the range of integer values you are using. If x and y are int values, then you are limited by Integer.MAX_VALUE and Integer.MIN_VALUE. On the other hand, if they are BigInteger values, you don't have much in the way of range constraints.
2 Actually, the signs of x and y must be the same in Java, so you only have half of infinity to pick from. :-)
You can't get the value of x, that's how modulus works. You just know x = 26 * k + y where k is an integer.

Generate random numbers in increments

I need to generate n random numbers between a and b, but any two numbers cannot have a difference of less than c. All variables except n are floats (n is an int).
Solutions are preferred in java, but C/C++ is okay too.
Here is what code I have so far.:
static float getRandomNumberInRange(float min, float max) {
return (float) (min + (Math.random() * (max - min)));
}
static float[] randomNums(float a, float b, float c, int n) {
float minDistance = c;
float maxDistance = (b - a) - (n - 1) * c;
float[] randomNumArray = new float[n];
float random = getRandomNumberInRange(minDistance, maxDistance);
randomNumArray[0] = a + random;
for (int x = 1; x < n; x++) {
maxDistance = (b - a) - (randomNumArray[x - 1]) - (n - x - 1) * c;
random = getRandomNumberInRange(minDistance, maxDistance);
randomNumArray[x] = randomNumArray[x - 1] + random;
}
return randomNumArray;
}
If I run the function as such (10 times), I get the following output:
Input: randomNums(-1f, 1f, 0.1f, 10)
[-0.88, 0.85, 1.23, 1.3784, 1.49, 1.59, 1.69, 1.79, 1.89, 1.99]
[-0.73, -0.40, 0.17, 0.98, 1.47, 1.58, 1.69, 1.79, 1.89, 1.99]
[-0.49, 0.29, 0.54, 0.77, 1.09, 1.56, 1.69, 1.79, 1.89, 1.99]
I think a reasonable approach can be the following:
Total "space" is (b - a)
Remove the minimum required space (n-1)*c to obtain the remaining space
Shot (n-1) random numbers between 0 and 1 and scale them so that the sum is this just computed "optional space". Each of them will be a "slice" of space to be used.
First number is a
For each other number add c and the next "slice" to the previous number. Last number will be b.
If you don't want first and last to match a and b exactly then just create n+1 slices instead of n-1 and start with a+slice[0] instead of a.
The main idea is that once you remove the required spacing between the points (totalling (n-1)*c) the problem is just to find n-1 values so that the sum is the prescribed "optional space". To do this with a uniform distribution just shoot n-1 numbers, compute the sum and uniformly scale those numbers so that the sum is instead what you want by multiplying each of them by the constant factor k = wanted_sum / current_sum.
To obtain the final result you just use as spacing between a value and the previous one the sum of the mandatory part c and one of the randomly sampled variable parts.
An example in Python of the code needed for the computation is the following
space = b - a
slack = space - (n - 1)*c
slice = [random.random() for i in xrange(n-1)] # Pick (n-1) random numbers 0..1
k = slack / sum(slice) # Compute needed scaling
slice = [x*k for x in slice] # Scale to get slice sizes
result = [a]
for i in xrange(n-1):
result.append(result[-1] + slice[i] + c)
If you have random number X and you want another random number Y which is a minimum of A from X and a maximum of B from X, why not write that in your code?
float nextRandom(float base, float minDist, float maxDist) {
return base + minDist + (((float)Math.random()) * (maxDist - minDist));
}
by trying to keep the base out of the next number routine, you add a lot of complexity to your algorithm.
Though this does not exactly do what you need and does not incorporate the techinque being described in this thread, I believe that this code will prove to be useful as it will do what it seems like you want.
static float getRandomNumberInRange(float min, float max)
{
return (float) (min + (Math.random() * ((max - min))));
}
static float[] randomNums(float a, float b, float c, int n)
{
float averageDifference=(b-a)/n;
float[] randomNumArray = new float[n];
int random;
randomNumArray[0]=a+averageDifference/2;
for (int x = 1; x < n; x++)
randomNumArray[x]=randomNumArray[x-1]+averageDifference;
for (int x = 0; x < n; x++)
{
random = getRandomNumberInRange(-averageDifference/2, averageDifference/2);
randomNumArray[x]+=random;
}
return randomNumArray;
}
I need to generate n random numbers between a and b, but any two numbers cannot have a difference of less than c. All variables except n are floats (n is an int).
Solutions are preferred in java, but C/C++ is okay too.
First, what distribution? I'm going to assume a uniform distribution, but with that caveat that "any two numbers cannot have a difference of less than c". What you want is called "rejection sampling". There's a wikipedia article on the subject, plus a whole lot of other references on the 'net and in books (e.g. http://www.columbia.edu/~ks20/4703-Sigman/4703-07-Notes-ARM.pdf). Pseudocode, using some function random_uniform() that returns a random number drawn from U[0,1], and assuming a 1-based array (many languages use a 0-based array):
function generate_numbers (a, b, c, n, result)
result[1] = a + (b-a)*random_uniform()
for index from 2 to n
rejected = true
while (rejected)
result[index] = a + (b-a)*random_uniform()
rejected = abs (result[index] < result[index-1]) < c
end
end
Your solution was almost correct, here is the fix:
maxDistance = b - (randomNumArray[x - 1]) - (n - x - 1) * c;
I would do this by just generating n random numbers between a and b. Then I would sort them and get the first order differences, kicking out any numbers that generate a difference less than c, leaving me with m numbers. If m < n, I would just do it again, this time for n - m numbers, add those numbers to my original results, sort again, generate differences...and so on until I have n numbers.
Note, first order differences means x[1] - x[0], x[2] - x[1] and so on.
I don't have time to write this out in C but in R, it's pretty easy:
getRands<-function(n,a,b,c){
r<-c()
while(length(r) < n){
r<-sort(c(r,runif(n,a,b)))
r<-r[-(which(diff(r) <= c) + 1 )]
}
r
}
Note that if you are too aggresive with c relative to a and b, this kind of solution might take a long time to converge, or not converge at all if n * C > b -a
Also note, I don't mean for this R code to be a fully formed, production ready piece of code, just an illustration of the algorithm (for those who can follow R).
How about using a shifting range as you generate numbers to ensure that they don't appear too close?
static float[] randomNums(float min, float max, float separation, int n) {
float rangePerNumber = (max - min) / n;
// Check separation and range are consistent.
assert (rangePerNumber >= separation) : "You have a problem.";
float[] randomNumArray = new float[n];
// Set range for first random number
float lo = min;
float hi = lo + rangePerNumber;
for (int i = 0; i < n; ++i) {
float random = getRandomNumberInRange(lo, hi);
// Shift range for next random number.
lo = random + separation;
hi = lo + rangePerNumber;
randomNumArray[i] = random;
}
return randomNumArray;
}
I know you already accepted an answer, but I like this problem. I hope it's unique, I haven't gone through everyone's answers in detail just yet, and I need to run, so I'll just post this and hope it helps.
Think of it this way: Once you pick your first number, you have a chunk +/- c that you can no longer pick in.
So your first number is
range1=b-a
x=Random()*range1+a
At this point, x is somewhere between a and b (assuming Random() returns in 0 to 1). Now, we mark out the space we can no longer pick in
excludedMin=x-c
excludedMax=x+c
If x is close to either end, then it's easy, we just pick in the remaining space
if (excludedMin<=a)
{
range2=b-excludedMax
y=Random()*range2+excludedMax
}
Here, x is so close to a, that you won't get y between a and x, so you just pick between x+c and b. Likewise:
else if (excludedMax>=b)
{
range2=excludedMin-a
y=Random()*range2+a
}
Now if x is somewhere in the middle, we have to do a little magic
else
{
range2=b-a-2*c
y=Random()*range2+a
if (y>excludedMin) y+=2*c
}
What's going on here? Well, we know that the range y can lie in, is 2*c smaller than the whole space, so we pick a number somewhere in that smaller space. Now, if y is less than excludedMin, we know y "is to the left" of x-c, and we're all ok. However, if y>excluded min, we add 2*c (the total excluded space) to it, to ensure that it's greater than x+c, but it'll still be less than b because our range was reduced.
Now, it's easy to expand so n numbers, each time you just reduce the range by the excluded space among any of the other points. You continue until the excluded space equals the original range (b-a).
I know it's bad form to do a second answer, but I just thought of one...use a recursive search of the space:
Assume a global list of points: points
FillRandom(a,b,c)
{
range=b-a;
if (range>0)
{
x=Random()*range+a
points.Append(x)
FillRandom(a,x-c,c)
FillRandom(x+c,b,c)
}
}
I'll let you follow the recursion, but at the end, you'll have a list in points that fills the space with density 1/c

Clojure/Java Mandelbrot Fractal drawing

I am trying to port this algorithm to clojure.
My code is
(defn calc-iterations [x y]
(let [c (struct complex x y)]
(loop [z (struct complex 0 0)
iterations 0]
(if (and (< 2.0 (abs z))
(> max-iterations iterations))
iterations
(recur (add c (multiply z z)) (inc iterations))))))
Multiply, add and abs functions are working as they should. I have tested them with a calculator. However for the following values:
(calc-iterations 0.60703135 -0.33984375) ; should give me 2, instead I get 4
(calc-iterations -1.8421874 0.3515625 ) ; should give me 1, instead I get 3
I am checking the correct iteration numbers using another java applet that I have found on the net. it seems to be working since it produces correct output. Its iteration function is
protected int calcIterations( float x, float y ) {
int iterations = 0;
float xn = x, yn = y;
while ( iterations < MAX_ITERATIONS ) {
float xn1 = xn*xn - yn*yn;
float yn1 = 2*xn*yn;
xn = xn1 + x;
yn = yn1 + y;
float magsq = xn*xn + yn*yn;
if ( magsq > 4 )
break;
iterations++;
}
System.out.println( x + " " + y + " " + iterations );
return iterations;
}
Can anyone spot my error?
I've spotted two differences.
The Java implementation starts at z = (x, y) rather than yours which starts at (0, 0). As your recursive formula is z = z^2 + c, (0, 0)^2 + (x, y) = (x, y) so starting at (x, y) is the same as doing the first iteration. So the number of iterations will come out one less than yours because of this.
The Java implementation increments the number of iterations after checking whether the result, z, is within 2 units from the origin, and doesn't increment it otherwise, whereas yours increments iterations every time. The number of iterations will come out one less than yours because of this also.
So that probably accounts for the differences in your results.
I'd argue that your implementation is more correct, because it distinguishes between the cases where |z| > 2 after one iteration (i.e. where |(x,y)| > 2), and where |z| > 2 after two iterations (i.e. where |(x^2-y^2+x, 2xy+y)| > 2), whereas the Java implementation will perform its first iteration, giving (x^2-y^2+x, 2xy+y), and exit before incrementing the number of iterations, thus not distinguishing between that case.

Categories