Бесконечные списки такие бесконечные

 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
41
42
{-
Чтобы испечь сто блинов, Шухрату требуется 30 минут, а Жене — 40 минут. Надир готов съесть 100 блинов за час. Шухрат с Женей пекут блины без остановки, а Надир непрерывно их поедает. Через какое время после начала этого процесса на столе окажется ровно сто блинов?
-}
import Data.List
import Data.Ratio
import Control.Monad
data Event t = Cooked t | Eaten t deriving Show
time (Cooked t) = t
time (Eaten t) = t
instance Eq t => Eq (Event t) where
x == y = time x == time y
instance Ord t => Ord (Event t) where
compare x y = (time x) `compare` (time y)
cook dt = map Cooked $ drop 1 $ iterate (+dt) 0
shuh = cook $ 30%100
jenya = cook $ 40%100
merge xs [] = xs
merge [] xs = xs
merge xs@(x:xs1) ys@(y:ys1)
| x <= y = x : merge xs1 ys
| otherwise = y : merge xs ys1
pancakes = merge shuh jenya
eat dt tm (Cooked t : ts) = (Eaten next) : eat dt next ts where next = (max t tm) + dt
nodir = eat (60%100) 0
events = merge pancakes (nodir pancakes)
withStock = zip events (drop 1 $ scanl diff 0 events)
where diff n (Cooked _) = n + 1
diff n (Eaten _) = n - 1
main = mapM_ print $ take 5 $ dropWhile ((<100).snd) withStock