McNugget Numbers, Revisited
April 13, 2012
We studied McNugget Numbers in a previous exercise. You may recall that McDonald’s Restaurants sell Chicken McNuggets in meal sizes of 6, 9 or 20 nuggets, and a McNugget Number is a number that can be formed by some combination of 6, 9 and 20. For instance, 100 is a McNugget Number because 100 = 5 ·20.
The previous exercise asked you to find the list of numbers that cannot be formed by some combination of 6, 9 and 20; those numbers, which are the Non-McNugget Numbers, are 1, 2, 3, 4, 5, 7, 8, 10, 11, 13, 14, 16, 17, 19, 22, 23, 25, 28, 31, 34, 37 and 43. Today’s exercise asks you to count the ways in which a McNugget number can be formed; for instance, you can form the number 100 in 5 different ways: 100 = 0 · 6 + 0 · 9 + 5 · 20 = 1 · 6 + 6 · 9 + 2 · 20 = 4 · 6 + 4 · 9 + 2 · 20 = 7 · 6 + 2 · 9 + 2 · 20 = 10 · 6 + 0 · 9 + 2 · 20.
Your task is to write a program that calculates the number of ways a number can be expressed as a McNugget Number, and to use your program to calculate the number of ways to express one million as a McNugget Number. When you are finished, you are welcome to read or run a suggested solution, or to post your own solution or discuss the exercise in the comments below.
[…] today’s Programming Praxis exercise, our goal is to calculate the number of ways a number can be expressed […]
My Haskell solution (see http://bonsaicode.wordpress.com/2012/04/13/programming-praxis-mcnugget-numbers-revisited/ for a version with comments):
Problem: Find all possible combination of x,y,z for which
6x + 9y+ 20z = 100 (or P as input)
Sol: Compute Possible values range of x,y,z. This is the quotient of p divided by 6,8,20
In the above example
x = {0-13}
y= {0-11 }
z ={0-5}
Compute the combination by brute force:
List<tuple> result = new List<tuple>
for(int x= 0; x<= 13; x++)
{
for(int y = 0; y <= 11; y++)
{
for(int z =0; z <= 5; z++)
{
int number = 6x + 9y + 20z;
//put 100 as input variable
if( 100/number ==0)
{
Add(x,y,z) to result list;
}
else
continue;
}
}
}
Not a very good algorithm. Looks like a cubic Algorith O(3). Will work to improve it.
List result = new List
for(int x= 0; x<= 13; x++)
{
for(int y = 0; y <= 11; y++)
{
for(int z =0; z <= 5; z++)
{
int number = 6x + 9y + 20z;
//put 100 as input variable
if( number ==100)
{
Add(x,y,z) to result list;
}
else
continue;
}
}
}
Here’s an O(n) solution, that probably can be reduced to a closed form with some more work. However, Remco’s solution above is much more beautiful :-)
Dynamic Programming
#include
int mc_check(int);
void com_mc(int);
void main() {
int number;
clrscr();
printf(“Enter Number to be checked \n”);
scanf(“%d”,&number);
if(mc_check(number)==1) {
com_mc(number);
}
else {
printf(“Not an McNugget”);
}
getch();
}
int mc_check(int check) {
int i,flag=1;
if( check%6==0 || check%9==0 ||check%20==0 || (check-20)%6==0 || (check-20)%9==0 || (check-9)%20==0 || (check-9)%20==0 || (check-6)%9==0 || (check-6)%20==0 )
return flag;
else
return 0;
}
void com_mc(int number) {
int i,j,k,flag1,flag2,flag3;
for(i=0;((flag1=i*6)<=number);i++) {
for(j=0;((flag2=j*9)<=(number-flag1));j++) {
for(k=0;((flag3=k*20)<=(number-flag1-flag2));k++) {
if((i*6+j*9+k*20)==number)
printf("Combination:%d*6+%d*9+%d*20\n",i,j,k);
}
}
}
}
This is an intuitive yet slow python implementation: