| We return to our old friend the
triangle again this month. The area and perimeter of a given triangle
are equal, numerically speaking. The dimensions of all the sides and
the area are integers, and the perimeter is less than 100 cm. The
longest side is less than twice the length of the second longest side.
What are the lengths of the sides? It doesn't say that we're dealing with a right triangle here, and in fact a little analysis shows it can't be. The longest side in a right-angled triangle will be the hypotenuse, and this is double one of the other sides. Call this other side x. Then, by Pythagorus, the third side must be the square root of (x2 + (2x)2) which equals the square root of 5x2. This, in turn, is x times the square root of 5. So the third side can't be an integer, as specified. Therefore the triangle isn't a right-angled triangle. So the area will be easiest to find using Hero's formula. If you cast your mind back to your school-days, you'll recall it's: ![]() where s = half the perimeter, and the 3 sides are denoted by a, b, and c. In the program listing below, I've called the perimeter peri and the half-perimeter is denoted halfPeri. Variables a, b, and c are replaced by short, med, and long. For convenience, the self-explanatory variable names area and areaSquared are employed. Let's begin by working out what possible search ranges we could use in the light of the limited information we have about the lengths of the sides. long
= 2*med - 1 (maximum)
and short = med - 1 (maximum) but short + med + long = 99 (maximum) Therefore med - 1 + med + 2*med - 1 = 99 (maximum) Therefore 4*med = 101 (maximum) Therefore med = 25 (maximum) Therefore short = med - 1 = 24 (maximum) This gives the ranges: short
= 1 to 24
med = (short + 1) to 25 long = (med + 1) to (2*med - 1) Using this and Hero's formula, we can now write some code to do the work for us: |
| ' Puzzlet #093 ' A triangle's area and perimeter are ' numerically the same. The area and ' the sides are all integers, and the ' perimeter is less than 100 cm. The ' longest side is less than twice the ' length of the second longest side. ' What are the lengths of the sides? ' By Dave Ellis. declare PrintHeader() declare HerosRule() declare PrintResult() def short, med, long: int: 'sides def peri: int: 'perimiters def areaSquared: int def area, halfPeri: float openconsole print "Searching ...": print for short = 1 to 24 for med = short + 1 to 25 for long = med + 1 to 2*med - 1 peri = short + med + long halfPeri = peri/2 areaSquared = HerosRule() if areaSquared > 0 area = sqrt(areaSquared) if peri = area PrintResult() endif endif next long next med next short print: print "No more!" print: print "Press a key to exit ... ", do: until inkey$ <> "" closeconsole end sub PrintHeader ' pretty printer print " Sides" print "Small Med Long" return sub HerosRule ' returns the square of the area, ' found by applying Hero's Rule. def value: float def sMinusA, sMinusB, sMinusC: float sMinusA = halfPeri - short sMinusB = halfPeri - med sMinusC = halfPeri - long value = halfPeri * sMinusA * sMinusB * sMinusC return value sub PrintResult ' pretty printer print using ("### ", short), print using ("####", med), print using ("######", long) return |
| PROGRAM NOTES The usual top-down approach is applied to this program. The main routine tells you everything you need to know. In the following extract, the lines are numbered to make it easier to follow the description. |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
for short = 1 to 24 for med = short + 1 to 25 for long = med + 1 to 2*med - 1 peri = short + med + long halfPeri = peri/2 areaSquared = HerosRule() if areaSquared > 0 area = sqrt(areaSquared) if peri = area PrintResult() endif endif next long next med next short |
| Now for an exegesis of the code using the above line numbers: |
| 1 |
for short = 1 to 24. Opens
the main FOR-NEXT loop, using variable short as iterator. Note that the
range used, 1 to 24, is as discussed in the introductory notes. |
| 2 |
for med = short + 1 to 25. Opens the first nested FOR-NEXT loop, using variable med over the range short + 1 to 25. |
| 3 |
for long = med + 1 to 2*med - 1. Opens the second nested FOR-NEXT loop, using variable long over the range med + 1 to 2*med - 1. |
| 4 |
peri = short + med + long. Calculates perimeter peri using the current values established for short, med and long in lines 1 to 3 above. |
| 5 |
halfPeri =
peri/2. Calculates the half-permiter from peri/2,
storing the result in variable halfPeri. |
| 6 |
areaSquared = HerosRule(). Line six applies the above-established global variable values in the function HerosRule() and saves the result in variable areaSquared. Note that the final step in Hero's formula, the square root, hasn't been applied yet. |
| 7 |
if areaSquared > 0. The reason we didn't take that square root in Line 6 is that there was a possibility it could be a negative, which would cause a crash. This line checks for that possibility, and only continues with the current values if it's safe to do so. |
| 8 |
area = sqrt(areaSquared). Now that it's safe to go on, the area is finally calculated. |
| 9 |
if peri = area. We're now in a position to compare area and peri numerically. If they're the same, we have a solution. |
| 10 |
PrintResult(). Subroutine PrintResult() is invoked to print the results to the computer screen. |
| 11 |
endif. Housekeeping, closing the END-IF clause opened in line 9. |
| 12 |
endif. Housekeeping, closing the END-IF clause opened in line 7. |
| 13 |
next long. Housekeeping, completes the FOR-NEXT clause opened in line 3. |
| 14 |
next med. Housekeeping, completes the FOR-NEXT clause opened in line 2. |
| 15 |
next short. Housekeeping, completes the FOR-NEXT clause opened in line 1. |
| When
you run the program, you'll see the inset printed out onto your
computer's screen. Thus, there are five solutions altogether. Note that only the first two solutions are actually using right-angled triangles - but the problem never specified what type of triangle to work with anyway! |
Searching
... 5 12 13 6 8 10 6 25 29 7 15 20 9 10 17 No more! Press a key ... |