' Puzzlet #047
' Five weights are available, 31, 28, 19, 42,
' and 20 kg. Using a total of 41 weights, make
' an overall weight of 1.279 tonnes (1279 kg).
' Use each weight at least five times.
' By Dave Ellis.
declare PrintResult()
def sum, w19, w20, w28, w31, w42: int
openconsole
print "Searching ...": print
print string$(18, "-")
print " Weights in kg": print
print "19 20 28 31 42"
print string$(18, "-"): print
w19 = 5
do
w20 = 5
do
w28 = 5
do
w31 = 5
do
w42 = 13
do
if w19 + w20 + w28 + w31 + w42 = 41
sum = 19*w19 + 20*w20 + 28*w28 + 31*w31 + 42*w42
if sum = 1279
PrintResult()
endif
sum = 0
endif
w42 = w42 + 1
until w42 > 18 | sum > 1279
w31 = w31 + 1
until w31 > 12 | sum > 1279
w28 = w28 + 1
until w28 > 13 | sum > 1279
w20 = w20 + 1
until w20 > 13 | sum > 1279
w19 = w19 + 1
until w19 > 13 | sum > 1279
print: print string$(18, "-")
print: print "No more!"
print: print "Press a key to exit ... ",
do: until inkey$ <> ""
closeconsole
end
sub PrintResult
' pretty printer
print using ("##", w19),
print using ("####", w20),
print using ("####", w28),
print using ("####", w31),
print using ("####", w42)
return
PROGRAM NOTES
One of the first things to do when designing this program is to think about the search range. Every weight has a lower search limit of five, since the problem specifies at least five of each weight must be used.
Let's think about the upper search limit for the 42 kg weight. The minimum combined weight must be 5(19+20+28+31+42), since the rules demand at least 5 of every weight, which comes to 700 kg. Now, 1279 - 700 = 579 kg. 579/42 = 13.8, so the maximum additional 42 kg weights is 13. Since we already have 5, the total maximum of 42 kg weights is 18.
What about a minimum? Try 7. From above, we have at most 41 - 25 is 16 weights left. If 7 of those are 42 kg weights, the weight total is 700 + 7*42 = 994 kg. 1279 - 994 = 285 kg to make up from the rest of the weights. However, we now only have 16 - 7 = 9 weights left. The next largest weight is 31 kg. 9 x 31 = 279, which doesn't make up the required 285 kg. So, we have to try 8 42 kg weights, and if you do the sums you'll find this works out ok.
Continuing in this vein, you can quickly construct a little table of maximum and minimum permissable numbers of weights:
Weight
19
20
28
31
42
Minimum
5
5
5
6
13
Maximum
13
13
13
12
18
When searching for these, it's important to nest loops with the smallest search range in the innermost loop, the next smallest search range in the next loop, etc. This minimises the total number of iterations necessary to complete the search.
The analysis and arrangement of the loops are all very worthwhile. I ran this program using a "brute force and ignorance" approach, and it took 28 times longer to complete! The version above completes in just a few seconds.
The program uses meaningful variable names such as w28 to indicate the number of 28kg weights, sum to hold the total weight of all the individual weights being investigated at any one time, and so on.
You may notice that, whenever sum is calculated (which only occurs if the inner loop is reached, which in turn only happens if there are exactly 41 weights being investigated), it is reset to zero immediately afterwards. This is to prevent unintentional exiting of outer loops using sum's value as an exit condition. Without this precaution the program will always leap straight out and stop after only a few iterations - as soon as sum is greater than 1279 for the first time.
When you run the code, it will produce the inset screen.
So, as you can see, there are in fact three answers, each one of which meet the specified conditions.
Searching ...
--------------------------
Weights in kg
19 20 28 31 42
--------------------------
6 5 10 5 15
7 5 6 8 15
7 6 6 6 16
--------------------------
No more!
Press a key ...ess a key ...
MAIN MENU
DOWNLOAD CODE
ARCHIVES
Site design/maintenance: Dave Ellis E-mail me!
Last Updated: February 22nd, 2004.