import Data.List
--------------------------------------------------------------------------------
-- LifeRPG - RP Reward Calculator
--
-- A simple calculator to help decide how to price rewards in LifeRPG.
--
-- Instructions:
--
-- 1) Fill in the price of your reward in real currency:
price = 49.99
--
-- 2) Add high and low "real currency to RP" conversion points below. Additional
-- points may be added, but there must be at least two. "Dollar" here can be
-- replaced with RealCurrency, Minute, Hour, or Day. It makes no difference,
-- but might help clarity.
conversionPoints =
[ a 10 Dollar reward `should` cost 250 RP
, a 50 Dollar reward `should` cost 750 RP
, a 100 Dollar reward `should` cost 1000 RP
]
--
-- 3) Click the "Run" button below to calculate your reward cost.
--
-- Note: I use the term "price" here, but it can just as well be thought of
-- as "time" if the reward costs time instead of money.
--------------------------------------------------------------------------------
---- PROGRAM START: DO NOT EDIT THIS ----
main :: IO ()
main = do
let points = sort conversionPoints
if length points < 2 then error "Must have 2 or more conversion points."
else return ()
if price < 0 || any (\(x,y) -> x < 0 || y < 0) points then
error "All values must be positive."
else return ()
let (lowPoints,highPoints) = partition ((>=) price . fst) points
printRP $ calcRP price lowPoints highPoints
where
printRP rp = do
putStr "Your reward should cost: "
putStr $ show rp
putStrLn " RP!"
calcRP :: Float -> [(Float,Float)] -> [(Float,Float)] -> Int
calcRP price lowPoints highPoints
| null lowPoints = round $
price * (snd . head $ highPoints) / (fst . head $ highPoints)
| null highPoints = round $
price * (snd . last $ lowPoints) / (fst . last $ lowPoints)
| otherwise = round rpAmount
where
lowRP = (snd . last) lowPoints
lowCurrency = (fst . last) lowPoints
highRP = (snd . head) highPoints
highCurrency = (fst . head) highPoints
rpSlope = (highRP - lowRP) / (highCurrency - lowCurrency)
rpAmount = (price - lowCurrency) * rpSlope + lowRP
---- eDSL Helpers ----
data Currency = RealCurrency | Dollar | RP | Minute | Hour | Day
reward = ""
a :: Float -> Currency -> String -> Float
a realCurrency _ _ = realCurrency
cost :: Float -> Currency -> Float
cost = const
should :: Float -> Float -> (Float, Float)
should = (,)