Without looking at your code, I first did some pencil and paper work.
Heron's formula for an isosceles triangle, with sides of {a,a,b}, would reduce as:
m = (a + a + b)/2 = a + b/2
A = sqrt(m*(m-a)*(m-a)*)(m-b))
but m-a is just b/2. And m-b is a-b/2. Substitute, and do some quick algebra...
A = sqrt(a^2 - b^2/4) * b/2
This may be a bit simpler to work with than the original formula. It does point out a restriction on a, that a>=b/2. Of course, that should be obvious, since an isosceles triangle MUST have that property.
Next, if you condition your search on the triangle perimeter, then we see another piece of information to reduce the search. If P is an odd integer, then so must be b. Likewise, if P is even, then b is also.
Better, is to look at it from the perspective of a. a must be an integer, at least as large as P/4, and no larger than P/2. (Think about it! Check my logic.) So for ANY given integer perimeter P, the possible side lengths are:
a = ceil(P/4):ceil(P/2 - 1);
b = P - 2*a;
It is always a good idea to test things out, just to be confident you have it right. In fact, I'll write a couple of tiny helper functions to compute a and b for any perimeter.
afun = @( P) ceil(P/4):ceil(P/2 - 1);
bfun = @( P) P - 2*afun( P);
First, try an even perimeter.
P = 12;
[afun( P);bfun( P)]
ans =
3 4 5
6 4 2
The first row of that array is a, the second row is b.
Now try an odd value for the perimeter.
P = 13;
[afun( P);bfun( P)]
ans =
4 5 6
5 3 1
Next, we require that the area is also an integer.
Areafun = @( P) sqrt(afun( P).^2 - bfun( P).^2/4) .* bfun( P)/2;
But can we do just a bit more before we go into actual numbers? We said before that if P is an odd number, then so must be b. What was the area again?
A = sqrt(a^2 - b^2/4) * b/2
If b is odd, then a^2-b^2/4 must ALWAYS be non-integer, and so must be the area. So we can conclude that to have an integer area, an integral sided isosceles triangle must always have an even perimeter.
So a simple code might just loop over the even integers, starting with P=4, searching for integer values of Areafun.
afun = @( P) ceil(P/4):ceil(P/2 - 1);
bfun = @( P) P - 2*afun( P);
Areafun = @( P) sqrt(afun( P).^2 - bfun( P).^2/4) .* bfun( P)/2;
for P = 4:2:100
A = Areafun( P);
ind = find((A == round(A)) & (A ~= 0));
if ~isempty(ind)
a = afun( P);
b = bfun( P);
disp('Solution(s) found')
P
[a(ind);b(ind);A(ind)]
end
end
Could we do even better? Perhaps by thinking more deeply about the problem, perhaps we might.
Best Answer