Teaser 3113: The plumber’s buckets
From The Sunday Times, 22nd May 2022 [link] [link]
A plumber was trying to empty a tank containing 100 litres of water using three buckets, each marked with a different whole number of litres capacity between 10 and 20 litres. He calculated that he could exactly empty the tank, but only by using all three buckets and completely filling each bucket a different number of times.
He filled and emptied each bucket the calculated number of times but the tank still contained 6 litres of water, because the smallest bucket had a dent that reduced its capacity by 3 litres.
What were the marked capacities of the three buckets?
The version of this puzzle that appears in the book The Sunday Times Teasers Book 2 (2023) is as follows (with modified sections underlined):
A plumber was trying to empty a tank containing 100 litres of water using three buckets, each marked with a different whole number of litres capacity between 10 and 20 litres. He calculated that he could exactly empty the tank, but only by using all three buckets.
He then emptied the tank as calculated, filling each bucket a different number of times, but then found the tank still contained 6 litres of water, because the smallest bucket had a dent that reduced its capacity by 3 litres.
What were the marked capacities of the three buckets?
This corresponds to my own re-wording of the puzzle given in the comments.
[teaser3113]

Jim Randell 4:51 pm on 20 May 2022 Permalink |
Perhaps I misread this puzzle, but I couldn’t find a solution that fits the text.
However, I did find a solution where the dent reduces the capacity of the largest bucket (not the smallest) by 3 litres. This is my preferred way to “rescue” the puzzle, as it is a minimal change to the text, and the dent would be less noticeable in the largest bucket. However, another way to rescue the puzzle (but with a different solution) is if the capacity of the smallest bucket is reduced by 2 litres (not 3 litres).
This Python program runs in 58ms.
from enigma import ( irange, subsets, express, seq_all_different as all_different, singleton, printf ) # choose the labelled capacities of the buckets for bs in subsets(irange(10, 20), size=3): # there is only one way to use the buckets qs = singleton(express(100, bs)) if qs is None: continue # each bucket is used if 0 in qs: continue # the number of uses are all different if not all_different(qs): continue # largest [was: smallest] bucket must be used twice if qs[-1] != 2: continue printf("bs={bs} qs={qs}")Solution: The puzzle, as originally worded, has no solution.
If we look for combinations of (correctly labelled) buckets that can be used (completely filling each bucket a number of times) to empty a 100 litre tank, such that all three buckets must be used, each of them a different number of times, we find there are 5 viable combinations (buckets × uses):
(And if we require there to be only a single way to use the buckets we can discard the (12, 17, 18) combination, leaving only 3 viable combinations).
The original text asked for a combination where the smallest bucket was used twice, but as we see there are no such combinations.
In my rescued version, where the largest bucket (not the smallest) has the dent, the solution is that the buckets are labelled (11, 18, 19) litres (although they are actually (11, 18, 16) litres).
The published solution was that the buckets are labelled (13, 17, 19) litres (although they are actually (10, 17, 19) litres). Which corresponds to my re-wording of the puzzle given below.
However we can use (correctly labelled) buckets (13, 17, 19) to empty the tank in the following ways:
So it is not true to say that it can “only [be done] by using all three buckets and completely filling each bucket a different number of times”. (The first line achieves the required result using two of the buckets the same number of times). Hence the requirement for rewording of the puzzle.
But if we suppose “the calculated number of times” requires that there is only one possible way to fill the buckets, then the reworded puzzle also has no solutions. (As there are 2 ways to use these (correctly labelled) buckets to empty the tank).
It is possible that the setter intended that when the plumber sat down to work out how many times to use the buckets, he only considers using each bucket a different number of times. He tried using just one bucket and found it was not possible, then he tried using combinations of two buckets and found none of those were possible, and finally he tried using all three buckets and found that there was a single way they could be used. And he then proceeded to use this calculated number of ways, but when he finished there was 6 litres remaining in the tank, because the smallest bucket’s capacity was reduced by 3 litres from the labelled capacity.
In this scenario, there are 9 candidate bucket combinations, and only one of them has the smallest bucket having 2 uses, so this gives a unique solution, and it is the published solution.
The published solution is: “13, 17 and 19 litres”.
LikeLike
Jim Randell 5:58 pm on 20 May 2022 Permalink |
This might be a stricter interpretation of the puzzle text, which finds a couple more candidate solutions. But still doesn’t find a solution that fits the text.
Instead I have coded it to find the same solution I found above.
There remains an issue as to whether “he filled and emptied each bucket the calculated number of times” is intended to imply that there is only a single way of filling the buckets (each a different non-zero number of times), or he chose one from multiple viable ways. Fortunately this does not change the answer to my “rescued” version of the puzzle.
This Python program runs in 56ms. (Internal run time is 1.5ms).
from enigma import (irange, subsets, express, seq_all_different as all_different, printf) # find viable ways to use the buckets def buckets(t, bs): rs = list() for qs in express(t, bs): # each bucket is used if 0 in qs: return [] # the numbers of uses are all different if not all_different(qs): return [] # is viable rs.append(qs) return rs # choose the labelled capacities of the buckets for bs in subsets(irange(10, 20), size=3): # find viable ways to use the buckets for qs in buckets(100, bs): # largest [was: smallest] bucket must be used twice if qs[-1] != 2: continue # output solution printf("bs={bs} qs={qs}")The interpretation of the puzzle text where there is just a single way to fill the buckets can be implemented at line 13 by only returning the list of candidates if it has a length of 1. But this doesn’t change the answer found.
LikeLike
Frits 5:59 pm on 20 May 2022 Permalink |
Correct, with SubstitutedExpression I end up with 3 options (the third solution would be if the capacity of the smallest bucket is reduced by 1.5 litres).
LikeLike
Jim Randell 8:26 am on 21 May 2022 Permalink |
It has been suggested to me that the intended interpretation of this puzzle is more like this (with {{ changed sections }} in double braces):
To solve this formulation of the puzzle we can take my program and just move the “different number of times” test (line 10 in the program above is moved to line 18 below):
Run: [ @replit ]
from enigma import (irange, subsets, express, seq_all_different as all_different, printf) # find viable ways to use the buckets def buckets(t, bs): rs = list() for qs in express(t, bs): # each bucket is used if 0 in qs: return [] # is viable rs.append(qs) return rs # choose the labelled capacities of the buckets for bs in subsets(irange(10, 20), size=3): # find viable ways to use the buckets for qs in buckets(100, bs): # the numbers of uses are all different if not all_different(qs): continue # smallest bucket must be used twice if qs[0] != 2: continue # output solution printf("bs={bs} qs={qs}")LikeLike
Mark Valentine 12:00 pm on 22 May 2022 Permalink |
I think the text is absolutely fine. Clearly you need three different bucket sizes, where no two (or one) of which can combine to make exactly 100. Then from these triples you apply the condition for the smallest bucket size.
LikeLike
Jim Randell 12:27 pm on 22 May 2022 Permalink |
@Mark: You also need to check that the numbers of uses of each bucket are all different. And where this requirement is placed in the puzzle text makes a difference.
The original puzzle text has no solutions. My revised text does have a unique solution. (And it seems that this revised text corresponds to the intended puzzle).
LikeLike
Mark Valentine 9:00 pm on 22 May 2022 Permalink |
Ok to be fair I didn’t check for uniqueness . Just stopped at a solution. so will defer.
LikeLike
Hugh+Casement 9:47 am on 21 May 2022 Permalink |
I don’t see that changing the passages in double braces makes any difference!
Does the clue lie in “but only by using all three buckets” ?
That is to say, no (different) integer multiples of any two undented buckets would sum to 100 litres.
LikeLike
Jim Randell 10:03 am on 21 May 2022 Permalink |
There is a subtle difference between “but only using all three buckets” and “but only using all three buckets, each a different number of times” that stops the puzzle from working in the originally published formulation.
The “using all three buckets” requirement means we can’t use buckets with capacity 10 or 20, as then we could exactly empty the tank using just one of them. Similarly if a collection of buckets includes a pair that can be used to exactly empty the tank then that is also disallowed.
LikeLike
Hugh+Casement 12:23 pm on 21 May 2022 Permalink |
Yes, but he used the buckets the calculated number of times.
LikeLike
J Slusar 6:55 pm on 21 May 2022 Permalink |
But what is wrong with buckets marked 13, 14 and 15 filling the smallest twice, the middle one once and the larger one 4 times? The total would have been 100, but the reduced capacity of the smaller bucket would mean 6 litres remained in the tank?
LikeLike
Jim Randell 10:01 pm on 21 May 2022 Permalink |
Thanks for the comment.
I think this combination is ruled out by the requirement that “he could exactly empty the tank, but only by using all three buckets and completely filling each bucket a different number of times”.
With (13, 14, 15) there are three ways we can make 100:
The first of these means that you don’t have to use all three buckets, and the second means that you don’t have to use each bucket a different number of times. So the requirement is not met.
LikeLike
bencooperjamin 1:46 am on 23 May 2022 Permalink |
Doesnt work because 5*14 +2*15=100 ie the tank can be emptied with only 2 of the buckets.
LikeLike
GeoffR 12:34 pm on 23 May 2022 Permalink |
I finally managed to find a program solution, which agrees with Jim’s last posting i.e 3rd posting (21 May 2022).
% A Solution in MiniZinc include "globals.mzn"; int: Tank == 100; % litres % Three buckets - capacity ranges in litres var 10..20:B1; var 10..20:B2; var 10..20:B3; % Three different size buckets are required constraint B1 < B2 /\ B2 < B3; % No of times buckets B1, B2 and B3 are emptied var 1..10:n1; var 1..10:n2; var 1..10:n3; constraint all_different([n1, n2, n3]); % Smallest bucket B1 must be emptied twice due to a 3L dent constraint n1 == 2; % Tank emptying constraints for one and two buckets % Tank cannot be emptied with any single bucket constraint forall(i in 1..10) ( Tank mod (B1 * i) != 0 ); constraint forall(i in 1..10) ( Tank mod (B2 * i) != 0 ); constraint forall(i in 1..10) ( Tank mod (B3 * i) != 0 ); % Buckets B1 and B2 cannot empty tank on their own constraint forall(i in 1..10, j in 1..10) ( Tank mod (i * B1 + j * B2) != 0); % Buckets B1 and B3 cannot empty tank on their own constraint forall(i in 1..10, j in 1..10) ( Tank mod (i * B1 + j * B3) != 0); % Buckets B2 and B3 cannot empty tank on their own constraint forall(i in 1..10, j in 1..10) ( Tank mod (i * B2 + j * B3) != 0); % Empty the tank with three buckets B1, B2 and B3 constraint Tank mod (n1 * B1 + n2 * B2 + n3 * B3) == 0; solve satisfy; output [" Capacities of three buckets (B1, B2, B3) = " ++ show([B1, B2, B3 ] ) ++ "\n" ++ " No of times each bucket emptied (n1, n2, n3) = " ++ show([n1, n2, n3 ]) ];LikeLike
Frits 10:39 am on 25 May 2022 Permalink |
To simplify restraints you can use:
LikeLike