Difference between revisions of "FP Test3 2025"
Jump to navigation
Jump to search
| Line 10: | Line 10: | ||
* a type <code>Stock</code> for the available ingredients (name and quantity), | * a type <code>Stock</code> for the available ingredients (name and quantity), | ||
* a type <code>Drink</code> with the drink’s name, price, and list of required ingredients, | * a type <code>Drink</code> with the drink’s name, price, and list of required ingredients, | ||
| − | * a type Machine that combines both stock and available drinks. | + | * a type <code>Machine</code> that combines both stock and available drinks. |
</translate> | </translate> | ||
Latest revision as of 08:05, 11 November 2025
Home Preparation For Test 3 - 2025
(Theme: Vending Machine)
Data types and examples
Let's define a data types representing the state of a vending machine:
- a type
Stockfor the available ingredients (name and quantity), - a type
Drinkwith the drink’s name, price, and list of required ingredients, - a type
Machinethat combines both stock and available drinks.
type Stock = [(String, Int)]
data Drink = Drink { name :: String , price :: Int , ingredients :: [String] } deriving Show
data Machine = Machine {stock :: Stock, drinks :: [Drink] } deriving Show
stockExample :: Stock
stockExample = [ ("water", 10) , ("coffee", 4) , ("milk", 2) , ("tea", 3) , ("sugar", 5) , ("cocoa", 1) ]
drinksList :: [Drink]
drinksList = [
Drink "Coffee" 30 ["water","coffee"],
Drink "StrongCoffee" 40 ["water","coffee","coffee"],
Drink "Tea" 25 ["water", "water","tea"],
Drink "Cappuccino" 45 ["water","coffee","milk"],
Drink "Latte" 50 ["water","coffee","milk","sugar"],
Drink "Chocolate" 50 ["water","cocoa","milk"],
Drink "Cocoa" 60 ["milk","cocoa","milk"]
]
machineExample :: Machine
machineExample = Machine stockExample drinksList
Tasks
Create functions that:
- Implement a function
findDrinkthat finds a drink by name from a list.
If the drink does not exist, raise an error "No such drink".
findDrink :: [Drink] -> String -> Drink
ghci> findDrink drinksList "Tea"
Drink {name = "Tea", price = 25, ingredients = ["water","water","tea"]}
- Implement a function
inStockthat checks whether a given ingredient is currently available in stock.
inStock :: Stock -> String -> Bool
ghci> inStock stockExample "milk"
True
ghci> inStock stockExample "juice"
False
- Implement a function
useIngredientthat decreases the quantity of a given ingredient by one unit.
Ingredients with zero quantity should be removed from the stock.
useIngredient :: Stock -> String -> Stock
ghci> useIngredient stockExample "milk"
[("water",10),("coffee",4),("milk",1),("tea",3),("sugar",5),("cocoa",1)]
ghci> useIngredient stockExample "cocoa"
[("water",10),("coffee",4),("milk",2),("tea",3),("sugar",5)]
- Implement a function
canServeDrinkthat checks whether all ingredients required for a drink are available.
canServeDrink :: Stock -> Drink -> Bool
ghci> canServeDrink stockExample (findDrink drinksList "Cocoa")
True
- Implement a function
serveDrinkthat updates the stock after preparing a drink.
If some ingredient is missing, raise an error "Can not serve this drink".
serveDrink :: Stock -> Drink -> Stock
ghci> serveDrink stockExample (findDrink drinksList "Cocoa")
[("water",10),("coffee",4),("tea",3),("sugar",5)]
- Implement a function
processOrdersthat processes a list of orders (drink names) in sequence. It returns:Justa new machine with the updated stock if all drinks can be served, orNothingif any of the orders cannot be fulfilled.
processOrders :: Machine -> [String] -> Maybe Machine
ghci> processOrders machineExample ["Coffee","Tea","Coffee","Chocolate"]
Just (Machine {stock = [("water",5),("coffee",2),("milk",1),("tea",2),("sugar",5)], drinks = [ {- skipping list of drinks -} ]})
- Implement a function
processPaymentthat processes orders similarly but returns the total price of all successfully served drinks,
or Nothing if any order fails.
processPayment :: Machine -> [String] -> Maybe Int
ghci> processPayment machineExample ["Coffee","Tea","Coffee","Chocolate"]
Just 135
- Implement a function
bestValuethat finds the best possible combination of orders (any subset of the given list) maximizing the total profit.
Hint: You can generate all subsets of the input list, evaluate each with processPayment, and return one that yields the highest total payment.
bestValue :: Machine -> [String] -> [String]
ghci> bestValue machineExample ["Coffee","Tea","Coffee","Chocolate"]
["Coffee","Tea","Coffee","Chocolate"]
ghci> bestValue machineExample ["Cappuccino","Cappuccino","Tea","Cocoa","Chocolate"]
["Cappuccino","Tea","Chocolate"]
ghci> bestValue machineExample ["Cocoa","Chocolate"]
["Cocoa"]