-
Notifications
You must be signed in to change notification settings - Fork 0
/
goingtothecinema.fsx
40 lines (30 loc) · 1.81 KB
/
goingtothecinema.fsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
(*
My friend John likes to go to the cinema. He can choose between system A and system B.
System A : buy a ticket (15 dollars) every time
System B : buy a card (500 dollars) and every time
buy a ticket the price of which is 0.90 times the price he paid for the previous one.
#Example: If John goes to the cinema 3 times:
System A : 15 * 3 = 45
System B : 500 + 15 * 0.90 + (15 * 0.90) * 0.90 + (15 * 0.90 * 0.90) * 0.90 ( = 536.5849999999999, no rounding for each ticket)
John wants to know how many times he must go to the cinema so that the final result of System B, when rounded up to the next dollar, will be cheaper than System A.
The function movie has 3 parameters: card (price of the card), ticket (normal price of a ticket), perc (fraction of what he paid for the previous ticket) and returns the first n such that
ceil(price of System B) < price of System A.
taken from: https://www.codewars.com/kata/going-to-the-cinema/train/fsharp
*)
let calcCard start ticket perc n =
[1 .. n]
|> Seq.fold(fun sum idx -> sum + (float(ticket) * (pown perc idx))) (float(start))
let movie (card:int) (ticket:int) (perc:float) : int =
// let idx, maxcard, maxticket = Seq.initInfinite id
// |> Seq.map(fun idx -> ((idx, calcCard card ticket perc idx, ticket * idx)))
// |> Seq.skipWhile(fun (idx, sumcard, sumticket) -> ceil(sumcard) >= float(sumticket))
// |> Seq.head
// idx
let rec loop (cardsum, ticketsum, count) =
let cs = cardsum + (float(ticket) * (pown perc count))
let ts = ticket * count
match ceil(cs) >= float(ts) with
|true -> loop(cs, ts, (count + 1))
|false -> count
loop(float(card), 0, 1)
let m = movie 250 20 0.9