Friday Puzzler: Split the Bill

This post is more than 2 years old.

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.

Raymond Camden's Picture

About Raymond Camden

Raymond is a senior developer evangelist for Adobe. He focuses on document services, JavaScript, and enterprise cat demos. If you like this article, please consider visiting my Amazon Wishlist or donating via PayPal to show your support. You can even buy me a coffee!

Lafayette, LA https://www.raymondcamden.com

Archived Comments

Comment 1 by Mike Collins posted on 11/30/2012 at 9:29 PM

This probably needs more validation but here is my quick answer.

https://docs.google.com/doc...

Comment 2 by Lance posted on 11/30/2012 at 9:52 PM

Here is my shot :-)

<pre>
&lt;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&lt;=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&lt;=arguments.p;i++){
rt[i]=dollarFormat(rt[i]/100);
}
return rt;
}
result = SplitBill(numOfPeople,bill,tip);
writeDump(result);
&lt;/cfscript>

</pre>

Comment 3 by Bill posted on 11/30/2012 at 10:04 PM
Comment 4 by Bill posted on 11/30/2012 at 10:12 PM

Small update to above post

http://pastebin.com/u30niHsz

Comment 5 by Raymond Camden posted on 11/30/2012 at 10:14 PM

Will I be the first to smile at the fact that Bill wrote code to split the Bill? :)

Comment 6 by Lance posted on 11/30/2012 at 10:34 PM

Since this pasted poorly, here it is in paste bin. Extra point for figuring the tip? lol

http://pastebin.com/zs36UkiF

Comment 7 by CJM posted on 12/1/2012 at 3:49 AM

Whew, this ended up being some ugly code when you try to go fast!

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() );

Comment 8 by Raymond Camden posted on 12/1/2012 at 3:51 AM

Btw - thank you to all who used pastebin/external sites/etc. Lance, you're fired. No, you lose -2.1 brownie points. There we go. ;)

Comment 9 by Jared posted on 12/1/2012 at 4:08 AM

hi everyone! this is a great exercise idea, but is anyone going to post a sample in something other than cold fusion? i'm sure all those script samples are awesome and work great for people who run cold fusion, but you can bring in a ton of traffic on this blog post if you show some samples in a more current or relevant language. how about some python maybe? i'm learning that one as we speak, that would be great. anyone???

Comment 10 by AXL posted on 12/1/2012 at 7:48 AM

Here is my version.

http://pastebin.com/7MthR9Sd

Comment 11 by Raymond Camden posted on 12/1/2012 at 5:11 PM

@Jared: I don't mind other languages, but this is a "ColdFusion" puzzler. It is specifically meant for ColdFusion solutions.

Comment 12 by Bob posted on 12/2/2012 at 7:15 AM

Just ran across this and figured I'd throw my entry in just for the heck of it...

http://pastebin.com/a4mG00JD