Monday Mini-Golf #7: Simplify ingredient measurements
Mathematica, 349 334 330 322 bytes

This answer section felt a little lonely. So uh, here's my attempt. Input should be given as in the test cases.

n=ToExpression@StringSplit@InputString[];i=#~Mod~1&amp;;b=#&amp;@@n;If[Length@n==3,{x,y,z}=n,{x,y,z}=If[IntegerQ@b,{b,0,Last@n},{0,b,Last@n}]];v={0,1/4,1/3,1/2,2/3,3/4};s=&lt;|T-&gt;16,t-&gt;3,o-&gt;16,q-&gt;4,p-&gt;2,f-&gt;16|&gt;;r=&lt;|T-&gt;c,t-&gt;T,o-&gt;l,f-&gt;p,p-&gt;q,q-&gt;g|&gt;;If[v~MemberQ~i[a=(x+y)/s@z],{x,y,z}={Floor@a,i@a,r@z}]~Do~3;Print@Row[{x,y,z}/. 0-&gt;""]


Explanation

First get the user input, split that input on whitespace, and assign that to n. i=#~Mod~1&amp; creates a function that gets the fractional part of a number, by taking it mod 1. b=#&amp;@@n will simply get the first item in n; that would be everything up to the first space.

If n is 3 elements long, that means we have an integer, a fraction, and a unit. {x,y,z}=n will assign x, y and z to be the three parts of n.
The other case is that n is not 3 elements long; that means it’ll be 2 elements long instead. To stay consistent with above, we want x to be the integer part, y to be the fraction, and z the unit. So in this case, we need to check:


If b (the first element of n) is an integer, then x=b, y=0 and z=Last@n (the last element of n).
If b isn’t an integer, that means we only have a fraction with no integer. So we want to swap x and y from above; instead, x=0, y=b, and z is the same as above.


Now we need to set up some lists:

v = {0, 1/4, 1/3, 1/2, 2/3, 3/4} is the list of acceptable fractions, as stated in the question.

s = &lt;|T -&gt; 16, t -&gt; 3, o -&gt; 16, q -&gt; 4, p -&gt; 2, f -&gt; 16|&gt; is an association (key-value pair, like a dictionary in Python) that represents the amount needed of a given unit to go “up” to one of the next largest unit. For example, o -&gt; 16 is because 16 ounces are required before we go up to 1 pound.

r = &lt;|T -&gt; c, t -&gt; T, o -&gt; l, f -&gt; p, p -&gt; q, q -&gt; g|&gt; is the association that actually represents what the next unit up is. For example, T -&gt; c means one unit larger than Tablespoons is cups.

If[v~MemberQ~i[a = (x + y)/s@z], {x, y, z} = {Floor@a, i@a, r@z}]~Do~3

Now, the maximum number of times we need to go up a unit is 3; that would be fluid ounces (f) -> pints (p) -> quarts (q) -> gallon (g). So, now we do the following 3 times:


Add x and y, (the integer and fractional parts)
From the s association above, get element z; that is, access the current unit, and get the corresponding value in that association.
Divide (x+y) by that value we got above, assign it to a, then get its fractional part.
If that part is in the list v, then we can go up one unit; set x to a rounded down (integer part), set y to the fractional part of a, then access the association r with the current unit z to get the next unit up, and set that to z.
If it’s not part of v instead, we don’t do anything, since it can’t be simplified.


Once that’s done 3 times, we print out the result:

Print@Row[{x,y,z}/. 0-&gt;””]

This simply prints out {x,y,z} in a row, but replaces any zeroes (if there’s no integer, or no fraction), with an empty string, so those don’t print out.