constpay=(amount)=>{constbeverage={2.2:'Americano',2.3:'Latte',2.4:'Flat white',3.5:'Filter'}[amount];returnbeverage?`Here is your ${beverage}, have a nice day!`:'Sorry, exact change only, try again tomorrow!';}
Which outputs:
pay(2.2)"Here is your Americano, have a nice day!"pay(2.3)"Here is your Latte, have a nice day!"pay(2.30)"Here is your Latte, have a nice day!"pay(2.31)"Sorry, exact change only, try again tomorrow!"
constautopay=[](floatcash){constautocoffee=std::unordered_map<float,std::string>{{2.2,"Americano"},{2.3,"Latte"},{2.4,"Flat white"},{3.5,"Filter"},}[cash];returncoffee.empty()?"Sorry, exact change only, try again tomorrow!":"Here is your "+coffee+", have a nice day!";};
The {} operator would define a map. In the solution that would be a map of float type keys for string type values. The [ ] is then used to access a particular key.
I did it three different ways, but here's what I ended up with as probably the cleanest:
JS
constcoffee=(amount)=>{letdrinktype={2.2:"Americano",2.3:"Latte",2.4:"Flat white",3.5:"Filter",}[amount]if(drinktype){return"Here is your "+drinktype+", have a nice day!"}else{return"Sorry, exact change only, try again tomorrow!"}}
You can watch me solve it here, plus see the other two solutions (and a bonus discussion about why not to use floats for currency in JS 😂): youtu.be/HtvBlId7tig
I over engineered this but I felt like having a bit of fun with this one so lets have a Go shall we!?
coffee.go
packagecoffeeimport"fmt"// Product represents a type of product available at the coffee shoptypeProductintconst(AmericanoProduct=iotaLatteFlatWhiteFilter)const(// AmericanoPrice is the price of the product AmericanoAmericanoPricefloat64=2.20// LattePrice is the price of the product LatteLattePricefloat64=2.30// FlatWhitePrice is the price of the product FlatWhiteFlatWhitePricefloat64=2.40// FilterPrice is the price of the product FilterFilterPricefloat64=3.50)const(exactChangestring="Here is your %s, have a nice day!"notExactstring="Sorry, exact change only, try again tomorrow!")// String gives the text representation of the productfunc(pProduct)String()string{switchp{caseAmericano:return"Americano"caseLatte:return"Latte"caseFlatWhite:return"Flat White"caseFilter:return"Filter"default:return""}}// Price returns of the price of the productfunc(pProduct)Price()float64{switchp{caseAmericano:returnAmericanoPricecaseLatte:returnLattePricecaseFlatWhite:returnFlatWhitePricecaseFilter:returnFilterPricedefault:returnfloat64(0)}}// Order represents an order submitted to the coffee shoptypeOrderstruct{Items[]Product// Items is the collection of products being orderedTenderfloat64// Tender is the amount of money given for the order}// Total calculates the total value of the order from all the products in itfunc(oOrder)Total()float64{vartotalfloat64for_,item:=rangeo.Items{total+=item.Price()}returntotal}func(oOrder)String()string{count:=len(o.Items)switchcount{case0:return""case1:returno.Items[0].String()case2:returnfmt.Sprintf("%s and %s",o.Items[0].String(),o.Items[1].String())default:varstrstringfori,item:=rangeo.Items{ifi+1==count{str+="and "}str+=item.String()ifi+1!=count{str+=", "}}returnstr}}// Purchase responds to an order submitted at the coffee shopfuncPurchase(orderOrder)string{iforder.Total()==order.Tender{returnfmt.Sprintf(exactChange,order)}returnnotExact}
coffee_test.go
packagecoffeeimport"testing"funcTestPurchase(t*testing.T){testCases:=[]struct{descriptionstringinputOrderexpectedstring}{{"buy an Americano with exact change",Order{[]Product{Americano,},AmericanoPrice,},"Here is your Americano, have a nice day!",},{"buy an Americano without exact change",Order{[]Product{Americano,},2.30,},notExact,},{"buy a Latte with exact change",Order{[]Product{Latte,},LattePrice,},"Here is your Latte, have a nice day!",},{"buy a Latte without exact change",Order{[]Product{Latte,},5.00,},notExact,},{"buy a Flat White with exact change",Order{[]Product{FlatWhite,},FlatWhitePrice,},"Here is your Flat White, have a nice day!",},{"buy a Flat White without exact change",Order{[]Product{FlatWhite,},10.00,},notExact,},{"buy a Filter with exact change",Order{[]Product{Filter,},FilterPrice,},"Here is your Filter, have a nice day!",},{"buy a Filter without exact change",Order{[]Product{Filter,},4.00,},notExact,},{"buy two drinks with exact change",Order{[]Product{Americano,FlatWhite,},AmericanoPrice+FlatWhitePrice,},"Here is your Americano and Flat White, have a nice day!",},{"buy two drinks without exact change",Order{[]Product{Filter,Latte,},10.00,},notExact,},{"buy many drinks with exact change",Order{[]Product{Americano,Americano,FlatWhite,Latte,Filter,},(AmericanoPrice*2)+FlatWhitePrice+LattePrice+FilterPrice,},"Here is your Americano, Americano, Flat White, Latte, and Filter, have a nice day!",},{"buy many drinks without exact change",Order{[]Product{Americano,Americano,FlatWhite,Latte,Filter,},30.00,},notExact,},}for_,test:=rangetestCases{ifresult:=Purchase(test.input);result!=test.expected{t.Fatalf("FAIL: %s - Purchase(%+v): '%s' - expected '%s'",test.description,test.input,result,test.expected)}t.Logf("PASS: %s",test.description)}}
I used this challenge as my "hello world" with Go. At first I tried a map thinking that it might be easy to have float64 type as key. Can you please post a solution using a map? Here's mine:
packagemainimport"fmt"funcbuy(amountstring)string{types:=map[string]string{"2.2":"Americano","2.3":"Latte","2.4":"Flat white","3.5":"Filter",}returnfmt.Sprintf("Here is your %s have a nice day!",types[amount])}funcmain(){fmt.Println(buy("2.2"))fmt.Println(buy("3.5"))}
That would also enable you to pass in a float as an argument to the func instead of a string as well.
Don't forget to include logic for checking if they have exact change!
If you would still like me to post a solution using a map I would be more than happy to.
Note
In Golang, if you attempt to access a value of a map with a key that doesn't exist, you will get the zero value of the type stored in the map. That may be useful for the exact change logic check in your solution.
If we use your map for example:
types[5.0]
would return "", since the key 5.0 doesn't exist and "" is the zero value for a string in Golang.
importqualifiedData.Map.StrictasMcoffees=M.fromList[(2.2,"Americano"),(2.3,"Latte"),(2.4,"Flat white"),(3.5,"Filter")]coffee::Double->Stringcoffeeprice=letmaybeName=M.lookuppricecoffeesincasemaybeNameofNothing->"Sorry, exact change only. Try again tomorrow!"Justname->"Here is your "++name++", have a nice day!"
I feel it isn't super explicit that people can only order one drink here, so maybe the function should account for that, eh?
In Ruby
DRINK_COSTS={"Americano"=>2.2,"Latte"=>2.3,"Flat white"=>2.4,"Filter"=>3.50}.freezedefbuy(drinks,cash)costs=drinks.map{|drink|DRINK_COSTS[drink]}response="Sorry, exact change only, try again tomorrow!"response=ifcosts==cash&&drinks.size>1"Here are your beverages, have a nice day!"elsifcosts==cash"Here is your #{drinks.first}, have a nice day!"endend
This would expect drinks to be an array of strings. We could also do something were we could accept either a string or an array with something like drinks = [drinks].flatten where we put the result in an array and then flatten it each time. That way we don't have to worry about the type we get (since we aren't checking for it due to this being Ruby).
I had actually thought about that myself but chose not to consider it at the moment. I might go back and tweak mine to take a collection of drinks as well.
fromdecimalimportDecimaldefpay(amount:Decimal)->str:drink={2.2:'Americano',2.3:'Latte',2.4:'Flat white',3.5:'Filter'}.get(amount)error_message='Sorry, exact change only, try again tomorrow!'success_message=f'Here is your {drink}, have a nice day'returnerror_messageifnotdrinkelsesuccess_message
My take at the challenge written in Haskell this time!
changeToMessage::Float->StringchangeToMessagechange|change==2.2="Here is your Americano, have a nice day!"|change==2.3="Here is your Late, have a nice day!"|change==2.4="Here is your Flat White, have a nice day!"|change==3.5="Here is your Filter, have a nice day!"|otherwise="Sorry, exact change only, try again tomorrow!
-module(coffee).-include_lib("eunit/include/eunit.hrl").-export([coffee/1]).coffee(X)->P=coffee_price(X),casePoffalse->"Sorry, exact change only, try again tomorrow!";_->"Here is your "++P++", have a nice day!"end.coffee_price(2.20)->"Americano";coffee_price(2.30)->"Latte";coffee_price(2.40)->"Flat white";coffee_price(3.50)->"Filter";coffee_price(_)->false.americano_test()->?assert(coffee(2.20)=="Here is your Americano, have a nice day!").latte_test()->?assert(coffee(2.30)=="Here is your Latte, have a nice day!").flat_white_test()->?assert(coffee(2.40)=="Here is your Flat white, have a nice day!").filter_test()->?assert(coffee(3.50)=="Here is your Filter, have a nice day!").invalid_test()->?assert(coffee(4.90)=="Sorry, exact change only, try again tomorrow!").
constcoffeeAmounts={'Americano':2.20,'Latte':2.30,'Flat White':2.40,'Filter':3.50}constcoffee=(coffeeType,cash)=>{returncoffeeAmounts[coffeeType]===cash?"Here is your "+coffeeType+", have a nice day!":"Sorry, exact change only, try again tomorrow!";}
A simple Javascript solution using nested ternary operators.
constcoffeeShop=(order="Water",cash=0)=>{constdrinks=[{name:"Americano",cost:2.2},{name:"Latte",cost:2.3},{name:"Flat White",cost:2.4},{name:"Filter",cost:3.5}];constrequest=drinks.filter(drink=>drink.name==order);request[0]==null?console.log(`We do not serve ${order} here. Try some Filter tomorrow.`):request[0].cost==cash?console.log(`Here is your ${request[0].name}, have a nice day!`):console.log("Sorry, exact change only, try again tomorrow!");};
Works fine
coffeeShop();//We do not serve Water here. Try some Filter tomorrow!coffeeShop("Americano",2.2);//Here is your Americano, have a nice day!coffeeShop("Americano",2.5);//Sorry, exact change only, try again tomorrow!coffeeShop("Filter",3.5);//Here is your Filter, have a nice day!coffeeShop("Mocha",3.5);//We do not serve Mocha here. Try some Filter tomorrow!!
functiongetCoffee(change){constchangeSum=change.reduce((a,b)=>a+b);switch(changeSum){case(2.20):return("Here is your Americano, have a nice day!");break;case(2.30):return("Here is your Latte, have a nice day!");break;case(2.40):return("Here is your Flat white, have a nice day!");break;case(3.50):return("Here is your Filter, have a nice day!");break;default:return("Sorry, exact change only, try again tomorrow!");}}
constgetACoffee=(amount)=>{constmenu={'2.2':'Americano','2.3':'Latte','2.4':'Flat white','3.5':'Filter'},coffeeType=menu[`${parseFloat(amount)}`];returncoffeeType?`Here is your ${coffeeType}, have a nice day!`:'Sorry, exact change only, try again tomorrow!'};
defbob(type: 'water',money: '0.0')exact={'americano'=>'2.20','latte'=>'2.30','flat white'=>'2.40','filter'=>'3.50'}[type.to_s.downcase]==money{true=>"Here is your #{type.to_s}, have a nice day!",false=>'Sorry, exact change only, try again tomorrow!'}[exact]end
Outputs:
putsbob()# Sorry, exact change only, try again tomorrow!putsbob(type: 'Latte',money: '2.50')# Sorry, exact change only, try again tomorrow!putsbob(type: 'Latte',money: '2.30')# Here is your Latte, have a nice day!
defgetCoffee(smallChange,type):menu={'Americano':2.20,'Latte':2.30,'Flat white':2.40,'Filter':3.50}ifsum(smallChange)==menu[type]:return"Here is your %s, have a nice day!"%(type)else:return"Sorry, exact change only, try again tomorrow!"
objectCoffeeShop{privatelazyvalcoffees=Map(2.2->"Americano",2.3->"Flat white",2.4->"Latte",3.5->"Filter")//desired method defmakeCoffee(change:Double):String={coffees.get(change).fold("Sorry, exact change only, try again tomorrow!"){coffee=>s"Here is your $coffee, have a nice day!"}}}
Well, here it is:
Which outputs:
I also like it, and decided to rewrite it in c++
I like it
What is the name for the
notation? I seem to have managed to avoid seeing this for years!
The {} operator would define a map. In the solution that would be a map of float type keys for string type values. The [ ] is then used to access a particular key.
Awesome, thank you!
You're welcome!
Good approach. What if the function is called like
I did it three different ways, but here's what I ended up with as probably the cleanest:
JS
You can watch me solve it here, plus see the other two solutions (and a bonus discussion about why not to use floats for currency in JS 😂): youtu.be/HtvBlId7tig
I over engineered this but I felt like having a bit of fun with this one so lets have a Go shall we!?
coffee.go
coffee_test.go
I used this challenge as my "hello world" with Go. At first I tried a map thinking that it might be easy to have float64 type as key. Can you please post a solution using a map? Here's mine:
Hello Cherny!
You can most certainly use floats as keys in a map, you just need to indicate what type the keys are in the map declaration.
For your code above you have:
If you want to use floats as the keys, you simply need to indicate as so:
Then you could so something like this:
That would also enable you to pass in a float as an argument to the func instead of a string as well.
Don't forget to include logic for checking if they have exact change!
If you would still like me to post a solution using a map I would be more than happy to.
Note
In Golang, if you attempt to access a value of a map with a key that doesn't exist, you will get the zero value of the type stored in the map. That may be useful for the exact change logic check in your solution.
If we use your map for example:
would return "", since the key 5.0 doesn't exist and "" is the zero value for a string in Golang.
Tweaked to allow purchasing multiple drinks, inspired by Ben Halpern's solution.
Haskell
I feel it isn't super explicit that people can only order one drink here, so maybe the function should account for that, eh?
In Ruby
This would expect
drinks
to be an array of strings. We could also do something were we could accept either a string or an array with something like drinks = [drinks].flatten where we put the result in an array and then flatten it each time. That way we don't have to worry about the type we get (since we aren't checking for it due to this being Ruby).I had actually thought about that myself but chose not to consider it at the moment. I might go back and tweak mine to take a collection of drinks as well.
Python solution
My take at the challenge written in Haskell this time!
Try it online.
Erlang solution with tests.
A simple Javascript solution using nested ternary operators.
Works fine
Here's mine:
My solution in js
x86_64 assembly (System V ABI, GNU assembler), using the C standard library for printf.
coffee.S:
coffee.h:
Here you have a version using only ruby hashes:
Outputs:
Python
Scala:
Just perfect!
You are correct. I edited my original comment.