## Friday Puzzler: Split the Bill

Today's puzzler is more of a simple exercise than a real brain teaser, but the more I thought about it, the more I thought it might be a fun little bit of code to write or something that more experienced developers could pass on to their coworkers. As always, the "rules" are to try to do this within five minutes or so.

Today's puzzler is simple. You will write a UDF (User-Defined Function) that handles splitting a bill. Your first argument is the total bill. The second argument is the number of people. Simple division, right? Well here's where things get a bit interesting. If you have a bill of one dollar and three people, you can't simply divide 1 by 3 as you'll get a result with a fraction of a cent. Therefore, your solution has to be a bit more elegant. I want you to return an array. The array will have one element per person. Each value in the array represents how much each person will pay in dollars and cents. Values like: 1.25, 9.89, 10, etc. Given that you will most likely have floating-point results, you need to collect the extra money and just give it to one person.

So given the initial example of one dollar and three people, you would return an array that looks like so: [0.34,0.33,0.33]

Bonus points will be awards for good validation (what happens if you pass in a negative amount) and randomly assigning the pennies as opposed to always giving it to the first person.

Every solution should take the bill as the first argument. It should be a number value representing the dollars and cents total for the bill. So 1.75 for one dollar and seventy-five cents. The second argument is the number of people.

https://docs.google.com/document/pub?id=1iHgidr-4r...

<pre>

<cfscript>

param name='numOfPeople' default='3';

param name='bill' default='143.03';

param name='tip' default='0.15';

function SplitBill(p,b,t){ // p = number of people, b = bill total, t = percentage of tip to be left default to 15%

var rt = arrayNew(1);

var tb = 0;

var eachBase = 0;

var remainder = 0;

var ranPerson = 0;

if (!isNumeric(arguments.p)||!isNumeric(arguments.b)){return 'Enter Bill and number of people as numbers';}

if (!isNumeric(arguments.t)){arguments.t = 0.15;}

var tb = arguments.b*(1+arguments.t);

var eachBase = int(tb*100/arguments.p);

var remainder = arguments.b*100 mod arguments.p;

var ranPerson = randRange(1,arguments.p);

for(i=1;i<=arguments.p;i++){

rt[i]=eachBase;

}

while(remainder>0){

rt[ranPerson]=rt[ranPerson]+1;

ranPerson = ranPerson+1;

if(ranPerson > arrayLen(rt)){ranPerson=1;}

remainder = remainder-1;

}

for(i=1;i<=arguments.p;i++){

rt[i]=dollarFormat(rt[i]/100);

}

return rt;

}

result = SplitBill(numOfPeople,bill,tip);

writeDump(result);

</cfscript>

</pre>

http://pastebin.com/UVu3MhiC

http://pastebin.com/u30niHsz

http://pastebin.com/zs36UkiF

http://pastebin.com/pMgS6aB8

Here are the test cases I ran ( I'd love to know the ones that break it! ):

writeOutput( ".33 .33 .34" );

writeDump( splitBill( 3, 1 ) );

writeOutput( ".25 .25" );

writeDump( splitBill( 2, .5 ) );

writeOutput( "20" );

writeDump( splitBill( 1, 20 ) );

writeOutput( "1.33 1.33 1.34" );

writeDump( splitBill( 3, 4 ) );

writeOutput("4.21 4.21 4.21 4.21");

writeDump( splitBill( 4, 16.84 ) );

writeOutput( "4.39 4.39 4.39 4.39 4.39 4.40" );

writeDump( splitBill( 6, 26.35 ) );

writeOutput(" -3, 26.35");

writeDump( splitBill( -3, 26.35 ) );

writeOutput(" 3, -26.35");

writeDump( splitBill( 3, -26.35 ) );

writeOutput("Nothing Passed");

writeDump( splitBill() );

http://pastebin.com/7MthR9Sd

http://pastebin.com/a4mG00JD