DEV Community

dev.to staff
dev.to staff

Posted on

Daily Challenge #56 - Coffee Shop

Today, your challenge is to help Bob with his coffee shop!

Bob's coffee shop is really busy, so busy in fact that if you do not have the right amount of change, you won't get your coffee as Bob doesn't like waiting for people to sort change. Drinks avaialble are Americano £2.20, Latte £2.30, Flat white £2.40 and Filter £3.50

Write a function that returns, "Here is your "+type+", have a nice day!" if they have the right change or returns "Sorry, exact change only, try again tomorrow!"


Want to propose a challenge idea for a future post? Email yo+challenge@dev.to with your suggestions!

This challenge comes from victoriabate on CodeWars. Thank you to CodeWars, who has licensed redistribution of this challenge under the 2-Clause BSD License!

Oldest comments (30)

Collapse
 
ynndvn profile image
La blatte

Well, here it is:

const pay = (amount) => {
  const beverage = {2.2:'Americano',2.3:'Latte',2.4:'Flat white',3.5:'Filter'}[amount];
  return beverage ? `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!"
Collapse
 
smz_68 profile image
Ardalan

I like it

Collapse
 
lordapple profile image
LordApple • Edited

I also like it, and decided to rewrite it in c++

    const auto pay = [](float cash){
        const auto coffee = std::unordered_map<float, std::string>{
                {2.2, "Americano"},
                {2.3, "Latte"},
                {2.4, "Flat white"},
                {3.5, "Filter"},

        }[cash];

        return coffee.empty() ? "Sorry, exact change only, try again tomorrow!"
                              : "Here is your " + coffee + ", have a nice day!";
    };
Collapse
 
georgecoldham profile image
George

What is the name for the

{a:'A', b:'B', c:'C'}[value]

notation? I seem to have managed to avoid seeing this for years!

Collapse
 
aayzio profile image
aayzio • Edited

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.

Thread Thread
 
georgecoldham profile image
George

Awesome, thank you!

Thread Thread
 
aayzio profile image
aayzio

You're welcome!

Collapse
 
kvharish profile image
K.V.Harish

Good approach. What if the function is called like

pay('2.20')
Collapse
 
chrisachard profile image
Chris Achard

I did it three different ways, but here's what I ended up with as probably the cleanest:

JS

const coffee = (amount) => {
  let drinktype = {
    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!"
  }
}
Enter fullscreen mode Exit fullscreen mode

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

Collapse
 
yas46 profile image
Yasser Beyer
const coffeeAmounts = {
    'Americano': 2.20,
    'Latte': 2.30,
    'Flat White': 2.40,
    'Filter': 3.50
}

const coffee = (coffeeType, cash) => {
    return coffeeAmounts[coffeeType] === cash 
      ? "Here is your " + coffeeType + ", have a nice day!"
      : "Sorry, exact change only, try again tomorrow!";
}
Collapse
 
cgty_ky profile image
Cagatay Kaya

A simple Javascript solution using nested ternary operators.

const coffeeShop = (order = "Water", cash = 0) => {
  const drinks = [
    { name: "Americano", cost: 2.2 },
    { name: "Latte", cost: 2.3 },
    { name: "Flat White", cost: 2.4 },
    { name: "Filter", cost: 3.5 }
  ];

  const request = 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!!
Collapse
 
craigmc08 profile image
Craig McIlwrath • Edited

Haskell

import qualified Data.Map.Strict as M

coffees = M.fromList [ (2.2, "Americano")
                     , (2.3, "Latte") 
                     , (2.4, "Flat white") 
                     , (3.5, "Filter")
                     ]

coffee :: Double -> String
coffee price = let maybeName = M.lookup price coffees
               in case maybeName of
                 Nothing -> "Sorry, exact change only. Try again tomorrow!" 
                 Just name -> "Here is your " ++ name ++ ", have a nice day!" 
Collapse
 
rafaacioly profile image
Rafael Acioly • Edited

Python solution

from decimal import Decimal

def pay(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'

  return error_message if not drink else success_message

Remember, always use decimal for currency

Collapse
 
aminnairi profile image
Amin

My take at the challenge written in Haskell this time!

changeToMessage :: Float -> String
changeToMessage change 
    | 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!

Try it online.

Collapse
 
ben profile image
Ben Halpern • Edited

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 }.freeze

def buy(drinks, cash)
    costs = drinks.map { |drink| DRINK_COSTS[drink] }
    response = "Sorry, exact change only, try again tomorrow!"
    response = if costs == cash && drinks.size > 1
                   "Here are your beverages, have a nice day!"
               elsif costs == cash
                   "Here is your #{drinks.first}, have a nice day!"
               end
end

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).

Collapse
 
dak425 profile image
Donald Feury

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.

Collapse
 
craigmc08 profile image
Craig McIlwrath

You are correct. I edited my original comment.

Collapse
 
jeremy profile image
Jeremy Schuurmans

Here's mine:

function getCoffee(change) {
  const changeSum = 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!");
  }
}