Skip to content

Instantly share code, notes, and snippets.

@mvaldesdeleon
Last active August 21, 2020 21:21
Show Gist options
  • Save mvaldesdeleon/8573f43f5f1d2ff2aec75a753c063979 to your computer and use it in GitHub Desktop.
Save mvaldesdeleon/8573f43f5f1d2ff2aec75a753c063979 to your computer and use it in GitHub Desktop.
type Score = Int
type Rank = Int
climbingLeaderboard :: [Score] -> [Score] -> [Rank]
climbingLeaderboard scores alice = let scoreRank = denseRank scores
aliceDesc = reverse alice
in reverse (rankSeries scoreRank aliceDesc)
denseRank :: [Score] -> [(Rank, Score)]
denseRank scores = go scores 1
where
go [] _ = []
go [score] rank = [(rank, score)]
go (score1:score2:scoreTail) rank = let nextRank = if score1 == score2 then rank else rank + 1
in (rank, score1) : go (score2:scoreTail) nextRank
rankSeries :: [(Rank, Score)] -> [Score] -> [Rank]
rankSeries [] _ = error "Impossible state"
rankSeries _ [] = []
rankSeries scoreRank@((rank, rankScore):rankTail) scores@(score:scoreTail)
| score >= rankScore = rank : rankSeries scoreRank scoreTail
| score < rankScore = if null rankTail then map (\_ -> rank + 1) scores
else rankSeries rankTail scores
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment