module Codeforces.Virtual.RatingCalculator
( calculateContestResults
) where
import Codeforces.Types.Common
import Codeforces.Types.Party hiding ( Contestant )
import Codeforces.Types.Standings
import Codeforces.Virtual.Types
import Control.Monad
import Control.Monad.Trans.State
import Data.Functor ( (<&>) )
import Data.List
import qualified Data.Map as M
import Data.Maybe
import Data.Ord
calculateContestResults
:: M.Map Handle Rating -> [RanklistRow] -> ContestResults
calculateContestResults :: Map Handle Rating -> [RanklistRow] -> ContestResults
calculateContestResults Map Handle Rating
hs [RanklistRow]
rrs = [Contestant]
-> Map Party Rating -> Map Rating Seed -> ContestResults
ContestResults [Contestant]
sortedCs Map Party Rating
deltas Map Rating Seed
seeds
where
sortedCs :: [Contestant]
sortedCs = [Contestant] -> [Contestant]
reassignRanks ([Contestant] -> [Contestant]) -> [Contestant] -> [Contestant]
forall a b. (a -> b) -> a -> b
$ Map Handle Rating -> [RanklistRow] -> [Contestant]
mkContestants Map Handle Rating
hs [RanklistRow]
rrs
(Map Party Rating
deltas, Map Rating Seed
seeds) = [Contestant] -> (Map Party Rating, Map Rating Seed)
process [Contestant]
sortedCs
mkContestants :: M.Map Handle Rating -> [RanklistRow] -> [Contestant]
mkContestants :: Map Handle Rating -> [RanklistRow] -> [Contestant]
mkContestants Map Handle Rating
prevRatings = (RanklistRow -> Contestant) -> [RanklistRow] -> [Contestant]
forall a b. (a -> b) -> [a] -> [b]
map
(\RanklistRow {Seed
Rating
[ProblemResult]
Maybe DiffTime
Party
rrLastSubmissionTime :: RanklistRow -> Maybe DiffTime
rrProblemResults :: RanklistRow -> [ProblemResult]
rrUnsuccessfulHackCount :: RanklistRow -> Rating
rrSuccessfulHackCount :: RanklistRow -> Rating
rrPenalty :: RanklistRow -> Rating
rrPoints :: RanklistRow -> Seed
rrRank :: RanklistRow -> Rating
rrParty :: RanklistRow -> Party
rrLastSubmissionTime :: Maybe DiffTime
rrProblemResults :: [ProblemResult]
rrUnsuccessfulHackCount :: Rating
rrSuccessfulHackCount :: Rating
rrPenalty :: Rating
rrPoints :: Seed
rrRank :: Rating
rrParty :: Party
..} -> Contestant :: Party -> Rating -> Seed -> Rating -> Contestant
Contestant { contestantParty :: Party
contestantParty = Party
rrParty
, contestantRank :: Rating
contestantRank = Rating
rrRank
, contestantPoints :: Seed
contestantPoints = Seed
rrPoints
, contestantRating :: Rating
contestantRating = Party -> Rating
getPartyRating Party
rrParty
}
)
where
getPartyRating :: Party -> Rating
getPartyRating = [Rating] -> Rating
computePartyRating ([Rating] -> Rating) -> (Party -> [Rating]) -> Party -> Rating
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Member -> Rating) -> [Member] -> [Rating]
forall a b. (a -> b) -> [a] -> [b]
map Member -> Rating
lookupRating ([Member] -> [Rating]) -> (Party -> [Member]) -> Party -> [Rating]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Party -> [Member]
partyMembers
lookupRating :: Member -> Rating
lookupRating Member
m = Rating -> Handle -> Map Handle Rating -> Rating
forall k a. Ord k => a -> k -> Map k a -> a
M.findWithDefault Rating
initRating (Member -> Handle
memberHandle Member
m) Map Handle Rating
prevRatings
initRating :: Rating
initRating :: Rating
initRating = Rating
0
computePartyRating :: [Rating] -> Rating
computePartyRating :: [Rating] -> Rating
computePartyRating [Rating]
ratings = Rating -> Seed -> Seed -> Rating
go Rating
20 Seed
100 Seed
4000
where
go :: Int -> Float -> Float -> Rating
go :: Rating -> Seed -> Seed -> Rating
go Rating
0 Seed
l Seed
r = Seed -> Rating
forall a b. (RealFrac a, Integral b) => a -> b
round (Seed -> Rating) -> Seed -> Rating
forall a b. (a -> b) -> a -> b
$ (Seed
l Seed -> Seed -> Seed
forall a. Num a => a -> a -> a
+ Seed
r) Seed -> Seed -> Seed
forall a. Fractional a => a -> a -> a
/ Seed
2
go Rating
i Seed
l Seed
r | Seed
computed Seed -> Seed -> Bool
forall a. Ord a => a -> a -> Bool
> Seed
mid = Rating -> Seed -> Seed -> Rating
go (Rating
i Rating -> Rating -> Rating
forall a. Num a => a -> a -> a
- Rating
1) Seed
mid Seed
r
| Bool
otherwise = Rating -> Seed -> Seed -> Rating
go (Rating
i Rating -> Rating -> Rating
forall a. Num a => a -> a -> a
- Rating
1) Seed
l Seed
mid
where
mid :: Seed
mid = (Seed
l Seed -> Seed -> Seed
forall a. Num a => a -> a -> a
+ Seed
r) Seed -> Seed -> Seed
forall a. Fractional a => a -> a -> a
/ Seed
2
rWinsProbability :: Seed
rWinsProbability =
[Seed] -> Seed
forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
product ([Seed] -> Seed) -> [Seed] -> Seed
forall a b. (a -> b) -> a -> b
$ (Rating -> Seed) -> [Rating] -> [Seed]
forall a b. (a -> b) -> [a] -> [b]
map (Seed -> Seed -> Seed
getEloWinProbability Seed
mid (Seed -> Seed) -> (Rating -> Seed) -> Rating -> Seed
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Rating -> Seed
forall a b. (Integral a, Num b) => a -> b
fromIntegral) [Rating]
ratings
computed :: Seed
computed = Seed -> Seed -> Seed
forall a. Floating a => a -> a -> a
logBase Seed
10 (Seed
1 Seed -> Seed -> Seed
forall a. Fractional a => a -> a -> a
/ Seed
rWinsProbability Seed -> Seed -> Seed
forall a. Num a => a -> a -> a
- Seed
1) Seed -> Seed -> Seed
forall a. Num a => a -> a -> a
* Seed
400 Seed -> Seed -> Seed
forall a. Num a => a -> a -> a
+ Seed
mid
type SeedCache = M.Map Rating Seed
process :: [Contestant] -> (M.Map Party Delta, SeedCache)
process :: [Contestant] -> (Map Party Rating, Map Rating Seed)
process [] = (Map Party Rating
forall k a. Map k a
M.empty, Map Rating Seed
forall k a. Map k a
M.empty)
process [Contestant]
cs = (State (Map Rating Seed) (Map Party Rating)
-> Map Rating Seed -> (Map Party Rating, Map Rating Seed))
-> Map Rating Seed
-> State (Map Rating Seed) (Map Party Rating)
-> (Map Party Rating, Map Rating Seed)
forall a b c. (a -> b -> c) -> b -> a -> c
flip State (Map Rating Seed) (Map Party Rating)
-> Map Rating Seed -> (Map Party Rating, Map Rating Seed)
forall s a. State s a -> s -> (a, s)
runState ([Contestant] -> Map Rating Seed
precomputeSeeds [Contestant]
cs) (State (Map Rating Seed) (Map Party Rating)
-> (Map Party Rating, Map Rating Seed))
-> State (Map Rating Seed) (Map Party Rating)
-> (Map Party Rating, Map Rating Seed)
forall a b. (a -> b) -> a -> b
$ do
Map Party Rating
ds <- [Contestant] -> State (Map Rating Seed) (Map Party Rating)
calculateDeltas [Contestant]
cs
Map Party Rating -> State (Map Rating Seed) (Map Party Rating)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Map Party Rating -> State (Map Rating Seed) (Map Party Rating))
-> (Map Party Rating -> Map Party Rating)
-> Map Party Rating
-> State (Map Rating Seed) (Map Party Rating)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Contestant] -> Map Party Rating -> Map Party Rating
adjustTopDeltas [Contestant]
cs (Map Party Rating -> Map Party Rating)
-> (Map Party Rating -> Map Party Rating)
-> Map Party Rating
-> Map Party Rating
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Map Party Rating -> Map Party Rating
adjustAllDeltas (Map Party Rating -> State (Map Rating Seed) (Map Party Rating))
-> Map Party Rating -> State (Map Rating Seed) (Map Party Rating)
forall a b. (a -> b) -> a -> b
$ Map Party Rating
ds
precomputeSeeds :: [Contestant] -> SeedCache
precomputeSeeds :: [Contestant] -> Map Rating Seed
precomputeSeeds [Contestant]
cs =
[(Rating, Seed)] -> Map Rating Seed
forall k a. Ord k => [(k, a)] -> Map k a
M.fromList ([(Rating, Seed)] -> Map Rating Seed)
-> [(Rating, Seed)] -> Map Rating Seed
forall a b. (a -> b) -> a -> b
$ (Contestant -> (Rating, Seed)) -> [Contestant] -> [(Rating, Seed)]
forall a b. (a -> b) -> [a] -> [b]
map (\Contestant
c -> (Contestant -> Rating
contestantRating Contestant
c, Contestant -> [Contestant] -> Seed
calculateSeedOf Contestant
c [Contestant]
cs)) [Contestant]
cs
adjustAllDeltas :: M.Map Party Delta -> M.Map Party Delta
adjustAllDeltas :: Map Party Rating -> Map Party Rating
adjustAllDeltas Map Party Rating
ds = (Rating -> Rating) -> Map Party Rating -> Map Party Rating
forall a b k. (a -> b) -> Map k a -> Map k b
M.map (Rating -> Rating -> Rating
forall a. Num a => a -> a -> a
+ Rating
inc) Map Party Rating
ds
where inc :: Rating
inc = (Rating -> Rating
forall a. Num a => a -> a
negate ([Rating] -> Rating
forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum (Map Party Rating -> [Rating]
forall k a. Map k a -> [a]
M.elems Map Party Rating
ds)) Rating -> Rating -> Rating
forall a. Integral a => a -> a -> a
`div` Map Party Rating -> Rating
forall k a. Map k a -> Rating
M.size Map Party Rating
ds) Rating -> Rating -> Rating
forall a. Num a => a -> a -> a
- Rating
1
adjustTopDeltas :: [Contestant] -> M.Map Party Delta -> M.Map Party Delta
adjustTopDeltas :: [Contestant] -> Map Party Rating -> Map Party Rating
adjustTopDeltas [Contestant]
cs Map Party Rating
ds = (Rating -> Rating) -> Map Party Rating -> Map Party Rating
forall a b k. (a -> b) -> Map k a -> Map k b
M.map (Rating -> Rating -> Rating
forall a. Num a => a -> a -> a
+ Rating
inc) Map Party Rating
ds
where
inc :: Rating
inc = Rating -> Rating -> Rating
forall a. Ord a => a -> a -> a
min Rating
0 (Rating -> Rating) -> Rating -> Rating
forall a b. (a -> b) -> a -> b
$ Rating -> Rating -> Rating
forall a. Ord a => a -> a -> a
max (-Rating
10) (Rating -> Rating
forall a. Num a => a -> a
negate Rating
sumTopDeltas Rating -> Rating -> Rating
forall a. Integral a => a -> a -> a
`div` Rating
zeroSumCount)
sumTopDeltas :: Rating
sumTopDeltas = [Rating] -> Rating
forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum ([Rating] -> Rating) -> [Rating] -> Rating
forall a b. (a -> b) -> a -> b
$ (Contestant -> Maybe Rating) -> [Contestant] -> [Rating]
forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe ((Party -> Map Party Rating -> Maybe Rating)
-> Map Party Rating -> Party -> Maybe Rating
forall a b c. (a -> b -> c) -> b -> a -> c
flip Party -> Map Party Rating -> Maybe Rating
forall k a. Ord k => k -> Map k a -> Maybe a
M.lookup Map Party Rating
ds (Party -> Maybe Rating)
-> (Contestant -> Party) -> Contestant -> Maybe Rating
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Contestant -> Party
contestantParty)
(Rating -> [Contestant] -> [Contestant]
forall a. Rating -> [a] -> [a]
take Rating
zeroSumCount ([Contestant] -> [Contestant]) -> [Contestant] -> [Contestant]
forall a b. (a -> b) -> a -> b
$ [Contestant] -> [Contestant]
sortByRatingDesc [Contestant]
cs)
zeroSumCount :: Rating
zeroSumCount = Rating -> Rating -> Rating
forall a. Ord a => a -> a -> a
min (Map Party Rating -> Rating
forall k a. Map k a -> Rating
M.size Map Party Rating
ds) Rating
topCount
topCount :: Rating
topCount = Rating
4 Rating -> Rating -> Rating
forall a. Num a => a -> a -> a
* (Double -> Rating
round' (Double -> Rating)
-> (Map Party Rating -> Double) -> Map Party Rating -> Rating
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Double -> Double
forall a. Floating a => a -> a
sqrt (Double -> Double)
-> (Map Party Rating -> Double) -> Map Party Rating -> Double
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Rating -> Double
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Rating -> Double)
-> (Map Party Rating -> Rating) -> Map Party Rating -> Double
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Map Party Rating -> Rating
forall k a. Map k a -> Rating
M.size) Map Party Rating
ds
round' :: Double -> Rating
round' = Double -> Rating
forall a b. (RealFrac a, Integral b) => a -> b
round :: Double -> Int
calculateDeltas :: [Contestant] -> State SeedCache (M.Map Party Delta)
calculateDeltas :: [Contestant] -> State (Map Rating Seed) (Map Party Rating)
calculateDeltas [Contestant]
cs = do
[(Party, Rating)]
deltas <- [Contestant]
-> (Contestant
-> StateT (Map Rating Seed) Identity (Party, Rating))
-> StateT (Map Rating Seed) Identity [(Party, Rating)]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
t a -> (a -> m b) -> m (t b)
forM [Contestant]
cs ((Contestant -> StateT (Map Rating Seed) Identity (Party, Rating))
-> StateT (Map Rating Seed) Identity [(Party, Rating)])
-> (Contestant
-> StateT (Map Rating Seed) Identity (Party, Rating))
-> StateT (Map Rating Seed) Identity [(Party, Rating)]
forall a b. (a -> b) -> a -> b
$ \Contestant
c -> Contestant -> [Contestant] -> State (Map Rating Seed) Rating
calculateDelta Contestant
c [Contestant]
cs State (Map Rating Seed) Rating
-> (Rating -> (Party, Rating))
-> StateT (Map Rating Seed) Identity (Party, Rating)
forall (f :: * -> *) a b. Functor f => f a -> (a -> b) -> f b
<&> (Contestant -> Party
contestantParty Contestant
c, )
Map Party Rating -> State (Map Rating Seed) (Map Party Rating)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Map Party Rating -> State (Map Rating Seed) (Map Party Rating))
-> Map Party Rating -> State (Map Rating Seed) (Map Party Rating)
forall a b. (a -> b) -> a -> b
$ [(Party, Rating)] -> Map Party Rating
forall k a. Ord k => [(k, a)] -> Map k a
M.fromList [(Party, Rating)]
deltas
reassignRanks :: [Contestant] -> [Contestant]
reassignRanks :: [Contestant] -> [Contestant]
reassignRanks = Rating -> Rating -> [Contestant] -> [Contestant]
go Rating
1 Rating
1 ([Contestant] -> [Contestant])
-> ([Contestant] -> [Contestant]) -> [Contestant] -> [Contestant]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Contestant] -> [Contestant]
sortByPointsDesc
where
go :: Rating -> Rating -> [Contestant] -> [Contestant]
go Rating
_ Rating
_ [] = []
go Rating
_ Rating
rank [Contestant
c ] = [Rating -> Contestant -> Contestant
withRank Rating
rank Contestant
c]
go Rating
i Rating
rank (Contestant
c1 : Contestant
c2 : [Contestant]
cs) = Rating -> Contestant -> Contestant
withRank Rating
rank Contestant
c1 Contestant -> [Contestant] -> [Contestant]
forall a. a -> [a] -> [a]
: Rating -> Rating -> [Contestant] -> [Contestant]
go (Rating
i Rating -> Rating -> Rating
forall a. Num a => a -> a -> a
+ Rating
1) Rating
nextRank (Contestant
c2 Contestant -> [Contestant] -> [Contestant]
forall a. a -> [a] -> [a]
: [Contestant]
cs)
where
nextRank :: Rating
nextRank | Contestant -> Seed
contestantPoints Contestant
c2 Seed -> Seed -> Bool
forall a. Ord a => a -> a -> Bool
< Contestant -> Seed
contestantPoints Contestant
c1 = Rating
i Rating -> Rating -> Rating
forall a. Num a => a -> a -> a
+ Rating
1
| Bool
otherwise = Rating
rank
withRank :: Rating -> Contestant -> Contestant
withRank Rating
r Contestant
c = Contestant
c { contestantRank :: Rating
contestantRank = Rating
r }
calculateDelta :: Contestant -> [Contestant] -> State SeedCache Delta
calculateDelta :: Contestant -> [Contestant] -> State (Map Rating Seed) Rating
calculateDelta Contestant
c [Contestant]
cs = do
Seed
mid <- Contestant -> [Contestant] -> State (Map Rating Seed) Seed
midRank Contestant
c [Contestant]
cs
Rating
needRating <- [Contestant] -> Seed -> State (Map Rating Seed) Rating
calculateNeedRating [Contestant]
cs Seed
mid
Rating -> State (Map Rating Seed) Rating
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Rating -> State (Map Rating Seed) Rating)
-> Rating -> State (Map Rating Seed) Rating
forall a b. (a -> b) -> a -> b
$ (Rating
needRating Rating -> Rating -> Rating
forall a. Num a => a -> a -> a
- Contestant -> Rating
contestantRating Contestant
c) Rating -> Rating -> Rating
forall a. Integral a => a -> a -> a
`div` Rating
2
midRank :: Contestant -> [Contestant] -> State SeedCache Seed
midRank :: Contestant -> [Contestant] -> State (Map Rating Seed) Seed
midRank Contestant
c [Contestant]
cs = do
Seed
seed <- Contestant -> [Contestant] -> State (Map Rating Seed) Seed
getSeedOf Contestant
c [Contestant]
cs
Seed -> State (Map Rating Seed) Seed
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Seed -> State (Map Rating Seed) Seed)
-> Seed -> State (Map Rating Seed) Seed
forall a b. (a -> b) -> a -> b
$ Seed -> Seed
forall a. Floating a => a -> a
sqrt (Seed -> Seed) -> Seed -> Seed
forall a b. (a -> b) -> a -> b
$ Rating -> Seed
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Contestant -> Rating
contestantRank Contestant
c) Seed -> Seed -> Seed
forall a. Num a => a -> a -> a
* Seed
seed
calculateNeedRating :: [Contestant] -> Float -> State SeedCache Rating
calculateNeedRating :: [Contestant] -> Seed -> State (Map Rating Seed) Rating
calculateNeedRating [Contestant]
cs Seed
rank = Rating -> Rating -> State (Map Rating Seed) Rating
go Rating
1 Rating
8000
where
go :: Rating -> Rating -> State (Map Rating Seed) Rating
go Rating
l Rating
r
| Rating
r Rating -> Rating -> Rating
forall a. Num a => a -> a -> a
- Rating
l Rating -> Rating -> Bool
forall a. Ord a => a -> a -> Bool
<= Rating
1 = Rating -> State (Map Rating Seed) Rating
forall (f :: * -> *) a. Applicative f => a -> f a
pure Rating
l
| Bool
otherwise = do
let mid :: Rating
mid = (Rating
l Rating -> Rating -> Rating
forall a. Num a => a -> a -> a
+ Rating
r) Rating -> Rating -> Rating
forall a. Integral a => a -> a -> a
`div` Rating
2
Seed
seed <- Rating -> [Contestant] -> State (Map Rating Seed) Seed
getSeed Rating
mid [Contestant]
cs
if Seed
seed Seed -> Seed -> Bool
forall a. Ord a => a -> a -> Bool
< Seed
rank then Rating -> Rating -> State (Map Rating Seed) Rating
go Rating
l Rating
mid else Rating -> Rating -> State (Map Rating Seed) Rating
go Rating
mid Rating
r
getSeed :: Rating -> [Contestant] -> State SeedCache Seed
getSeed :: Rating -> [Contestant] -> State (Map Rating Seed) Seed
getSeed Rating
rating [Contestant]
cs = do
Map Rating Seed
cache <- StateT (Map Rating Seed) Identity (Map Rating Seed)
forall (m :: * -> *) s. Monad m => StateT s m s
get
case Rating -> Map Rating Seed -> Maybe Seed
forall k a. Ord k => k -> Map k a -> Maybe a
M.lookup Rating
rating Map Rating Seed
cache of
Maybe Seed
Nothing -> do
let seed :: Seed
seed = Rating -> [Contestant] -> Seed
calculateSeed Rating
rating [Contestant]
cs
(Map Rating Seed -> Map Rating Seed)
-> StateT (Map Rating Seed) Identity ()
forall (m :: * -> *) s. Monad m => (s -> s) -> StateT s m ()
modify ((Map Rating Seed -> Map Rating Seed)
-> StateT (Map Rating Seed) Identity ())
-> (Map Rating Seed -> Map Rating Seed)
-> StateT (Map Rating Seed) Identity ()
forall a b. (a -> b) -> a -> b
$ Rating -> Seed -> Map Rating Seed -> Map Rating Seed
forall k a. Ord k => k -> a -> Map k a -> Map k a
M.insert Rating
rating Seed
seed
Seed -> State (Map Rating Seed) Seed
forall (f :: * -> *) a. Applicative f => a -> f a
pure Seed
seed
(Just Seed
seed) -> Seed -> State (Map Rating Seed) Seed
forall (f :: * -> *) a. Applicative f => a -> f a
pure Seed
seed
getSeedOf :: Contestant -> [Contestant] -> State SeedCache Seed
getSeedOf :: Contestant -> [Contestant] -> State (Map Rating Seed) Seed
getSeedOf Contestant
x [Contestant]
ys = Rating -> [Contestant] -> State (Map Rating Seed) Seed
getSeed (Contestant -> Rating
contestantRating Contestant
x) ((Contestant -> Bool) -> [Contestant] -> [Contestant]
forall a. (a -> Bool) -> [a] -> [a]
filter (Contestant -> Contestant -> Bool
forall a. Eq a => a -> a -> Bool
/= Contestant
x) [Contestant]
ys)
calculateSeed :: Rating -> [Contestant] -> Seed
calculateSeed :: Rating -> [Contestant] -> Seed
calculateSeed Rating
rating [Contestant]
others =
Seed
1 Seed -> Seed -> Seed
forall a. Num a => a -> a -> a
+ [Seed] -> Seed
forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum [ Rating -> Rating -> Seed
getEloWinProbability' (Contestant -> Rating
contestantRating Contestant
x) Rating
rating | Contestant
x <- [Contestant]
others ]
calculateSeedOf :: Contestant -> [Contestant] -> Seed
calculateSeedOf :: Contestant -> [Contestant] -> Seed
calculateSeedOf Contestant
x [Contestant]
ys = Rating -> [Contestant] -> Seed
calculateSeed (Contestant -> Rating
contestantRating Contestant
x) ((Contestant -> Bool) -> [Contestant] -> [Contestant]
forall a. (a -> Bool) -> [a] -> [a]
filter (Contestant -> Contestant -> Bool
forall a. Eq a => a -> a -> Bool
/= Contestant
x) [Contestant]
ys)
getEloWinProbability :: Float -> Float -> Float
getEloWinProbability :: Seed -> Seed -> Seed
getEloWinProbability Seed
x Seed
y = Seed
1 Seed -> Seed -> Seed
forall a. Fractional a => a -> a -> a
/ (Seed
1 Seed -> Seed -> Seed
forall a. Num a => a -> a -> a
+ Seed
10 Seed -> Seed -> Seed
forall a. Floating a => a -> a -> a
** ((Seed
y Seed -> Seed -> Seed
forall a. Num a => a -> a -> a
- Seed
x) Seed -> Seed -> Seed
forall a. Fractional a => a -> a -> a
/ Seed
400))
getEloWinProbability' :: Rating -> Rating -> Float
getEloWinProbability' :: Rating -> Rating -> Seed
getEloWinProbability' Rating
x = Seed -> Seed -> Seed
getEloWinProbability (Rating -> Seed
forall a b. (Integral a, Num b) => a -> b
fromIntegral Rating
x) (Seed -> Seed) -> (Rating -> Seed) -> Rating -> Seed
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Rating -> Seed
forall a b. (Integral a, Num b) => a -> b
fromIntegral
sortByPointsDesc :: [Contestant] -> [Contestant]
sortByPointsDesc :: [Contestant] -> [Contestant]
sortByPointsDesc = (Contestant -> Down Seed) -> [Contestant] -> [Contestant]
forall b a. Ord b => (a -> b) -> [a] -> [a]
sortOn (Seed -> Down Seed
forall a. a -> Down a
Down (Seed -> Down Seed)
-> (Contestant -> Seed) -> Contestant -> Down Seed
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Contestant -> Seed
contestantPoints)
sortByRatingDesc :: [Contestant] -> [Contestant]
sortByRatingDesc :: [Contestant] -> [Contestant]
sortByRatingDesc = (Contestant -> Down Rating) -> [Contestant] -> [Contestant]
forall b a. Ord b => (a -> b) -> [a] -> [a]
sortOn (Rating -> Down Rating
forall a. a -> Down a
Down (Rating -> Down Rating)
-> (Contestant -> Rating) -> Contestant -> Down Rating
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Contestant -> Rating
contestantRating)