Three jars hold integer quantities of water A, B, C. A pour operation picks two jars and transfers water from the larger to the smaller, exactly enough to double the smaller:
Goal: design a sequence of pours guaranteed to reach a state where at least two jars hold equal amounts, starting from any positive integers A, B, C.
This problem is hard to solve from scratch in a reasonable time. The intended approach is:
Work through these in order. Each step is a starting point for a prompt — adapt the wording, try follow-ups, push back when the answer seems wrong.
Give the LLM the problem statement as written. Read the answer carefully. Does it actually solve the general case, or only specific instances? Test it on inputs you pick yourself. Many first answers to this problem are wrong or incomplete — your job here is to notice that before moving on.
Set the goal aside. Ask: if I keep pouring into jar A over and over, what happens to its value? What is the total water drawn from the source after k pours? Is there a closed form? Work one small example by hand before trusting the LLM's answer.
Now ask: can I make jar B lose exactly qA total, for an integer q I choose? What if at each step I get to pick whether to pour from B or from C into A — does that freedom help? Try constructing sequences for q = 5, 7, 13, and a large q with a small C. Ask the LLM to find the general pattern and verify it on your examples.
You can now subtract any multiple of A from B. Which multiple should you pick so the jars are in a strictly simpler state afterward? Does this remind you of any classical algorithm? Ask the LLM to state a loop invariant and prove: (i) each round produces legal pours, (ii) something strictly decreases, (iii) termination implies the goal is reached. Check the proof on your examples — LLM termination proofs on this problem are often hand-wavy.
A short informal explanation — half a page, no formal notation — of how the algorithm works. Imagine explaining it at a whiteboard to a sharp friend. Cover: why the goal simplifies, what repeated pouring gives you, how the third jar is used, and why the process terminates. This should be written entirely in your own words.
Write the pseudocode yourself (not from LLM output). Then implement it in Python or Java — LLM help is fine here. Run on all four examples below and include the full pour sequence and final state for each.
| Input (A, B, C) | Notes |
|---|---|
| (3, 28, 100) | Running example from class |
| (7, 11, 23) | Values close together |
| (1, 1023, 1025) | Large values; stress test |
| (your choice, all ≥ 500) | Pick something non-trivial |
Study whatever the LLM produces, but write every sentence yourself. Four sub-parts, each graded independently:
How many rounds does the outer loop run? How many pours per round? What is the total pour count as a tight asymptotic bound? Justify each answer.
Describe the BFS approach: what are the states, what are the edges, how large is the state space in terms of A+B+C, and what is the worst-case runtime? Then compare directly to Q-4: how much better is the binary algorithm, and what structure does it exploit that BFS completely ignores?
Come to OH prepared to do three things without referring to your writeup:
The demo is graded first. Q-1 through Q-5 are not fully graded until Q-6 is done.