{-# OPTIONS_GHC -O2 -fno-cse #-}
data People a = VIP a (People a) | Crowd [a]
mergeP
:: Ord a
=> People a
-> People a
-> People a
mergeP (VIP x xt) ys = VIP x $ mergeP xt ys
mergeP (Crowd xs) (Crowd ys) = Crowd $ merge xs ys
mergeP xs
@(Crowd
(x:xt
)) ys
@(VIP y yt
) = case compare x y
of LT -> VIP x $ mergeP (Crowd xt) ys
EQ -> VIP x $ mergeP (Crowd xt) yt
GT -> VIP y $ mergeP xs yt
merge
:: Ord a
=> [a
] -> [a
] -> [a
]merge xs
@(x:xt
) ys
@(y:yt
) = case compare x y
of LT -> x : merge xt ys
EQ -> x : merge xt yt
GT -> y : merge xs yt
diff xs
@(x:xt
) ys
@(y:yt
) = case compare x y
of LT -> x : diff xt ys
EQ -> diff xt yt
GT -> diff xs yt
foldTree :: (a -> a -> a) -> [a] -> a
foldTree f xs = go xs -- (pairs xs)
where pairs ~(x: ~(y:ys)) = f x y : pairs ys
go ~(x:zs) = x `f` go (pairs zs)
wheel = 2:4:2:4:6:2:6:4:2:4:6:6:2:6:4:2:6:4:6:8:4:2:4:2:
4:8:6:4:6:2:4:6:2:6:6:4:2:4:6:2:6:4:2:4:2:10:2:10:wheel
wheelNums = roll 0 wheel -- [0,2,6,8,12,18, ...]
rollFrom n = go wheelNums wheel
where m
= (n
-11) `
mod`
210 go (x:xs) (w:ws) = if x==m then roll (n+w) ws else go xs ws
primes = 2:3:5:7:primes'
where
primes' = diff (roll 11 wheel)
( serve
. foldTree mergeP
. map multiples
$ primes
_ )
primes_ = h ++ diff t
( serve
. foldTree mergeP
. map multiples
$ primes
_ ) where (h
,t
) = splitAt 6 (roll
11 wheel
)
multiples p = -- vip -- [p*q|q<-[p,p+2..]] -- [p*p,p*p+2*p..]
VIP (p*p) $ Crowd [p*q|q<-rollFrom p]
-- vip (x:xs) = VIP x $ Crowd xs
serve (VIP x xs) = x:serve xs
serve (Crowd xs) = xs
ey0jIE9QVElPTlNfR0hDIC1PMiAtZm5vLWNzZSAjLX0KbWFpbiA9IGdldExpbmUgPj49IHByaW50IC4gKHByaW1lcyAhISkgLiAoKyAoLTEpKSAuIHJlYWQKCmRhdGEgUGVvcGxlIGEgPSBWSVAgYSAoUGVvcGxlIGEpIHwgQ3Jvd2QgW2FdCiAKbWVyZ2VQIDo6IE9yZCBhID0+IFBlb3BsZSBhIC0+IFBlb3BsZSBhIC0+IFBlb3BsZSBhCm1lcmdlUCAoVklQIHggeHQpIHlzICAgICAgICAgICAgICAgICAgICA9IFZJUCB4ICQgbWVyZ2VQIHh0IHlzCm1lcmdlUCAoQ3Jvd2QgeHMpIChDcm93ZCB5cykgICAgICAgICAgICA9IENyb3dkICQgbWVyZ2UgIHhzIHlzCm1lcmdlUCB4c0AoQ3Jvd2QgKHg6eHQpKSB5c0AoVklQIHkgeXQpICA9IGNhc2UgY29tcGFyZSB4IHkgb2YKICAgIExUIC0+IFZJUCB4ICQgbWVyZ2VQIChDcm93ZCB4dCkgeXMKICAgIEVRIC0+IFZJUCB4ICQgbWVyZ2VQIChDcm93ZCB4dCkgeXQKICAgIEdUIC0+IFZJUCB5ICQgbWVyZ2VQIHhzIHl0CiAKbWVyZ2UgOjogT3JkIGEgPT4gW2FdIC0+IFthXSAtPiBbYV0KbWVyZ2UgeHNAKHg6eHQpIHlzQCh5Onl0KSA9IGNhc2UgY29tcGFyZSB4IHkgb2YKICAgIExUIC0+IHggOiBtZXJnZSB4dCB5cwogICAgRVEgLT4geCA6IG1lcmdlIHh0IHl0CiAgICBHVCAtPiB5IDogbWVyZ2UgeHMgeXQKIApkaWZmIHhzQCh4Onh0KSB5c0AoeTp5dCkgPSBjYXNlIGNvbXBhcmUgeCB5IG9mCiAgICBMVCAtPiB4IDogZGlmZiB4dCB5cwogICAgRVEgLT4gICAgIGRpZmYgeHQgeXQKICAgIEdUIC0+ICAgICBkaWZmIHhzIHl0Cgpmb2xkVHJlZSA6OiAoYSAtPiBhIC0+IGEpIC0+IFthXSAtPiBhCmZvbGRUcmVlIGYgeHMgPSBnbyB4cyAtLSAocGFpcnMgeHMpCiAgICB3aGVyZSBwYWlycyB+KHg6IH4oeTp5cykpID0gZiB4IHkgOiBwYWlycyB5cwogICAgICAgICAgZ28gfih4OnpzKSA9IHggYGZgIGdvIChwYWlycyB6cykKICAgICAgICAgIAp3aGVlbCAgICAgID0gMjo0OjI6NDo2OjI6Njo0OjI6NDo2OjY6Mjo2OjQ6Mjo2OjQ6Njo4OjQ6Mjo0OjI6CiAgICAgICAgICAgICAgICAgNDo4OjY6NDo2OjI6NDo2OjI6Njo2OjQ6Mjo0OjY6Mjo2OjQ6Mjo0OjI6MTA6MjoxMDp3aGVlbApyb2xsICAgICAgID0gc2NhbmwgKCspCndoZWVsTnVtcyAgPSByb2xsIDAgd2hlZWwgICAgICAgICAtLSBbMCwyLDYsOCwxMiwxOCwgLi4uXSAKcm9sbEZyb20gbiA9IGdvIHdoZWVsTnVtcyB3aGVlbAogIHdoZXJlIG0gPSAobi0xMSkgYG1vZGAgMjEwCiAgICAgICAgZ28gKHg6eHMpICh3OndzKSA9IGlmIHg9PW0gdGhlbiByb2xsIChuK3cpIHdzIGVsc2UgZ28geHMgd3MKICAgICAgICAgICAgICAgICAgCnByaW1lcyA6OiBbSW50XQpwcmltZXMgICAgPSAyOjM6NTo3OnByaW1lcycKICB3aGVyZQogICAgcHJpbWVzJyA9IGRpZmYgKHJvbGwgMTEgd2hlZWwpIAogICAgICAgICAgICAgICAoIHNlcnZlIC4gZm9sZFRyZWUgbWVyZ2VQIC4gbWFwIG11bHRpcGxlcyAkIHByaW1lc18gKQoKICAgIHByaW1lc18gPSBoICsrIGRpZmYgdAogICAgICAgICAgICAgICAoIHNlcnZlIC4gZm9sZFRyZWUgbWVyZ2VQIC4gbWFwIG11bHRpcGxlcyAkIHByaW1lc18gKQogICAgICAgICAgICAgIHdoZXJlIChoLHQpID0gc3BsaXRBdCA2IChyb2xsIDExIHdoZWVsKSAKCiAgICBtdWx0aXBsZXMgcCA9IC0tIHZpcCAtLSBbcCpxfHE8LVtwLHArMi4uXV0gLS0gW3AqcCxwKnArMipwLi5dCiAgICAgICAgICAgICAgICAgIFZJUCAocCpwKSAkIENyb3dkIFtwKnF8cTwtcm9sbEZyb20gcF0KIAogICAgLS0gdmlwICh4OnhzKSAgICAgICA9IFZJUCB4ICQgQ3Jvd2QgeHMKICAgIHNlcnZlIChWSVAgeCB4cykgPSB4OnNlcnZlIHhzCiAgICBzZXJ2ZSAoQ3Jvd2QgeHMpID0geHM=