Hoe kan je exact 5 liter water afmeten uit een bron als je enkel beschikt over een kruik van 7 liter en een kruik van 3 liter? Dit soort vragen kom je vaak tegen in puzzelboeken. Meestal kunnen dergelijke problemen vrij eenvoudig opgelost worden op basis van intuïtie of via de methode van gissen-en-missen. In het boek Scripta Mathematica uit 1948 beschrijf H.D. Grossman echter een vernuftige methode om systematisch een oplossing te genereren.

Veronderstel dat beide kruiken een volume van $$a$$ en $$b$$ liter hebben en dat we $$c$$ liter willen afmeten. Voor het gegeven voorbeeld is $$a=7$$, $$b=3$$ en $$c=5$$. Er moet gelden dat $$a$$ en $$b$$ twee verschillende positieve gehele getallen zijn, dat $$a$$ en $$b$$ relatieve priemgetallen zijn (hun grootste gemene deler is gelijk aan 1) en dat één van beide kruiken groter is dan het gevraagde volume $$c$$. Anders is het probleem onoplosbaar, triviaal, of kan het gereduceerd worden tot kleinere getallen.

broncode
broncode

Beschouw een veld van roosterpunten (punten met gehele coördinaten) met daarin de lijn $$OP$$ (blauwe lijn) die $$O$$ in het punt $$(0, 0)$$ verbindt met $$P$$ in het punt $$(a, b)$$ (het punt $$(7, 3)$$ in ons voorbeeld). Teken nu een zigzaglijn $$Z$$ (groene lijn) die vanuit $$O$$ vertrekt, en steeds het huidige punt verbindt met zijn bovenbuur als deze niet boven de lijn $$OP$$ ligt, of anders het huidige punt verbindt met zijn rechterbuur. Er kan aangetoond worden dat $$Z$$ voor het eerst de lijn $$OP$$ snijdt in het punt $$P$$.

De zigzaglijn $$Z$$ vormt nu als het ware een beschrijving om de kruiken te vullen uit de bron, in elkaar over te gieten en leeg te maken, totdat op een bepaald punt één van beide kruiken exact de gevraagde hoeveelheid water bevat. Als we starten in $$O$$ en de zigzaglijn volgen, dan voeren we bij elke stap omhoog de volgende twee acties uit

en voeren we bij elke stap naar rechts de volgende twee acties uit

We blijven $$Z$$ volgen totdat één van beide kruiken exact de gevraagde hoeveelheid water bevat. Er kan aangetoond worden dat er altijd zo een punt $$C$$ op de zigzaglijn te vinden is. Voor ons voorbeeld moeten dus de volgende acties uitgevoerd worden

Er kan een alternatieve oplossing gevonden worden door een tweede zigzaglijn $$Z'$$ (rode lijn) te tekenen boven de lijn $$OP$$. Deze lijn gaat steeds naar de rechterbuur indien dat punt boven de lijn $$OP$$ ligt, anders naar de bovenbuur. De oplossing die we op deze manier aflezen kan gevonden worden door de rol van $$a$$ en $$b$$ om te wisselen in bovenstaande omschrijvingen. De alternatieve oplossing voor ons voorbeeld wordt dan

Grossman zei hierover in zijn boek "There are always exactly two solutions which are in a sense complementary to each other."

Opgave

Voorbeeld

>>> positie((3, 7), (3, 0))
-1
>>> positie((3, 7), (0, 3))
1
>>> positie((3, 7), (6, 14))
0

>>> broncode(7, 3, 5)
Vul de 3-liter kruik aan de bron.
Giet de inhoud van de 3-liter kruik in de 7-liter kruik.
Vul de 3-liter kruik aan de bron.
Giet de inhoud van de 3-liter kruik in de 7-liter kruik.
Vul de 3-liter kruik aan de bron.
Vul de 7-liter kruik op met water uit de 3-liter kruik.
Giet de 7-liter kruik leeg.
Giet de inhoud van de 3-liter kruik in de 7-liter kruik.
Vul de 3-liter kruik aan de bron.
Giet de inhoud van de 3-liter kruik in de 7-liter kruik.
De 7-liter kruik bevat nu 5 liter.

>>> broncode(7, 3, 5, alternatief=True)
Vul de 7-liter kruik aan de bron.
Vul de 3-liter kruik op met water uit de 7-liter kruik.
Giet de 3-liter kruik leeg.
Vul de 3-liter kruik op met water uit de 7-liter kruik.
Giet de 3-liter kruik leeg.
Giet de inhoud van de 7-liter kruik in de 3-liter kruik.
Vul de 7-liter kruik aan de bron.
Vul de 3-liter kruik op met water uit de 7-liter kruik.
De 7-liter kruik bevat nu 5 liter.

Bronnen