I have used Solve to find the solution of an equation in Mathematica (The reason I am posting here is that no one could answer my question in mathematica stack.)The solution is called s and it is a function of two variables called v and ro. I want to find imaginary and real part of s and I want to use the information that v and ro are real and they are in the below interval:
$ 0.02 < ro < 1 ,
40
The code I used is as below:
ClearAll["Global`*"]
d = 1; l = 100; k = 0.001; kk = 0.001;ke = 0.0014;dd = 0.5 ; dr = 0.06; dc = 1000; p = Sqrt[8 (ro l /2 - 1)]/l^2;
m = (4 dr + ke^2 (d + dd)/2) (-k^2 + kk^2) (1 - l ro/2) (d - dd)/4 -
I v p k l (4 dr + ke^2 (d + dd)/2)/4 - v^2 ke^2/4 + I v k dr l p/4;
xr = 0.06/n;
tr = d/n;
dp = (x (v I kk/2 (4 dr + ke^2 (d + dd)/2) - I v kk ke^2 (d - dd)/8 - dr l p k kk (d - dd)/4) + y ((xr I kk (ro - 1/l) (4 dr + ke^2 (d + dd)/2)) - I v kk tr ke^2 (1/l - ro/2) + I dr xr 4 kk (1/l - ro/2)))/m;
a = -I v k dp/4 - I xr y kk p/2 + l ke^2 dp p (d + dd)/8 + (-d + dd)/4 k kk x + dr l p dp;
aa = -v I kk dp/4 + xr I y k p/2 - tr y ke^2 (1/l - ro/2) - (d - dd) x kk^2/4 + ke^2 x (d - dd)/8;
ca = CoefficientArrays[{x (s + ke^2 (d + dd)/2) +
dp (v I kk - l (d - dd) k p kk/2) + y (tr ro ke^2) - (d -
dd) ((-kk^2 + k^2) aa - 2 k kk a)/(4 dr + ke^2 (d + dd)/2) == 0, y (s + dc ke^2) + n x == 0}, {x, y}];
mat = Normal[ca];
matt = Last#mat;
sha = Solve[Det[matt] == 0, s];
shaa = Assuming[v < 100 && v > 40 && ro < 1 && ro > 0.03,Simplify[%]];
reals = Re[shaa];
ims = Im[shaa];
Solve[reals == 0, ro]
but it gives no answer. Could anyone help? I really appreciate any solution to this problem.
I run your code down to this point
mat = Normal[ca]
and look at the result.
There are lots of very tiny floating point coefficients, so small that I suspect most of them are just floating point noise now. Mathematica thinks 0.1 is only known to 1 significant digit of precision and your mat result is perhaps nothing more than zero correct digits now.
I continue down to this point
sha = Solve[Det[matt] == 0, s]
If you look at the value of sha you will see it is s->stuff and I don't think that is at all what you think it is. Mathematica returns "rules" from Solve, not just expressions.
If I change that line to
sha = s/.Solve[Det[matt] == 0, s]
then I am guessing that is closer to what you are imagining you want.
I continue to
shaa = Assuming[40<v<100 && .03<ro<1, Simplify[sha]];
reals = Re[shaa]
And I instead use, because you are assuming v and ro to be Real and because ComplexExpand has often been very helpful in getting Re to provide desired results,
reals=Re[ComplexExpand[shaa]]
and I click on Show ALL to see the full expanded value of that. That is about 32 large screens full of your expression.
In that are hundreds of
Arg[-1. + 50. ro]
and if I understand your intention I believe all those simplify to 0. If that is correct then
reals=reals/.Arg[-1. + 50. ro]->0
reduces the size of reals down to about 20 large screen fulls.
But there are still hundreds of examples of Sqrt[(-1.+50. ro)^2] and ((-1.+50. ro)^2)^(1/4) making up your reals. Unfortunately I'm expecting your enormous expression is too large and will take too long for Simplify with assumptions to be able to be practically effective.
Perhaps additional replacements to coax it into dramatically simplifying your reals without making any mistakes about Real versus Complex, but you have to be extremely careful with such things because it is very common for users to make mistakes when dealing with complex numbers and roots and powers and functions and end up with an incorrect result, might get your problem down to the point where it might be feasible for
Solve[reals == 0, ro]
to give you a meaningful answer.
This should give you some ideas of what you need to think carefully about and work on.
Related
I am trying to numerically solve the Klein-Gordon equation that can be found here. To make sure I solved it correctly, I am comparing it with an analytical solution that can be found on the same link. I am using the finite difference method and Matlab. The initial spatial conditions are known, not the initial time conditions.
I start off by initializing the constants and the space-time coordinate system:
close all
clear
clc
%% Constant parameters
A = 2;
B = 3;
lambda = 2;
mu = 3;
a = 4;
b = - (lambda^2 / a^2) + mu^2;
%% Coordinate system
number_of_discrete_time_steps = 300;
t = linspace(0, 2, number_of_discrete_time_steps);
dt = t(2) - t(1);
number_of_discrete_space_steps = 100;
x = transpose( linspace(0, 1, number_of_discrete_space_steps) );
dx = x(2) - x(1);
Next, I define and plot the analitical solution:
%% Analitical solution
Wa = cos(lambda * x) * ( A * cos(mu * t) + B * sin(mu * t) );
figure('Name', 'Analitical solution');
surface(t, x, Wa, 'edgecolor', 'none');
colormap(jet(256));
colorbar;
xlabel('t');
ylabel('x');
title('Wa(x, t) - analitical solution');
The plot of the analytical solution is shown here.
In the end, I define the initial spatial conditions, execute the finite difference method algorithm and plot the solution:
%% Numerical solution
Wn = zeros(number_of_discrete_space_steps, number_of_discrete_time_steps);
Wn(1, :) = Wa(1, :);
Wn(2, :) = Wa(2, :);
for j = 2 : (number_of_discrete_time_steps - 1)
for i = 2 : (number_of_discrete_space_steps - 1)
Wn(i + 1, j) = dx^2 / a^2 ...
* ( ( Wn(i, j + 1) - 2 * Wn(i, j) + Wn(i, j - 1) ) / dt^2 + b * Wn(i - 1, j - 1) ) ...
+ 2 * Wn(i, j) - Wn(i - 1, j);
end
end
figure('Name', 'Numerical solution');
surface(t, x, Wn, 'edgecolor', 'none');
colormap(jet(256));
colorbar;
xlabel('t');
ylabel('x');
title('Wn(x, t) - numerical solution');
The plot of the numerical solution is shown here.
The two plotted graphs are not the same, which is proof that I did something wrong in the algorithm. The problem is, I can't find the errors. Please help me find them.
To summarize, please help me change the code so that the two plotted graphs become approximately the same. Thank you for your time.
The finite difference discretization of w_tt = a^2 * w_xx - b*w is
( w(i,j+1) - 2*w(i,j) + w(i,j-1) ) / dt^2
= a^2 * ( w(i+1,j) - 2*w(i,j) + w(i-1,j) ) / dx^2 - b*w(i,j)
In your order this gives the recursion equation
w(i,j+1) = dt^2 * ( (a/dx)^2 * ( w(i+1,j) - 2*w(i,j) + w(i-1,j) ) - b*w(i,j) )
+2*w(i,j) - w(i,j-1)
The stability condition is that at least a*dt/dx < 1. For the present parameters this is not satisfied, they give this ratio as 2.6. Increasing the time discretization to 1000 points is sufficient.
Next up is the boundary conditions. Besides the two leading columns for times 0 and dt one also needs to set the values at the boundaries for x=0 and x=1. Copy also them from the exact solution.
Wn(:,1:2) = Wa(:,1:2);
Wn(1,:)=Wa(1,:);
Wn(end,:)=Wa(end,:);
Then also correct the definition (and use) of b to that in the source
b = - (lambda^2 * a^2) + mu^2;
and the resulting numerical image looks identical to the analytical image in the color plot. The difference plot confirms the closeness
Can I simply ask the logical flow of the below Mathematica code? What are the variables arg and abs doing? I have been searching for answers online and used ToMatlab but still cannot get the answer. Thank you.
Code:
PositiveCubicRoot[p_, q_, r_] :=
Module[{po3 = p/3, a, b, det, abs, arg},
b = ( po3^3 - po3 q/2 + r/2);
a = (-po3^2 + q/3);
det = a^3 + b^2;
If[det >= 0,
det = Power[Sqrt[det] - b, 1/3];
-po3 - a/det + det
,
(* evaluate real part, imaginary parts cancel anyway *)
abs = Sqrt[-a^3];
arg = ArcCos[-b/abs];
abs = Power[abs, 1/3];
abs = (abs - a/abs);
arg = -po3 + abs*Cos[arg/3]
]
]
abs and arg are being reused multiple times in the algorithm.
In a case where det > 0 the steps are
po3 = p/3;
b = (po3^3 - po3 q/2 + r/2);
a = (-po3^2 + q/3);
abs1 = Sqrt[-a^3];
arg1 = ArcCos[-b/abs1];
abs2 = Power[abs1, 1/3];
abs3 = (abs2 - a/abs2);
arg2 = -po3 + abs3*Cos[arg1/3]
abs3 can be identified as A in this answer: Using trig identity to a solve cubic equation
That is the most salient point of this answer.
Evaluating symbolically and numerically may provide some other insights.
Using demo inputs
{p, q, r} = {-2.52111798, -71.424692, -129.51520};
Copyable version of trig identity notes - NB a, b, p & q are used differently in this post
Plot[x^3 - 2.52111798 x^2 - 71.424692 x - 129.51520, {x, 0, 15}]
a = 1;
b = -2.52111798;
c = -71.424692;
d = -129.51520;
p = (3 a c - b^2)/3 a^2;
q = (2 b^3 - 9 a b c + 27 a^2 d)/27 a^3;
A = 2 Sqrt[-p/3]
A == abs3
-(b/3) + A Cos[1/3 ArcCos[
-((b/3)^3 - (b/3) c/2 + d/2)/Sqrt[-(-(b^2/9) + c/3)^3]]]
Edit
There is also a solution shown here
TRIGONOMETRIC SOLUTION TO THE CUBIC EQUATION, by Alvaro H. Salas
Clear[a, b, c]
1/3 (-a + 2 Sqrt[a^2 - 3 b] Cos[1/3 ArcCos[
(-2 a^3 + 9 a b - 27 c)/(2 (a^2 - 3 b)^(3/2))]]) /.
{a -> -2.52111798, b -> -71.424692, c -> -129.51520}
10.499
Here I'll use the notation
It is possible to find the continued fraction of a number by computing it then applying the definition, but that requires at least O(n) bits of memory to find a0, a1 ... an, in practice it is a much worse. Using double floating point precision it is only possible to find a0, a1 ... a19.
An alternative is to use the fact that if a,b,c are rational numbers then there exist unique rationals p,q,r such that 1/(a+b*21/3+c*22/3) = x+y*21/3+z*22/3, namely
So if I represent x,y, and z to absolute precision using the boost rational lib I can obtain floor(x + y*21/3+z*22/3) accurately only using double precision for 21/3 and 22/3 because I only need it to be within 1/2 of the true value. Unfortunately the numerators and denominators of x,y, and z grow considerably fast, and if you use regular floats instead the errors pile up quickly.
This way I was able to compute a0, a1 ... a10000 in under an hour, but somehow mathematica can do that in 2 seconds. Here's my code for reference
#include <iostream>
#include <boost/multiprecision/cpp_int.hpp>
namespace mp = boost::multiprecision;
int main()
{
const double t_1 = 1.259921049894873164767210607278228350570251;
const double t_2 = 1.587401051968199474751705639272308260391493;
mp::cpp_rational p = 0;
mp::cpp_rational q = 1;
mp::cpp_rational r = 0;
for(unsigned int i = 1; i != 10001; ++i) {
double p_f = static_cast<double>(p);
double q_f = static_cast<double>(q);
double r_f = static_cast<double>(r);
uint64_t floor = p_f + t_1 * q_f + t_2 * r_f;
std::cout << floor << ", ";
p -= floor;
//std::cout << floor << " " << p << " " << q << " " << r << std::endl;
mp::cpp_rational den = (p * p * p + 2 * q * q * q +
4 * r * r * r - 6 * p * q * r);
mp::cpp_rational a = (p * p - 2 * q * r) / den;
mp::cpp_rational b = (2 * r * r - p * q) / den;
mp::cpp_rational c = (q * q - p * r) / den;
p = a;
q = b;
r = c;
}
return 0;
}
The Lagrange algorithm
The algorithm is described for example in Knuth's book The Art of Computer Programming, vol 2 (Ex 13 in section 4.5.3 Analysis of Euclid's Algorithm, p. 375 in 3rd edition).
Let f be a polynomial of integer coefficients whose only real root is an irrational number x0 > 1. Then the Lagrange algorithm calculates the consecutive quotients of the continued fraction of x0.
I implemented it in python
def cf(a, N=10):
"""
a : list - coefficients of the polynomial,
i.e. f(x) = a[0] + a[1]*x + ... + a[n]*x^n
N : number of quotients to output
"""
# Degree of the polynomial
n = len(a) - 1
# List of consecutive quotients
ans = []
def shift_poly():
"""
Replaces plynomial f(x) with f(x+1) (shifts its graph to the left).
"""
for k in range(n):
for j in range(n - 1, k - 1, -1):
a[j] += a[j+1]
for _ in range(N):
quotient = 1
shift_poly()
# While the root is >1 shift it left
while sum(a) < 0:
quotient += 1
shift_poly()
# Otherwise, we have the next quotient
ans.append(quotient)
# Replace polynomial f(x) with -x^n * f(1/x)
a.reverse()
a = [-x for x in a]
return ans
It takes about 1s on my computer to run cf([-2, 0, 0, 1], 10000). (The coefficients correspond to the polynomial x^3 - 2 whose only real root is 2^(1/3).) The output agrees with the one from Wolfram Alpha.
Caveat
The coefficients of the polynomials evaluated inside the function quickly become quite large integers. So this approach needs some bigint implementation in other languages (Pure python3 deals with it, but for example numpy doesn't.)
You might have more luck computing 2^(1/3) to high accuracy and then trying to derive the continued fraction from that, using interval arithmetic to determine if the accuracy is sufficient.
Here's my stab at this in Python, using Halley iteration to compute 2^(1/3) in fixed point. The dead code is an attempt to compute fixed-point reciprocals more efficiently than Python via Newton iteration -- no dice.
Timing from my machine is about thirty seconds, spent mostly trying to extract the continued fraction from the fixed point representation.
prec = 40000
a = 1 << (3 * prec + 1)
two_a = a << 1
x = 5 << (prec - 2)
while True:
x_cubed = x * x * x
two_x_cubed = x_cubed << 1
x_prime = x * (x_cubed + two_a) // (two_x_cubed + a)
if -1 <= x_prime - x <= 1: break
x = x_prime
cf = []
four_to_the_prec = 1 << (2 * prec)
for i in range(10000):
q = x >> prec
r = x - (q << prec)
cf.append(q)
if True:
x = four_to_the_prec // r
else:
x = 1 << (2 * prec - r.bit_length())
while True:
delta_x = (x * ((four_to_the_prec - r * x) >> prec)) >> prec
if not delta_x: break
x += delta_x
print(cf)
In a programming contest, a problem was:
Count all solutions to the equation: x + 4y + 4z = n. You will be
given n and you will determine the count of solutions. Assume x, y and z are positive integers.
I have considered using triple for loops (brute force), but it was unefficient, causing TIME LIMIT EXCEED. (since the n may be = 1000,000):
int sol = 0;
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= n / 4; j++)
{
for (int k = 1; k <= n / 4; k++)
{
if (i + 4 * j + 4 * k == n)
sol++;
}
}
}
My friend could solve the problem. When I asked him, he said that he didn't use brute force at all. Instead, he converted the equation to a 'series' (i.e. summition). I asked him to tell how me but he refused :)
Can I know how?
This is particular case of coin change problem, which is solved in general by dynamic programming.
But here we can elaborate simple solution. I consider x,y,z > 0
x + 4*(y+z)=n
Let y + z = q = p + 1 (q > 1, p > 0)
x+4*q=n
x+4*p=n-4
There are M = Floor((n-5)/4) variants for x and p, hence there are M possible values of
q = 2..M+1
For every q>1 there are (q-1) variants of y and z: q = 1 + (q-1) = 2 + (q-2) +..+(q-1)+1
So we have N=1 + 2 + 3 + ... + M = M * (M + 1)/2 solutions
Example:
n = 15;
M = (15 - 5) div 4 = 2
N = 3
(3,1,2),(3,2,1),(7,1,1)
First note that n-x must be divisible by 4. Start by finding the smallest value that x can take:
start = 4
while ((n - start) % 4 != 0)
{
start = start + 1
}
From now on, you know that x will take values from [start, start+4, start+8 ...]. Now you can count the number of solutions by a simple counting loop:
count = 0
for (x = start; x < n - 4; x = x + 4)
{
y_z_sum = (n - x) / 4
count = count + y_z_sum - 1
}
For each choice of x, we can compute the value of y+z. For each value for y+z, there are y+z-1 possible choices (since y ranges from 1 to y+z-1, assuming that y and z are both positive integers).
Instead of a brute force solution with O(n3) running time, you can achieve O(n) this way.
This is a classic linear algebra problem. Please refer to any linear algebra textbook on how to solve a system of linear equations. One such method is called Gaussian Elimination.
A lot of people at Facebook like to play Starcraft II™. Some of them have made a custom game using the Starcraft II™ map editor. In this game, you play as the noble Protoss defending your adopted homeworld of Shakuras from a massive Zerg army. You must do as much damage to the Zerg as possible before getting overwhelmed. You can only build two types of units, shield generators and warriors. Shield generators do no damage, but your army survives for one second per shield generator that you build. Warriors do one damage every second. Your army is instantly overrun after your shield generators expire. How many shield generators and how many warriors should you build to inflict the maximum amount of damage on the Zerg before your army is overrun? Because the Protoss value bravery, if there is more than one solution you should return the one that uses the most warriors.
Constraints
1 ≤ G (cost for one shield generator) ≤ 100
1 ≤ W (cost for one warrior) ≤ 100
G + W ≤ M (available funds) ≤ 1000000000000 (1012)
Here's a solution whose complexity is O(W). Let g be the number of generators we build, and similarly let w be the number of warriors we build (and G, W be the corresponding prices per unit).
We note that we want to maximize w*g subject to w*W + g*G <= M.
First, we'll get rid of one of the variables. Note that if we choose a value for g, then obviously we should buy as many warriors as possible with the remaining amount of money M - g*G. In other words, w = floor((M-g*G)/W).
Now, the problem is to maximize g*floor((M-g*G)/W) subject to 0 <= g <= floor(M/G). We want to get rid of the floor, so let's consider W distinct cases. Let's write g = W*k + r, where 0 <= r < W is the remainder when dividing g by W.
The idea is now to fix r, and insert the expression for g and then let k be the variable in the equation. We'll get the following quadratic equation in k:
Let p = floor((M - r*G)/W), then the equation is (-GW) * k^2 + (Wp - rG)k + rp.
This is a quadratic equation which goes to negative infinity when x goes to infinity or negative infinity so it has a global maximum at k = -B/(2A). To find the maximum value for legal values of k, we'll try the minimum legal value of k, the maximum legal value of k and the two nearest integer points of the real maximum if they are within the legal range.
The overall maximum for all values of r is the one we are seeking. Since there are W values for r, and it takes O(1) to compute the maximum for a fixed value, the overall time is O(W).
If you build g generators, and w warriors, you can do a total damage of
w (damage per time) × g (time until game-over).
The funds constraint restricts the value of g and w to W × w + G × g ≤ M.
If you build g generators, you can build at most (M - g × G)/W warriors, and do g × (M - g × G)/W damage.
This function has a maximum at g = M / (2 G), which results in M2 / (4 G W) damage.
Summary:
Build M / (2 G) shield generators.
Build M / (2 G) warriors.
Do M2 / (4 G W) damage.
Since you can only build integer amounts of any of the two units, this reduces to the optimization problem:
maximize g × w
with respect to g × G + w × W ≤ M and g, w ∈ ℤ+
The general problem of Integer Programming is NP-complete, so the best algorithm for this is to check all integer values close to the real-valued solution above.
If you find some pair (gi, wi), with total damage di, you only have to check values where gj × wj ≥ di. This and the original condition W × w + G × g ≤ M constrains the search-space with each item found.
F#-code:
let findBestSetup (G : int) (W : int) (M : int) =
let mutable bestG = int (float M / (2.0 * float G))
let mutable bestW = int (float M / (2.0 * float W))
let mutable bestScore = bestG * bestW
let maxW = (M + isqrt (M*M - 4 * bestScore * G * W)) / (2*G)
let minW = (M - isqrt (M*M - 4 * bestScore * G * W)) / (2*G)
for w = minW to maxW do
// ceiling of (bestScore / w)
let minG = (bestScore + w - 1) / w
let maxG = (M - W*w)/G
for g = minG to maxG do
let score = g * w
if score > bestScore || score = bestScore && w > bestW then
bestG <- g
bestW <- w
bestScore <- score
bestG, bestW, bestScore
This assumed W and G were the counts and the cost of each was equal to 1. So it's obsolete with the updated question.
Damage = LifeTime*DamagePerSecond = W * G
So you need to maximize W*G with the constraint G+W <= M. Since both Generators and Warriors are always good we can use G+W = M.
Thus the function we want to maximize becomes W*(M-W).
Now we set the derivative = 0:
M-2W=0
W = M/2
But since we need the solution to the discrete case(You can't have x.5 warriors and x.5 generators) we use the values closest to the continuous solution(this is optimal due to the properties of a parabel).
If M is even than the continuous solution is identical to the discrete solution. If M is odd then we have two closest solutions, one with one warrior more than generators, and one the other way round. And the OP said we should choose more warriors.
So the final solution is:
G = W = M/2 for even M
and G+1 = W = (M+1)/2 for odd M.
g = total generators
gc = generator cost
w = warriors
wc = warrior cost
m = money
d = total damage
g = (m - (w*wc))/gc
w = (m - (g*gc))/wc
d = g * w
d = ((m - (w*wc))/gc) * ((m - (g*gc))/wc)
d = ((m - (w*wc))/gc) * ((m - (((m - (w*wc))/gc)*gc))/wc) damage as a function of warriors
I then tried to compute an array of all damages then find max but of course it'd not complete in 6 mins with m in the trillions.
To find the max you'd have to differentiate that equation and find when it equals zero, which I forgotten how to do seing I haven't done math in about 6 years
Not a really a solution but here goes.
The assumption is that you already get a high value of damage when the number of shields equals 1 (cannot equal zero or no damage will be done) and the number of warriors equals (m-g)/w. Iterating up should (again an assumption) reach the point of compromise between the number of shields and warriors where damage is maximized. This is handled by the bestDamage > calc branch.
There is almost likely a flaw in this reasoning and it'd be preferable to understand the maths behind the problem. As I haven't practised mathematics for a while I'll just guess that this requires deriving a function.
long bestDamage = 0;
long numShields = 0;
long numWarriors = 0;
for( int k = 1;; k++ ){
// Should move declaration outside of loop
long calc = m / ( k * g ); // k = number of shields
if( bestDamage < calc ) {
bestDamage = calc;
}
if( bestDamage > calc ) {
numShields = k;
numWarriors = (m - (numShields*g))/w;
break;
}
}
System.out.println( "numShields:" + numShields );
System.out.println( "numWarriors:" + numWarriors );
System.out.println( bestDamage );
Since I solved this last night, I thought I'd post my C++ solution. The algorithm starts with an initial guess, located at the global maximum of the continuous case. Then it searches 'little' to the left/right of the initial guess, terminating early when continuous case dips below an already established maximum. Interestingly, the 5 example answers posted by the FB contained 3 wrong answers:
Case #1
ours: 21964379805 dmg: 723650970382348706550
theirs: 21964393379 dmg: 723650970382072360271 Wrong
Case #2
ours: 1652611083 dmg: 6790901372732348715
theirs: 1652611083 dmg: 6790901372732348715
Case #3
ours: 12472139015 dmg: 60666158566094902765
theirs: 12472102915 dmg: 60666158565585381950 Wrong
Case #4
ours: 6386438607 dmg: 10998633262062635721
theirs: 6386403897 dmg: 10998633261737360511 Wrong
Case #5
ours: 1991050385 dmg: 15857126540443542515
theirs: 1991050385 dmg: 15857126540443542515
Finally the code (it uses libgmpxx for large numbers). I doubt the code is optimal, but it does complete in 0.280ms on my personal computer for the example input given by FB....
#include <iostream>
#include <gmpxx.h>
using namespace std;
typedef mpz_class Integer;
typedef mpf_class Real;
static Integer getDamage( Integer g, Integer G, Integer W, Integer M)
{
Integer w = (M - g * G) / W;
return g * w;
}
static Integer optimize( Integer G, Integer W, Integer M)
{
Integer initialNg = M / ( 2 * G);
Integer bestNg = initialNg;
Integer bestDamage = getDamage ( initialNg, G, W, M);
// search left
for( Integer gg = initialNg - 1 ; ; gg -- ) {
Real bestTheoreticalDamage = gg * (M - gg * G) / (Real(W));
if( bestTheoreticalDamage < bestDamage) break;
Integer dd = getDamage ( gg, G, W, M);
if( dd >= bestDamage) {
bestDamage = dd;
bestNg = gg;
}
}
// search right
for( Integer gg = initialNg + 1 ; ; gg ++ ) {
Real bestTheoreticalDamage = gg * (M - gg * G) / (Real(W));
if( bestTheoreticalDamage < bestDamage) break;
Integer dd = getDamage ( gg, G, W, M);
if( dd > bestDamage) {
bestDamage = dd;
bestNg = gg;
}
}
return bestNg;
}
int main( int, char **)
{
Integer N;
cin >> N;
for( int i = 0 ; i < N ; i ++ ) {
cout << "Case #" << i << "\n";
Integer G, W, M, FB;
cin >> G >> W >> M >> FB;
Integer g = optimize( G, W, M);
Integer ourDamage = getDamage( g, G, W, M);
Integer fbDamage = getDamage( FB, G, W, M);
cout << " ours: " << g << " dmg: " << ourDamage << "\n"
<< " theirs: " << FB << " dmg: " << fbDamage << " "
<< (ourDamage > fbDamage ? "Wrong" : "") << "\n";
}
}