I was given the task to solve the graded Diophantine problem. McDonald’s sells Chicken McNuggets in packages of 6, 9 or 20 McNuggets. Thus, it is possible, for example, to buy exactly 15 McNuggets (with one package of 6 and one package of 9), but it is not possible to buy exactly 16 nuggets, since no non-negative integer combination of 6’s, 9’s and 20’s adds up to 16. To determine if it is possible to buy exactly n McNuggets, one has to solve a Diophantine equation: find non-negative integer values of a, b, and c, such that
6a + 9b + 20c = n.
Write a function buy_nuggets() that takes a number (n) as an argument and returns tuple of four numbers which are; the total number of packages, the number of packages of 6 nuggets, the number of packages of 9 nuggets and the number of packages of 20 nuggets that are needed to sell n number of nuggets. If the combination of nuggets cannot be made then it returns a tuple of four zeros i.e. (0,0,0,0).
Note that there can be multiple solutions for a given n, then your solution should ensure that the smaller packages are used before the larger packages. For example, buy_nuggets(18) should return (3,3,0,0) instead of (2,0,2,0), that is 3 boxes of 6 piece nuggets over 2 boxes of nine piece. Input Format Integer (n)
I was provided with the restrictions -10^6<=a,b,c,n<=10^6
Output Format
Tuple of 4 numbers (d,a,b,c) where
d = total number of packages a - number of packages of 6 b - number of packages of 9 c - number of packages of 20
I then attempted
def nugget_boxes(n):
# Write your code here- (above this was given)
def diophantine(a,b,c,d):
if a>b and c and d:
q=extended_nuggets(a,b,c,d)
a1=q[1]
b1=q[2]
c1=q[3]
d1=q[4]
if b>a and c and d:
q=extended_nuggets(a,b,c,d)
a1=q[2]
b1=q[1]
c1=q[3]
d1=q[4]
if c>a and b and d:
q=extended_nuggets(a,b,c,d)
a1=q[3]
b1=q[1]
c1=q[2]
d1=q[4]
else:
q=extended_nuggets(a,b,c,d)
a1=q[4]
b1=q[1]
c1=q[2]
d1=q[3]
assert c%q[0]==0
d=q[0]
p=c/d
return diophantine(int(p*x1),int(p*y1), int(p*z1))
if __name__ == '__main__':
fptr = open(os.environ['OUTPUT_PATH'], 'w')
n = int(raw_input().strip())
results = nugget_boxes(n)
fptr.write(str(results) + '\n')
fptr.close()
I did ask before and was advised to return the function, I was referred to a python tutorial to which I am grateful for and I am reading, very concise yet informative. However, this specific problem has been giving me a hard time. I know this might be a hard task, but I was hoping you could still attempt teaching even with my current knowledge of coding.
An iterative solution that works well with the specific box sizes is below. It's expandable to other box scenarios by simply adding more nested
ifblocks.The way in which the "prefer smaller boxes" requirement is met is simply by ensuring we search the solution space appropriately. In other words, we start with the maximum possible number of six-boxes and search down.
Similarly, we start with the maximum possible number of nine-boxes (given the number of six-boxes) and search down.
We don't have to search number of twenty-boxes since, given the quantity of the two smaller sizes, there's only one possibility: the number that gets as close as possible to the desired quantity without going over.
Then, if we got the quantity exactly, we return the solution immediately. Otherwise, we keep searching. If no solution is found after exhaustive search, we return the sentinel value (all zeroes).
This is certainly better than the naive approach of testing every possible scenario of the counts and saving the one that meets the "prefer smaller boxes" requirement.
And what self-respecting developer would post code without a test harness? "Not I," said Pax :-)
The output from the test harness shows the function in action (comments added by me):