Teaser 2455: [Mixing jugs]
From The Sunday Times, 11th October 2009 [link]
I had a red jug, a white one and a blue one, containing kiwi, lime and mango juice, not necessarily in that order. Each [initially contained] a whole number of millilitres, totalling less than a litre. I poured juice from the red jug to the white and stirred the contents. I poured some from the white to the blue, some from the blue to the white, and some from the white to the red. Each time I doubled the contents of the jug into which the juice was poured. I ended with equal quantities in each jug and, in one jug, 45 ml more lime juice than mango.
At the end, how much of each juice was in the red jug?
This puzzle was originally published with no title.
[teaser2455]
Jim Randell 9:10 am on 24 February 2026 Permalink |
At the end of the series of transfers we end up with the same quantity in each jug.
So we can call that quantity 1 unit and we have:
Each transfer doubles the amount in the receiving jug, so before the transfer the red jug must have contained only 1/2 unit, and the white just must have contained 3/2 units:
We can then move on to transfer 3 (blue → white), and we get:
And transfer 2:
And finally, transfer 1:
And so we find the relative quantities initially in the jugs are: 21 : 13 : 14.
We can then look for integer multiples of these values to give us the starting quantities in the jugs (total volume is less than 1000 ml), such that after the final transfer one of the jugs has a mix with 45 ml more lime than mango.
The following Python program starts from the sequence of transfers, and performs the steps outlined above.
It runs in 73ms. (Internal runtime is 2.7ms).
from enigma import (irange, inf, rdiv, update, rev, ratio_q, subsets, seq2str, printf) # indices for red, white blue (R, W, B) = (0, 1, 2) # sequences of transfers xfers = [(R, W), (W, B), (B, W), (W, R)] # working backwards from the end # we start with a volume of 1 in each jug, and then make the reverse transfers jugs = [1, 1, 1] for (s, t) in rev(xfers): # volume moved = half the volume of the target jug v = rdiv(jugs[t], 2) # update the jugs jugs = update(jugs, [(s, jugs[s] + v), (t, jugs[t] - v)]) # jugs now has the relative quantities in the three jugs at the start (r, w, b) = ratio_q(*jugs) T = r + w + b printf("initial volume ratio = {jugs} -> {r} : {w} : {b}", jugs=seq2str(jugs)) # calculate vector sum: <a[i] + k.b[i]> vec_add = lambda xs, ys, k: list(x + y * k for (x, y) in zip(xs, ys)) # start with the initial quantities in the R, W, B jugs jugs = [[r, 0, 0], [0, w, 0], [0, 0, b]] # perform the transfers for (s, t) in xfers: # volume to move = total volume in target jug vt = sum(jugs[t]) # total volume in the source jug vs = sum(jugs[s]) # calculate quantities of each flavour to move qs = list(rdiv(vt * v, vs) for v in jugs[s]) # update the jugs jugs = update(jugs, [(s, vec_add(jugs[s], qs, -1)), (t, vec_add(jugs[t], qs, +1))]) printf("final volume ratio = {jugs}") # now look for a multiple that gives a total less than 1000 ml for k in irange(1, inf): if not (T * k < 1000): break # multiply up the final quantities jugs4 = list(list(k * v for v in vs) for vs in jugs) # assign indices to flavours for (lime, kiwi, mango) in subsets([0, 1, 2], size=len, select='P'): # one of the jugs has 45 ml more lime than mango if not any(vs[lime] == vs[mango] + 45 for vs in jugs4): continue # output solution d = { lime: "lime", kiwi: "kiwi", mango: "mango" } printf() printf("lime = {lime}, kiwi = {kiwi}, mango = {mango}") printf("initial: R={R} {dR}; W={W} {dW}; B={B} {dB}", R=r * k, W=w * k, B=b * k, dR=d[R], dW=d[W], dB=d[B]) printf("final: {jugs4}")Solution: At the end, the red jug contains: 55 ml lime, 15 ml kiwi, 10 ml mango.
The situation is (with volumes in ml):
And we see that the red jug has 45 ml more lime than mango in its mix.
LikeLike