Ranking methods

From Rosetta Code
Task
Ranking methods
You are encouraged to solve this task according to the task description, using any language you may know.

The numerical rank of competitors in a competition shows if one is better than, equal to, or worse than another based on their results in a competition.

The numerical rank of a competitor can be assigned in several different ways.


Task

The following scores are accrued for all competitors of a competition (in best-first order):

44 Solomon
42 Jason
42 Errol
41 Garry
41 Bernard
41 Barry
39 Stephen

For each of the following ranking methods, create a function/method/procedure/subroutine... that applies the ranking method to an ordered list of scores with scorers:

  1. Standard. (Ties share what would have been their first ordinal number).
  2. Modified. (Ties share what would have been their last ordinal number).
  3. Dense. (Ties share the next available integer).
  4. Ordinal. ((Competitors take the next available integer. Ties are not treated otherwise).
  5. Fractional. (Ties share the mean of what would have been their ordinal numbers).


See the wikipedia article for a fuller description.

Show here, on this page, the ranking of the test scores under each of the numbered ranking methods.

11l

Translation of: Python
F mc_rank([(Int, String)] iterable)
   ‘Modified competition ranking’
   [(Float, (Int, String))] r
   V lastresult = -1
   [(Int, String)] fifo
   L(item) iterable
      I item[0] == lastresult
         fifo [+]= item
      E
         V n = L.index
         L !fifo.empty
            r.append((n, fifo.pop(0)))
         lastresult = item[0]
         fifo [+]= item
   L !fifo.empty
      r.append((iterable.len, fifo.pop(0)))
   R r

F sc_rank([(Int, String)] iterable)
   ‘Standard competition ranking’
   [(Float, (Int, String))] r
   V lastresult = -1
   V lastrank = -1
   L(item) iterable
      I item[0] == lastresult
         r.append((lastrank, item))
      E
         V n = L.index + 1
         r.append((n, item))
         lastresult = item[0]
         lastrank = n
   R r

F d_rank([(Int, String)] iterable)
   ‘Dense ranking’
   [(Float, (Int, String))] r
   V lastresult = -1
   V lastrank = 0
   L(item) iterable
      I item[0] == lastresult
         r.append((lastrank, item))
      E
         lastresult = item[0]
         lastrank++
         r.append((lastrank, item))
   R r

F o_rank([(Int, String)] iterable)
   ‘Ordinal ranking’
   R enumerate(iterable, 1).map((i, item) -> ((Float(i), item)))

F f_rank([(Int, String)] iterable)
   ‘Fractional ranking’
   [(Float, (Int, String))] r
   V last = -1
   [(Int, (Int, String))] fifo
   L(item) iterable
      I item[0] != last
         I !fifo.empty
            V mean = Float(sum(fifo.map(f -> f[0]))) / fifo.len
            L !fifo.empty
               r.append((mean, fifo.pop(0)[1]))
      last = item[0]
      fifo.append((L.index + 1, item))
   I !fifo.empty
      V mean = sum(fifo.map(f -> f[0])) / fifo.len
      L !fifo.empty
         r.append((mean, fifo.pop(0)[1]))
   R r

V scores = [(44, ‘Solomon’),
            (42, ‘Jason’),
            (42, ‘Errol’),
            (41, ‘Garry’),
            (41, ‘Bernard’),
            (41, ‘Barry’),
            (39, ‘Stephen’)]

print("\nScores to be ranked (best first):")
L(n, s) scores
   print(‘        #2 #.’.format(n, s))

L(ranker, ranking_method) [(sc_rank, ‘Standard competition ranking’),
                           (mc_rank, ‘Modified competition ranking’),
                            (d_rank, ‘Dense ranking’),
                            (o_rank, ‘Ordinal ranking’),
                            (f_rank, ‘Fractional ranking’)]
   print("\n#.:".format(ranking_method))
   L(rank, score) ranker(scores)
      print(‘  #3, (#., #.)’.format(rank, score[0], score[1]))
Output:

Scores to be ranked (best first):
        44 Solomon
        42 Jason
        42 Errol
        41 Garry
        41 Bernard
        41 Barry
        39 Stephen

Standard competition ranking:
    1, (44, Solomon)
    2, (42, Jason)
    2, (42, Errol)
    4, (41, Garry)
    4, (41, Bernard)
    4, (41, Barry)
    7, (39, Stephen)

Modified competition ranking:
    1, (44, Solomon)
    3, (42, Jason)
    3, (42, Errol)
    6, (41, Garry)
    6, (41, Bernard)
    6, (41, Barry)
    7, (39, Stephen)

Dense ranking:
    1, (44, Solomon)
    2, (42, Jason)
    2, (42, Errol)
    3, (41, Garry)
    3, (41, Bernard)
    3, (41, Barry)
    4, (39, Stephen)

Ordinal ranking:
    1, (44, Solomon)
    2, (42, Jason)
    3, (42, Errol)
    4, (41, Garry)
    5, (41, Bernard)
    6, (41, Barry)
    7, (39, Stephen)

Fractional ranking:
    1, (44, Solomon)
  2.5, (42, Jason)
  2.5, (42, Errol)
    5, (41, Garry)
    5, (41, Bernard)
    5, (41, Barry)
    7, (39, Stephen)

ALGOL 68

As with some but not all of the other samples, the ranking procedures here assume the data is already sorted. The procedures do check for empty data sets, though.

BEGIN # rank some scores by various methods                                   #
    # MODE to hold the scores                                                 #
    MODE RESULT = STRUCT( INT score, STRING name );
    # returns the standard ranking of s                                       #
    PROC standard ranking = ( []RESULT s )[]INT:
         IF LWB s > UPB s THEN []INT() # no scores                            #
         ELSE                          # have some scores                     #
            [ LWB s : UPB s ]INT ranked;
            INT position := 1;
            ranked[ LWB s ] := position;
            FOR i FROM LWB s + 1 TO UPB s DO
                ranked[ i ] := IF score OF s[ i ] = score OF s[ i - 1 ] THEN
                                   # same score as the previous               #
                                   position
                               ELSE
                                   # different score, increase the position   #
                                   position := i
                               FI
            OD;
            ranked
         FI # standard ranking # ;
    # returns the modified ranking of s                                       #
    PROC modified ranking = ( []RESULT s )[]INT:
         IF LWB s > UPB s THEN []INT() # no scores                            #
         ELSE                          # have some scores                     #
            [ LWB s : UPB s ]INT ranked;
            INT position := ( UPB s + 1 ) - LWB s;
            ranked[ UPB s ] := position;
            FOR i FROM UPB s - 1 BY -1 TO LWB s DO
                ranked[ i ] := IF score OF s[ i ] = score OF s[ i + 1 ] THEN
                                   # same score as the previous               #
                                   position
                               ELSE
                                   # different score, decrease the position   #
                                   position := i
                               FI
            OD;
            ranked
         FI # modified ranking # ;
    # returns the debse ranking of s                                          #
    PROC dense ranking = ( []RESULT s )[]INT:
         IF LWB s > UPB s THEN []INT() # no scores                            #
         ELSE                          # have some scores                     #
            [ LWB s : UPB s ]INT ranked;
            INT position := 1;
            ranked[ LWB s ] := position;
            FOR i FROM LWB s + 1 TO UPB s DO
                ranked[ i ] := IF score OF s[ i ] = score OF s[ i - 1 ] THEN
                                   # same score as the previous               #
                                   position
                               ELSE
                                   # different score, increase the position   #
                                   position +:= 1
                               FI
            OD;
            ranked
         FI # dense ranking # ;
    # returns the ordinal ranking of s                                        #
    PROC ordinal ranking = ( []RESULT s )[]INT:
         IF LWB s > UPB s THEN []INT() # no scores                            #
         ELSE                          # have some scores                     #
            [ LWB s : UPB s ]INT ranked;
            INT position := 0;
            FOR i FROM LWB s TO UPB s DO
                ranked[ i ] := position +:= 1
            OD;
            ranked
         FI # ordinal ranking # ;
    # regturns the fractional ranking of s                                    #
    PROC fractional ranking = ( []RESULT s )[]REAL:
         IF LWB s > UPB s THEN []REAL() # no scores                           #
         ELSE                          # have some scores                     #
            [ LWB s : UPB s ]REAL ranked;
            REAL position := 1;
            FOR i FROM LWB s TO UPB s DO
                ranked[ i ]
                    := IF IF   i = LWB s
                          THEN FALSE
                          ELSE score OF s[ i ] = score OF s[ i - 1 ]
                          FI
                       THEN
                           # same score as the previous                       #
                           ranked[ i - 1 ]
                       ELSE
                           # first score or different score to the previous   #
                           INT same count := 1;
                           INT sum        := i;
                           FOR j FROM i + 1 TO UPB s
                           WHILE score OF s[ i ] = score OF s[ j ]
                           DO
                               same count +:= 1;
                               sum        +:= j
                           OD;
                           sum / same count
                       FI
            OD;
            ranked
         FI # fractional ranking # ;
    # shows the integer ranking of some scores                                #
    PROC show integral ranking = ( []RESULT s, []INT ranking, STRING title )VOID:
         BEGIN
            print( ( title, " competition ranking:", newline ) );
            FOR i FROM LWB s TO UPB s DO
                print( ( whole( ranking[ i ], -3 )
                       , ": "
                       , whole( score OF s[ i ], -3 )
                       , " "
                       , name OF s[ i ]
                       , newline
                       )
                     )
            OD;
            print( ( newline ) )
         END # show integral ranking # ;
    # shows the real ranking of some scores                                   #
    PROC show real ranking = ( []RESULT s, []REAL ranking, STRING title )VOID:
         BEGIN
            print( ( title, " competition ranking:", newline ) );
            FOR i FROM LWB s TO UPB s DO
                print( ( IF INT integer rank = ENTIER ranking[ i ];
                            integer rank = ranking[ i ]
                         THEN
                             whole( integer rank, -3 ) + "   "
                         ELSE
                             fixed( ranking[ i ], -6, 2 )
                         FI
                       , ": "
                       , whole( score OF s[ i ], -3 ), " "
                       , name OF s[ i ]
                       , newline
                       )
                     )
            OD;
            print( ( newline ) )
         END # show real ranking # ;

    # scores to rank - task test cases                                        #
    []RESULT scores = ( ( 44, "Solomon" )
                      , ( 42, "Jason"   )
                      , ( 42, "Errol"   )
                      , ( 41, "Garry"   )
                      , ( 41, "Bernard" )
                      , ( 41, "Barry"   )
                      , ( 39, "Stephen" )
                      );
    show integral ranking( scores,   standard ranking( scores ), "standard"   );
    show integral ranking( scores,   modified ranking( scores ), "modified"   );
    show integral ranking( scores,      dense ranking( scores ), "dense"      );
    show integral ranking( scores,    ordinal ranking( scores ), "ordinal"    );
    show real ranking(     scores, fractional ranking( scores ), "fractional" )

END
Output:
standard competition ranking:
  1:  44 Solomon
  2:  42 Jason
  2:  42 Errol
  4:  41 Garry
  4:  41 Bernard
  4:  41 Barry
  7:  39 Stephen

modified competition ranking:
  1:  44 Solomon
  3:  42 Jason
  3:  42 Errol
  6:  41 Garry
  6:  41 Bernard
  6:  41 Barry
  7:  39 Stephen

dense competition ranking:
  1:  44 Solomon
  2:  42 Jason
  2:  42 Errol
  3:  41 Garry
  3:  41 Bernard
  3:  41 Barry
  4:  39 Stephen

ordinal competition ranking:
  1:  44 Solomon
  2:  42 Jason
  3:  42 Errol
  4:  41 Garry
  5:  41 Bernard
  6:  41 Barry
  7:  39 Stephen

fractional competition ranking:
  1   :  44 Solomon
  2.50:  42 Jason
  2.50:  42 Errol
  5   :  41 Garry
  5   :  41 Bernard
  5   :  41 Barry
  7   :  39 Stephen

AppleScript

use AppleScript version "2.3.1" -- Mac OS 10.9 (Mavericks) or later.
use sorter : script ¬
    "Custom Iterative Ternary Merge Sort" -- <www.macscripter.net/t/timsort-and-nigsort/71383/3>

(* The ranking methods are implemented as script objects sharing inherited code. *)
script standardRanking
    -- Properties and handlers inherited or overridden by the other script objects.
    -- The 'reference' is to a value that won't exist until 'results' is set to a list.
    -- 'me' and 'my' pertain to the script object using the code at the time.
    property results : missing value
    property startIndex : 1
    property endIndex : a reference to my results's length
    property step : 1
    property currentRank : missing value
    property currentScore : missing value
    
    -- Main handler.
    on resultsFrom(theScores)
        copy theScores to my results
        tell sorter to sort(my results, my startIndex, my endIndex, {comparer:me})
        set my currentScore to my results's item (my startIndex)'s score
        set my currentRank to my startIndex's contents
        repeat with i from (my startIndex) to (my endIndex) by (my step)
            my rankResult(i)
        end repeat
        set r to my results
        set my results to missing value
        return r
    end resultsFrom
    
    -- Comparison handler used by the sort.
    on isGreater(a, b)
        if (a's score < b's score) then return true
        return ((a's score = b's score) and (a's competitor comes after b's competitor))
    end isGreater
    
    -- Ranking handler. Inherited by the modifiedRanking script; overridden by the others.
    on rankResult(i)
        set thisResult to my results's item i
        set thisScore to thisResult's score
        if (thisScore is not currentScore) then
            set my currentRank to i
            set my currentScore to thisScore
        end if
        set my results's item i to thisResult & {rank:my currentRank}
    end rankResult
end script

script modifiedRanking
    property parent : standardRanking
    property startIndex : a reference to my results's length
    property endIndex : 1
    property step : -1
end script

script denseRanking
    property parent : standardRanking
    
    on rankResult(i)
        set thisResult to my results's item i
        set thisScore to thisResult's score
        if (thisScore is not my currentScore) then
            set my currentRank to (my currentRank) + 1
            set my currentScore to thisScore
        end if
        set my results's item i to thisResult & {rank:my currentRank}
    end rankResult
end script

script ordinalRanking
    property parent : standardRanking
    
    on rankResult(i)
        set my results's item i to (my results's item i) & {rank:i}
    end rankResult
end script

script fractionalRanking
    property parent : standardRanking
    
    on rankResult(i)
        set thisResult to my results's item i
        set thisScore to thisResult's score
        if (thisScore is not my currentScore) then
            -- The average of any run of consecutive integers is that of the first and last.
            set average to (i - 1 + (my currentRank)) / 2
            repeat with j from (my currentRank) to (i - 1)
                set my results's item j's rank to average
            end repeat
            set my currentRank to i
            set my currentScore to thisScore
        end if
        set my results's item i to thisResult & {rank:i as real}
    end rankResult
end script

-- Task code:
on formatRankings(type, theResults)
    set rankings to {type}
    repeat with thisResult in theResults
        set end of rankings to (thisResult's rank as text) & tab & ¬
            thisResult's competitor & " (" & thisResult's score & ")"
    end repeat
    
    return join(rankings, linefeed)
end formatRankings

on join(lst, delim)
    set astid to AppleScript's text item delimiters
    set AppleScript's text item delimiters to delim
    set txt to lst as text
    set AppleScript's text item delimiters to astid
    return txt
end join

local theScores, output
set theScores to {{score:44, competitor:"Solomon"}, {score:42, competitor:"Jason"}, ¬
    {score:42, competitor:"Errol"}, {score:41, competitor:"Garry"}, {score:41, competitor:"Bernard"}, ¬
    {score:41, competitor:"Barry"}, {score:39, competitor:"Stephen"}}
set output to {¬
    formatRankings("Standard ranking:", standardRanking's resultsFrom(theScores)), ¬
    formatRankings("Modified ranking:", modifiedRanking's resultsFrom(theScores)), ¬
    formatRankings("Dense ranking:", denseRanking's resultsFrom(theScores)), ¬
    formatRankings("Ordinal ranking:", ordinalRanking's resultsFrom(theScores)), ¬
    formatRankings("Fractional ranking:", fractionalRanking's resultsFrom(theScores)) ¬
        }
return join(output, linefeed & linefeed)
Output:
"Standard ranking:
1	Solomon (44)
2	Errol (42)
2	Jason (42)
4	Barry (41)
4	Bernard (41)
4	Garry (41)
7	Stephen (39)

Modified ranking:
1	Solomon (44)
3	Errol (42)
3	Jason (42)
6	Barry (41)
6	Bernard (41)
6	Garry (41)
7	Stephen (39)

Dense ranking:
1	Solomon (44)
2	Errol (42)
2	Jason (42)
3	Barry (41)
3	Bernard (41)
3	Garry (41)
4	Stephen (39)

Ordinal ranking:
1	Solomon (44)
2	Errol (42)
3	Jason (42)
4	Barry (41)
5	Bernard (41)
6	Garry (41)
7	Stephen (39)

Fractional ranking:
1.0	Solomon (44)
2.5	Errol (42)
2.5	Jason (42)
5.0	Barry (41)
5.0	Bernard (41)
5.0	Garry (41)
7.0	Stephen (39)"

AutoHotkey

Rank(data, opt:=1){ ; opt = 1 Standard (default), 2 Modified, 3 Dense, 4 Ordinal, 5 Fractional
	for index, val in StrSplit(data, "`n", "`r") {
		RegExMatch(val, "^(\d+)\s+(.*)", Match)
		if !(Match1=prev)
			n := index
		prev := Match1
		Res1 .= n "`t" Match "`n"
		Res4 .= index "`t" Match "`n"
		Temp .= n ":" index " " Match "`n"
	}
	n:=0
	while pos := RegExMatch(Temp, "`asm)^(\d+).*?\R(?!\1)|.+", Match, pos?pos+StrLen(Match):1) {
		n += StrSplit(Trim(Match, "`r`n"), "`n", "`r").MaxIndex()
		Res2 .= RegExReplace(Match, "`am)^\d+:\d+", n "`t")
		Res3 .= RegExReplace(Match, "`am)^\d+:\d+", A_Index "`t")
		R := 0
		for index, val in StrSplit(Match, "`n", "`r")
			R += StrSplit(val, ":").2
		Res5 .= RegExReplace(Match, "`am)^\d+:\d+", RegExReplace(R / StrSplit(Trim(Match, "`r`n"), "`n", "`r").MaxIndex(), "\.?0+$") "`t")
	}
	return Res%opt%
}
Example:
data =
(
44 Solomon
42 Jason
42 Errol
41 Garry
41 Bernard
41 Barry
39 Stephen
)

MsgBox, 262144, ,% "" 
. "Standard Ranking:`n"		Rank(data)
. "`nModified Ranking:`n"	Rank(data, 2)
. "`nDense Ranking:`n" 		Rank(data, 3)
. "`nOrdinal Ranking:`n" 	Rank(data, 4)
. "`nFractional Ranking:`n"	Rank(data, 5)
return
Output:
Standard Ranking:
1	44 Solomon
2	42 Jason
2	42 Errol
4	41 Garry
4	41 Bernard
4	41 Barry
7	39 Stephen

Modified Ranking:
1	 44 Solomon
3	 42 Jason
3	 42 Errol
6	 41 Garry
6	 41 Bernard
6	 41 Barry
7	 39 Stephen

Dense Ranking:
1	 44 Solomon
2	 42 Jason
2	 42 Errol
3	 41 Garry
3	 41 Bernard
3	 41 Barry
4	 39 Stephen

Ordinal Ranking:
1	44 Solomon
2	42 Jason
3	42 Errol
4	41 Garry
5	41 Bernard
6	41 Barry
7	39 Stephen

Fractional Ranking:
1	 44 Solomon
2.5	 42 Jason
2.5	 42 Errol
5	 41 Garry
5	 41 Bernard
5	 41 Barry
7	 39 Stephen

APL

Works with: Dyalog APL

These functions each take a 2-by-N matrix, where the first column contains the score, and the second column contains the name. They return a 3-by-N matrix, with the ranking added.

standard    (⊢⊂⍳)(1,2/)(1[2]),⊢
modified    (\∘¨⊢⊂⍳)(1,2/)(1[2]),⊢
dense       (+\1,2/1[2]),⊢
ordinal     ≢,⊢
fractional  (((/∘)+/÷≢)¨⊢⊂⍳)(1,2/)(1[2]),⊢
Output:
      ⍝ Input scores table from task:
      scores←⍉⍪44,⊂'Solomon'
      scores⍪←42,⊂'Jason'
      scores⍪←42,⊂'Errol'
      scores⍪←41,⊂'Garry'
      scores⍪←41,⊂'Bernard'
      scores⍪←41,⊂'Barry'
      scores⍪←39,⊂'Stephen'
      
      ⍝ Apply each function to it
      standard scores
1 44  Solomon 
2 42  Jason   
2 42  Errol   
4 41  Garry   
4 41  Bernard 
4 41  Barry   
7 39  Stephen 
      
      modified scores
1 44  Solomon 
3 42  Jason   
3 42  Errol   
6 41  Garry   
6 41  Bernard 
6 41  Barry   
7 39  Stephen 
      
      dense scores
1 44  Solomon 
2 42  Jason   
2 42  Errol   
3 41  Garry   
3 41  Bernard 
3 41  Barry   
4 39  Stephen 
      
      ordinal scores
1 44  Solomon 
2 42  Jason   
3 42  Errol   
4 41  Garry   
5 41  Bernard 
6 41  Barry   
7 39  Stephen 
      
      fractional scores
1   44  Solomon 
2.5 42  Jason   
2.5 42  Errol   
5   41  Garry   
5   41  Bernard 
5   41  Barry   
7   39  Stephen 

AWK

Translation of: Python

This uses separate files for each method of ranking:

##
## Dense ranking in file: ranking_d.awk
##

BEGIN{ lastresult = "!"; lastrank = 0 }

function d_rank(){
    if($1==lastresult){
        print lastrank, $0
    }else{
        lastresult = $1
        print ++lastrank, $0 }
}
//{d_rank() }

##
## Fractional ranking in file: ranking_f.awk
##

BEGIN{
    last = "!"
    flen = 0 }

function f_rank(){
    item = $0
    if($1!=last){
        if(flen){
            sum = 0
            for(fl=0; fl < flen;){
                $0 = fifo[fl++]
                sum += $1 }
            mean = sum / flen
            for(fl=0; fl < flen;){
                $0 = fifo[fl++]
                $1 = ""
                printf("%3g %s\n", mean, $0) }
            flen = 0
    }}
    $0 = item
    last = $1
    fifo[flen++] = sprintf("%i %s", FNR, item)
}
//{f_rank()}

END{ if(flen){
        sum = 0
        for(fl=0; fl < flen;){
            $0 = fifo[fl++]
            sum += $1 }
        mean = sum / flen
        for(fl=0; fl < flen;){
            $0 = fifo[fl++]
            $1 = ""
            printf("%3g %s\n", mean, $0) }}}

##
## Modified competition ranking in file: ranking_mc.awk
##

BEGIN{
    lastresult = "!"
    flen = 0 }

function mc_rank(){
    if($1==lastresult){
        fifo[flen++] = $0
    }else{
        for(fl=0; fl < flen;){
            print FNR-1, fifo[fl++]}
        flen = 0
        fifo[flen++] = $0
        lastresult = $1}
}
//{mc_rank()}

END{ for(fl=0; fl < flen;){
        print FNR, fifo[fl++]} }

##
## Ordinal ranking in file: ranking_o.awk
##

function o_rank(){ print FNR, $0 }
//{o_rank() }

##
## Standard competition ranking in file: ranking_sc.awk
##

BEGIN{ lastresult = lastrank = "!" }

function sc_rank(){
    if($1==lastresult){
        print lastrank, $0
    }else{
        print FNR, $0
        lastresult = $1
        lastrank = FNR}
}
//{sc_rank()}

The input as a file ranking.txt:

44 Solomon
42 Jason
42 Errol
41 Garry
41 Bernard
41 Barry
39 Stephen
Output:
C:\Users\RC\Code>awk -f ranking_sc.awk ranking.txt
1 44 Solomon
2 42 Jason
2 42 Errol
4 41 Garry
4 41 Bernard
4 41 Barry
7 39 Stephen

C:\Users\RC\Code>awk -f ranking_mc.awk ranking.txt
1 44 Solomon
3 42 Jason
3 42 Errol
6 41 Garry
6 41 Bernard
6 41 Barry
7 39 Stephen

C:\Users\RC\Code>awk -f ranking_d.awk ranking.txt
1 44 Solomon
2 42 Jason
2 42 Errol
3 41 Garry
3 41 Bernard
3 41 Barry
4 39 Stephen

C:\Users\RC\Code>awk -f ranking_o.awk ranking.txt
1 44 Solomon
2 42 Jason
3 42 Errol
4 41 Garry
5 41 Bernard
6 41 Barry
7 39 Stephen

C:\Users\RC\Code>awk -f ranking_f.awk ranking.txt
  1  44 Solomon
2.5  42 Jason
2.5  42 Errol
  5  41 Garry
  5  41 Bernard
  5  41 Barry
  7  39 Stephen

C:\Users\RC\Code>

BASIC

10 READ N
20 DIM S(N),N$(N),R(N)
30 FOR I=1 TO N: READ S(I),N$(I): NEXT
40 PRINT "--- Standard ranking ---": GOSUB 100: GOSUB 400
50 PRINT "--- Modified ranking ---": GOSUB 150: GOSUB 400
60 PRINT "--- Dense ranking ---": GOSUB 200: GOSUB 400
70 PRINT "--- Ordinal ranking ---": GOSUB 250: GOSUB 400
80 PRINT "--- Fractional ranking ---": GOSUB 300: GOSUB 400
90 END
100 REM
101 REM ** Ordinal ranking **
110 R(1)=1
120 FOR I=2 TO N
130 IF S(I)=S(I-1) THEN R(I)=R(I-1) ELSE R(I)=I
140 NEXT: RETURN
150 REM
151 REM ** Modified ranking **
160 R(N)=N
170 FOR I=N-1 TO 1 STEP -1
180 IF S(I)=S(I+1) THEN R(I)=R(I+1) ELSE R(I)=I
190 NEXT: RETURN
200 REM
201 REM ** Dense ranking **
210 R(1)=1
220 FOR I=2 TO N: R(I)=R(I-1)-(S(I)<>S(I-1)): NEXT
230 RETURN
250 REM
251 REM ** Ordinal ranking **
260 FOR I=1 TO N: R(I)=I: NEXT: RETURN
300 REM
301 REM ** Fractional ranking **
310 I=1: J=2
320 IF J<=N THEN IF S(J-1)=S(J) THEN J=J+1: GOTO 320
330 FOR K=I TO J-1: R(K) = (I+J-1)/2: NEXT
340 I=J: J=J+1: IF I<=N THEN 320
350 RETURN
400 REM
401 REM ** Print the table ***
410 FOR I=1 TO N
420 PRINT USING "\  \ ##, \        \";STR$(R(I));S(I);N$(I)
430 NEXT
440 PRINT: RETURN
500 DATA 7
510 DATA 44,Solomon
520 DATA 42,Jason
530 DATA 42,Errol
540 DATA 41,Garry
550 DATA 41,Bernard
560 DATA 41,Barry
570 DATA 39,Stephen
Output:
--- Standard ranking ---
 1    44 Solomon
 2    42 Jason
 2    42 Errol
 4    41 Garry
 4    41 Bernard
 4    41 Barry
 7    39 Stephen

--- Modified ranking ---
 1    44 Solomon
 3    42 Jason
 3    42 Errol
 6    41 Garry
 6    41 Bernard
 6    41 Barry
 7    39 Stephen

--- Dense ranking ---
 1    44 Solomon
 2    42 Jason
 2    42 Errol
 3    41 Garry
 3    41 Bernard
 3    41 Barry
 4    39 Stephen

--- Ordinal ranking ---
 1    44 Solomon
 2    42 Jason
 3    42 Errol
 4    41 Garry
 5    41 Bernard
 6    41 Barry
 7    39 Stephen

--- Fractional ranking ---
 1    44 Solomon
 2.5  42 Jason
 2.5  42 Errol
 5    41 Garry
 5    41 Bernard
 5    41 Barry
 7    39 Stephen

C

Takes the scores as input via a file, prints out usage on incorrect invocation.

#include<stdlib.h>
#include<stdio.h>

typedef struct{
	int score;
	char name[100];
}entry;

void ordinalRanking(entry* list,int len){
	
	int i;
	
	printf("\n\nOrdinal Ranking\n---------------");
	
	for(i=0;i<len;i++)
		printf("\n%d\t%d\t%s",i+1,list[i].score,list[i].name);
}

void standardRanking(entry* list,int len){
	
	int i,j=1;
	
	printf("\n\nStandard Ranking\n----------------");
	
	for(i=0;i<len;i++){
		printf("\n%d\t%d\t%s",j,list[i].score,list[i].name);
		if(list[i+1].score<list[i].score)
			j = i+2;
	}
}

void denseRanking(entry* list,int len){
	
	int i,j=1;
	
	printf("\n\nDense Ranking\n-------------");
	
	for(i=0;i<len;i++){
		printf("\n%d\t%d\t%s",j,list[i].score,list[i].name);
		if(list[i+1].score<list[i].score)
			j++;
	}
}

void modifiedRanking(entry* list,int len){
	
	int i,j,count;
	
	printf("\n\nModified Ranking\n----------------");
	
	for(i=0;i<len-1;i++){
		if(list[i].score!=list[i+1].score){
			printf("\n%d\t%d\t%s",i+1,list[i].score,list[i].name);
			count = 1;
			for(j=i+1;list[j].score==list[j+1].score && j<len-1;j++)
				count ++;
			for(j=0;j<count-1;j++)
				printf("\n%d\t%d\t%s",i+count+1,list[i+j+1].score,list[i+j+1].name);
			i += (count-1);
		}
	}
	printf("\n%d\t%d\t%s",len,list[len-1].score,list[len-1].name);
}

void fractionalRanking(entry* list,int len){
	
	int i,j,count;
	float sum = 0;
	
	printf("\n\nFractional Ranking\n------------------");
	
	for(i=0;i<len;i++){
		if(i==len-1 || list[i].score!=list[i+1].score)
			printf("\n%.1f\t%d\t%s",(float)(i+1),list[i].score,list[i].name);
		else if(list[i].score==list[i+1].score){
			sum = i;
			count = 1;
			for(j=i;list[j].score==list[j+1].score;j++){
				sum += (j+1);
				count ++;
			}
			for(j=0;j<count;j++)
				printf("\n%.1f\t%d\t%s",sum/count + 1,list[i+j].score,list[i+j].name);
			i += (count-1);
		}
	}
}

void processFile(char* fileName){
	FILE* fp = fopen(fileName,"r");
	entry* list;
	int i,num;
	
	fscanf(fp,"%d",&num);
	
	list = (entry*)malloc(num*sizeof(entry));
	
	for(i=0;i<num;i++)
		fscanf(fp,"%d%s",&list[i].score,list[i].name);
	
	fclose(fp);
	
	ordinalRanking(list,num);
	standardRanking(list,num);
	denseRanking(list,num);
	modifiedRanking(list,num);
	fractionalRanking(list,num);
}

int main(int argC,char* argV[])
{
	if(argC!=2)
		printf("Usage %s <score list file>");
	else
		processFile(argV[1]);
	return 0;
}

Input file, first row is number of records :

7
44 Solomon
42 Jason
42 Errol
41 Garry
41 Bernard
41 Barry
39 Stephen

Output :

C:\rosettaCode>ranking.exe rankData.txt


Ordinal Ranking
---------------
1       44      Solomon
2       42      Jason
3       42      Errol
4       41      Garry
5       41      Bernard
6       41      Barry
7       39      Stephen

Standard Ranking
----------------
1       44      Solomon
2       42      Jason
2       42      Errol
4       41      Garry
4       41      Bernard
4       41      Barry
7       39      Stephen

Dense Ranking
-------------
1       44      Solomon
2       42      Jason
2       42      Errol
3       41      Garry
3       41      Bernard
3       41      Barry
4       39      Stephen

Modified Ranking
----------------
1       44      Solomon
3       42      Jason
3       42      Errol
6       41      Garry
6       41      Bernard
6       41      Barry
7       39      Stephen

Fractional Ranking
------------------
1.0     44      Solomon
2.5     42      Jason
2.5     42      Errol
5.0     41      Garry
5.0     41      Bernard
5.0     41      Barry
7.0     39      Stephen

C#

Translation of: D
using System;
using System.Collections.Generic;
using System.Linq;

namespace RankingMethods {
    class Program {
        static void Main(string[] args) {
            Dictionary<string, int> scores = new Dictionary<string, int> {
                ["Solomon"] = 44,
                ["Jason"] = 42,
                ["Errol"] = 42,
                ["Gary"] = 41,
                ["Bernard"] = 41,
                ["Barry"] = 41,
                ["Stephen"] = 39,
            };

            StandardRank(scores);
            ModifiedRank(scores);
            DenseRank(scores);
            OrdinalRank(scores);
            FractionalRank(scores);
        }

        static void StandardRank(Dictionary<string, int> data) {
            Console.WriteLine("Standard Rank");

            var list = data.Values.Distinct().ToList();
            list.Sort((a, b) => b.CompareTo(a));

            int rank = 1;
            foreach (var value in list) {
                int temp = rank;
                foreach (var k in data.Keys) {
                    if (data[k] == value) {
                        Console.WriteLine("{0} {1} {2}", temp, value, k);
                        rank++;
                    }
                }
            }

            Console.WriteLine();
        }

        static void ModifiedRank(Dictionary<string, int> data) {
            Console.WriteLine("Modified Rank");

            var list = data.Values.Distinct().ToList();
            list.Sort((a, b) => b.CompareTo(a));

            int rank = 0;
            foreach (var value in list) {
                foreach (var k in data.Keys) {
                    if (data[k] == value) {
                        rank++;
                    }
                }

                foreach (var k in data.Keys) {
                    if (data[k] == value) {
                        Console.WriteLine("{0} {1} {2}", rank, data[k], k);
                    }
                }
            }

            Console.WriteLine();
        }

        static void DenseRank(Dictionary<string, int> data) {
            Console.WriteLine("Dense Rank");

            var list = data.Values.Distinct().ToList();
            list.Sort((a, b) => b.CompareTo(a));

            int rank = 1;
            foreach (var value in list) {
                foreach (var k in data.Keys) {
                    if (data[k] == value) {
                        Console.WriteLine("{0} {1} {2}", rank, data[k], k);
                    }
                }
                rank++;
            }

            Console.WriteLine();
        }

        static void OrdinalRank(Dictionary<string, int> data) {
            Console.WriteLine("Ordinal Rank");

            var list = data.Values.Distinct().ToList();
            list.Sort((a, b) => b.CompareTo(a));

            int rank = 1;
            foreach (var value in list) {
                foreach (var k in data.Keys) {
                    if (data[k] == value) {
                        Console.WriteLine("{0} {1} {2}", rank, data[k], k);
                        rank++;
                    }
                }
            }

            Console.WriteLine();
        }

        static void FractionalRank(Dictionary<string, int> data) {
            Console.WriteLine("Fractional Rank");

            var list = data.Values.Distinct().ToList();
            list.Sort((a, b) => b.CompareTo(a));

            int rank = 0;
            foreach (var value in list) {
                double avg = 0;
                int cnt = 0;

                foreach (var k in data.Keys) {
                    if (data[k] == value) {
                        rank++;
                        cnt++;
                        avg += rank;
                    }
                }
                avg /= cnt;

                foreach (var k in data.Keys) {
                    if (data[k] == value) {
                        Console.WriteLine("{0:F1} {1} {2}", avg, data[k], k);
                    }
                }
            }

            Console.WriteLine();
        }
    }
}
Output:
Standard Rank
1 44 Solomon
2 42 Jason
2 42 Errol
4 41 Gary
4 41 Bernard
4 41 Barry
7 39 Stephen

Modified Rank
1 44 Solomon
3 42 Jason
3 42 Errol
6 41 Gary
6 41 Bernard
6 41 Barry
7 39 Stephen

Dense Rank
1 44 Solomon
2 42 Jason
2 42 Errol
3 41 Gary
3 41 Bernard
3 41 Barry
4 39 Stephen

Ordinal Rank
1 44 Solomon
2 42 Jason
3 42 Errol
4 41 Gary
5 41 Bernard
6 41 Barry
7 39 Stephen

Fractional Rank
1.0 44 Solomon
2.5 42 Jason
2.5 42 Errol
5.0 41 Gary
5.0 41 Bernard
5.0 41 Barry
7.0 39 Stephen

C++

Translation of: C#
#include <algorithm>
#include <iomanip>
#include <iostream>
#include <map>
#include <ostream>
#include <set>
#include <vector>

template<typename T>
std::ostream& print(std::ostream& os, const T& src) {
    auto it = src.cbegin();
    auto end = src.cend();

    os << "[";
    if (it != end) {
        os << *it;
        it = std::next(it);
    }
    while (it != end) {
        os << ", " << *it;
        it = std::next(it);
    }

    return os << "]";
}

typedef std::map<std::string, int> Map;
typedef Map::value_type MapEntry;

void standardRank(const Map& scores) {
    std::cout << "Standard Rank" << std::endl;

    std::vector<int> list;
    for (auto& elem : scores) {
        list.push_back(elem.second);
    }
    std::sort(list.begin(), list.end(), std::greater<int>{});
    list.erase(std::unique(list.begin(), list.end()), list.end());

    int rank = 1;
    for (auto value : list) {
        int temp = rank;
        for (auto& e : scores) {
            if (e.second == value) {
                std::cout << temp << " " << value << " " << e.first.c_str() << std::endl;
                rank++;
            }
        }
    }

    std::cout << std::endl;
}

void modifiedRank(const Map& scores) {
    std::cout << "Modified Rank" << std::endl;

    std::vector<int> list;
    for (auto& elem : scores) {
        list.push_back(elem.second);
    }
    std::sort(list.begin(), list.end(), std::greater<int>{});
    list.erase(std::unique(list.begin(), list.end()), list.end());

    int rank = 0;
    for (auto value : list) {
        rank += std::count_if(scores.begin(), scores.end(), [value](const MapEntry& e) { return e.second == value; });
        for (auto& e : scores) {
            if (e.second == value) {
                std::cout << rank << " " << value << " " << e.first.c_str() << std::endl;
            }
        }
    }

    std::cout << std::endl;
}

void denseRank(const Map& scores) {
    std::cout << "Dense Rank" << std::endl;

    std::vector<int> list;
    for (auto& elem : scores) {
        list.push_back(elem.second);
    }
    std::sort(list.begin(), list.end(), std::greater<int>{});
    list.erase(std::unique(list.begin(), list.end()), list.end());

    int rank = 1;
    for (auto value : list) {
        for (auto& e : scores) {
            if (e.second == value) {
                std::cout << rank << " " << value << " " << e.first.c_str() << std::endl;
            }
        }
        rank++;
    }

    std::cout << std::endl;
}

void ordinalRank(const Map& scores) {
    std::cout << "Ordinal Rank" << std::endl;

    std::vector<int> list;
    for (auto& elem : scores) {
        list.push_back(elem.second);
    }
    std::sort(list.begin(), list.end(), std::greater<int>{});
    list.erase(std::unique(list.begin(), list.end()), list.end());

    int rank = 1;
    for (auto value : list) {
        for (auto& e : scores) {
            if (e.second == value) {
                std::cout << rank++ << " " << value << " " << e.first.c_str() << std::endl;
            }
        }
    }

    std::cout << std::endl;
}

void fractionalRank(const Map& scores) {
    std::cout << "Ordinal Rank" << std::endl;

    std::vector<int> list;
    for (auto& elem : scores) {
        list.push_back(elem.second);
    }
    std::sort(list.begin(), list.end(), std::greater<int>{});
    list.erase(std::unique(list.begin(), list.end()), list.end());

    int rank = 0;
    for (auto value : list) {
        double avg = 0.0;
        int cnt = 0;

        for (auto& e : scores) {
            if (e.second == value) {
                rank++;
                cnt++;
                avg += rank;
            }
        }
        avg /= cnt;

        for (auto& e : scores) {
            if (e.second == value) {
                std::cout << std::setprecision(1) << std::fixed << avg << " " << value << " " << e.first.c_str() << std::endl;
            }
        }
    }

    std::cout << std::endl;
}

int main() {
    using namespace std;

    map<string, int> scores{
        {"Solomon", 44},
        {"Jason", 42},
        {"Errol", 42},
        {"Gary", 41},
        {"Bernard", 41},
        {"Barry", 41},
        {"Stephen", 39}
    };

    standardRank(scores);
    modifiedRank(scores);
    denseRank(scores);
    ordinalRank(scores);
    fractionalRank(scores);

    return 0;
}
Output:
Standard Rank
1 44 Solomon
2 42 Errol
2 42 Jason
4 41 Barry
4 41 Bernard
4 41 Gary
7 39 Stephen

Modified Rank
1 44 Solomon
3 42 Errol
3 42 Jason
6 41 Barry
6 41 Bernard
6 41 Gary
7 39 Stephen

Dense Rank
1 44 Solomon
2 42 Errol
2 42 Jason
3 41 Barry
3 41 Bernard
3 41 Gary
4 39 Stephen

Ordinal Rank
1 44 Solomon
2 42 Errol
3 42 Jason
4 41 Barry
5 41 Bernard
6 41 Gary
7 39 Stephen

Ordinal Rank
1.0 44 Solomon
2.5 42 Errol
2.5 42 Jason
5.0 41 Barry
5.0 41 Bernard
5.0 41 Gary
7.0 39 Stephen

Cowgol

include "cowgol.coh";

# List of competitors
record Competitor is
    score: uint8;
    name: [uint8];
end record;

var cs: Competitor[] := {
    {44, "Solomon"},
    {42, "Jason"},
    {42, "Errol"},
    {41, "Garry"},
    {41, "Bernard"},
    {41, "Barry"},
    {39, "Stephen"}
};

# Rank competitors given ranking method
interface Ranking(c: [Competitor], 
                  n: intptr, 
                  len: intptr, 
                  last: uint16): (rank: uint16); 
sub Rank(cs: [Competitor], num: intptr, r: Ranking) is
    var last: uint16 := 0;
    var idx: intptr := 0;
    
    while idx < num loop
        last := r(cs, idx, num, last);
        if last < 100 then
            print_i16(last);
        else
            # print fixed-point rank nicely
            print_i16(last / 100);
            print_char('.');
            print_i16((last % 100) / 10);
            print_i16(last % 10);
        end if;
        print(". ");
        print_i8(cs.score);
        print(", ");
        print(cs.name);
        print_nl();
        idx := idx + 1;
        cs := @next cs;
    end loop;
end sub;

# Standard ranking
var stdcount: uint16 := 0;
sub Standard implements Ranking is
    if n==0 then stdcount := 0; end if;
    stdcount := stdcount + 1;
    if n>0 and c.score == [@prev c].score then
        rank := last;
    else
        rank := stdcount;
    end if;
end sub;

# Modified ranking
sub Modified implements Ranking is
    rank := last;
    if n == 0 or c.score != [@prev c].score then
        while n < len loop
            rank := rank + 1;
            c := @next c;
            if c.score != [@prev c].score then
                break;
            end if;
            n := n + 1;
        end loop;
    end if;
end sub;
    
# Dense ranking
sub Dense implements Ranking is
    if n>0 and c.score == [@prev c].score then
        rank := last;
    else
        rank := last + 1;
    end if;
end sub;

# Ordinal ranking
sub Ordinal implements Ranking is
    rank := last + 1;
end sub;

# Fractional ranking (with fixed point arithmetic)
sub Fractional implements Ranking is
    rank := last;
    if n==0 or c.score != [@prev c].score then
        var sum: uint16 := 0;
        var ct: uint16 := 0;
        while n < len loop
            sum := sum + (n as uint16 + 1);
            ct := ct + 1;
            c := @next c;
            if c.score != [@prev c].score then
                break;
            end if;
            n := n + 1;
        end loop;
        rank := (sum * 100) / (ct as uint16);
    end if;
end sub;

record Method is
    name: [uint8];
    method: Ranking;
end record;

var methods: Method[] := {
    {"Standard", Standard},
    {"Modified", Modified},
    {"Dense", Dense},
    {"Ordinal", Ordinal},
    {"Fractional", Fractional}
};

var n: @indexof methods := 0;
while n < @sizeof methods loop
    print("--- ");
    print(methods[n].name);
    print(" ---\n");
    Rank(&cs[0], @sizeof cs, methods[n].method);
    print_nl();
    n := n + 1;
end loop;
Output:
--- Standard ---
1. 44, Solomon
2. 42, Jason
2. 42, Errol
4. 41, Garry
4. 41, Bernard
4. 41, Barry
7. 39, Stephen

--- Modified ---
1. 44, Solomon
3. 42, Jason
3. 42, Errol
6. 41, Garry
6. 41, Bernard
6. 41, Barry
7. 39, Stephen

--- Dense ---
1. 44, Solomon
2. 42, Jason
2. 42, Errol
3. 41, Garry
3. 41, Bernard
3. 41, Barry
4. 39, Stephen

--- Ordinal ---
1. 44, Solomon
2. 42, Jason
3. 42, Errol
4. 41, Garry
5. 41, Bernard
6. 41, Barry
7. 39, Stephen

--- Fractional ---
1.00. 44, Solomon
2.50. 42, Jason
2.50. 42, Errol
5.00. 41, Garry
5.00. 41, Bernard
5.00. 41, Barry
7.00. 39, Stephen

D

import std.algorithm;
import std.stdio;

void main() {
    immutable scores = [
        "Solomon": 44,
        "Jason": 42,
        "Errol": 42,
        "Garry": 41,
        "Bernard": 41,
        "Barry": 41,
        "Stephen": 39
    ];

    scores.standardRank;
    scores.modifiedRank;
    scores.denseRank;
    scores.ordinalRank;
    scores.fractionalRank;
}

/*
Standard ranking
1 44 Solomon
2 42 Jason
2 42 Errol
4 41 Garry
4 41 Bernard
4 41 Barry
7 39 Stephen
*/
void standardRank(const int[string] data) {
    writeln("Standard Rank");

    int rank = 1;
    foreach (value; data.values.dup.sort!"a>b".uniq) {
        int temp = rank;
        foreach(k,v; data) {
            if (v==value) {
                writeln(temp, " ", v, " ", k);
                rank++;
            }
        }
    }

    writeln;
}

/*
Modified ranking
1 44 Solomon
3 42 Jason
3 42 Errol
6 41 Garry
6 41 Bernard
6 41 Barry
7 39 Stephen
*/
void modifiedRank(const int[string] data) {
    writeln("Modified Rank");

    int rank = 0;
    foreach (value; data.values.dup.sort!"a>b".uniq) {
        foreach(k,v; data) {
            if (v==value) {
                rank++;
            }
        }
        foreach(k,v; data) {
            if (v==value) {
                writeln(rank, " ", v, " ", k);
            }
        }
    }

    writeln;
}

/*
Dense ranking
1 44 Solomon
2 42 Jason
2 42 Errol
3 41 Garry
3 41 Bernard
3 41 Barry
4 39 Stephen
*/
void denseRank(const int[string] data) {
    writeln("Dense Rank");

    int rank = 1;
    foreach (value; data.values.dup.sort!"a>b".uniq) {
        foreach(k,v; data) {
            if (v==value) {
                writeln(rank, " ", v, " ", k);
            }
        }
        rank++;
    }

    writeln;
}

/*
Ordinal ranking
1 44 Solomon
2 42 Jason
3 42 Errol
4 41 Garry
5 41 Bernard
6 41 Barry
7 39 Stephen
*/
void ordinalRank(const int[string] data) {
    writeln("Ordinal Rank");

    int rank = 1;
    foreach (value; data.values.dup.sort!"a>b".uniq) {
        foreach(k,v; data) {
            if (v==value) {
                writeln(rank, " ", v, " ", k);
                rank++;
            }
        }
    }

    writeln;
}

/*
Fractional ranking
1,0 44 Solomon
2,5 42 Jason
2,5 42 Errol
5,0 41 Garry
5,0 41 Bernard
5,0 41 Barry
7,0 39 Stephen
*/
void fractionalRank(const int[string] data) {
    writeln("Fractional Rank");

    int rank = 0;
    foreach (value; data.values.dup.sort!"a>b".uniq) {
        real avg = 0;
        int cnt;

        foreach(k,v; data) {
            if (v==value) {
                rank++;
                cnt++;
                avg+=rank;
            }
        }
        avg /= cnt;

        foreach(k,v; data) {
            if (v==value) {
                writef("%0.1f ", avg);
                writeln(v, " ", k);
            }
        }
    }

    writeln;
}
Output:
Standard Rank
1 44 Solomon
2 42 Errol
2 42 Jason
4 41 Garry
4 41 Bernard
4 41 Barry
7 39 Stephen

Modified Rank
1 44 Solomon
3 42 Errol
3 42 Jason
6 41 Garry
6 41 Bernard
6 41 Barry
7 39 Stephen

Dense Rank
1 44 Solomon
2 42 Errol
2 42 Jason
3 41 Garry
3 41 Bernard
3 41 Barry
4 39 Stephen

Ordinal Rank
1 44 Solomon
2 42 Errol
3 42 Jason
4 41 Garry
5 41 Bernard
6 41 Barry
7 39 Stephen

Fractional Rank
1.0 44 Solomon
2.5 42 Errol
2.5 42 Jason
5.0 41 Garry
5.0 41 Bernard
5.0 41 Barry
7.0 39 Stephen

Elixir

Translation of: Ruby
defmodule Ranking do
  def methods(data) do
    IO.puts "stand.\tmod.\tdense\tord.\tfract."
    Enum.group_by(data, fn {score,_name} -> score end)
    |> Enum.map(fn {score,pairs} ->
         names = Enum.map(pairs, fn {_,name} -> name end) |> Enum.reverse
         {score, names}
       end)
    |> Enum.sort_by(fn {score,_} -> -score end)
    |> Enum.with_index
    |> Enum.reduce({1,0,0}, fn {{score, names}, i}, {s_rnk, m_rnk, o_rnk} ->
         d_rnk = i + 1
         m_rnk = m_rnk + length(names)
         f_rnk = ((s_rnk + m_rnk) / 2) |> to_string |> String.replace(".0","")
         o_rnk = Enum.reduce(names, o_rnk, fn name,acc ->
           IO.puts "#{s_rnk}\t#{m_rnk}\t#{d_rnk}\t#{acc+1}\t#{f_rnk}\t#{score} #{name}"
           acc + 1
         end)
         {s_rnk+length(names), m_rnk, o_rnk}
       end)
  end
end

~w"44 Solomon
   42 Jason
   42 Errol
   41 Garry
   41 Bernard
   41 Barry
   39 Stephen"
|> Enum.chunk(2)
|> Enum.map(fn [score,name] -> {String.to_integer(score),name} end)
|> Ranking.methods
Output:
stand.  mod.    dense   ord.    fract.
1       1       1       1       1       44 Solomon
2       3       2       2       2.5     42 Jason
2       3       2       3       2.5     42 Errol
4       6       3       4       5       41 Garry
4       6       3       5       5       41 Bernard
4       6       3       6       5       41 Barry
7       7       4       7       7       39 Stephen

Factor

Works with: Factor version 0.99 2019-07-10
USING: arrays assocs formatting fry generalizations io kernel
math math.ranges math.statistics math.vectors sequences
splitting.monotonic ;
IN: rosetta-code.ranking

CONSTANT: ranks {
    { 44 "Solomon" } { 42 "Jason" } { 42 "Errol" }
    { 41 "Garry" } { 41 "Bernard" } { 41 "Barry" }
    { 39 "Stephen" }
}

: rank ( seq quot -- seq' )
    '[ [ = ] monotonic-split [ length ] map dup @ [ <array> ]
    2map concat ] call ; inline

: standard ( seq -- seq' ) [ cum-sum0 1 v+n ] rank ;
: modified ( seq -- seq' ) [ cum-sum ] rank ;
: dense    ( seq -- seq' ) [ length [1,b] ] rank ;
: ordinal  ( seq -- seq' ) length [1,b] ;

: fractional ( seq -- seq' )
    [ dup cum-sum swap [ dupd - [a,b) mean ] 2map ] rank ;

: .rank ( quot -- )
    [ ranks dup keys ] dip call swap
    [ first2 "%5u %d %s\n" printf ] 2each ; inline

: ranking-demo ( -- )
    "Standard ranking"   [ standard   ]
    "Modified ranking"   [ modified   ]
    "Dense ranking"      [ dense      ]
    "Ordinal ranking"    [ ordinal    ]
    "Fractional ranking" [ fractional ]
    [ [ print ] [ .rank nl ] bi* ] 2 5 mnapply ;

MAIN: ranking-demo
Output:
Standard ranking
    1 44 Solomon
    2 42 Jason
    2 42 Errol
    4 41 Garry
    4 41 Bernard
    4 41 Barry
    7 39 Stephen

Modified ranking
    1 44 Solomon
    3 42 Jason
    3 42 Errol
    6 41 Garry
    6 41 Bernard
    6 41 Barry
    7 39 Stephen

Dense ranking
    1 44 Solomon
    2 42 Jason
    2 42 Errol
    3 41 Garry
    3 41 Bernard
    3 41 Barry
    4 39 Stephen

Ordinal ranking
    1 44 Solomon
    2 42 Jason
    3 42 Errol
    4 41 Garry
    5 41 Bernard
    6 41 Barry
    7 39 Stephen

Fractional ranking
    1 44 Solomon
2+1/2 42 Jason
2+1/2 42 Errol
    5 41 Garry
    5 41 Bernard
    5 41 Barry
    7 39 Stephen


FreeBASIC

Data 44,"Solomon", 42,"Jason", 42,"Errol", 41,"Garry"
Data 41,"Bernard", 41,"Barry", 39,"Stephen"

Dim Shared As Integer n = 7
Dim Shared As Integer puntos(n), i
Dim Shared As Single ptosnom(n)
Dim Shared As String nombre(n)

Print "Puntuaciones a clasificar (mejores primero):"
For i = 1 To n
    Read puntos(i), nombre(i)
    Print Using "      ##, \        \"; puntos(i); nombre(i)
Next i
Print 

Sub MostarTabla
    For i = 1 To n
        Print Using " \  \ ##, \        \"; Str(ptosnom(i)); puntos(i); nombre(i)
    Next i
    Print
End Sub

Print "--- Standard ranking ---"
ptosnom(1) = 1
For i = 2 To n
    If puntos(i) = puntos(i-1) Then ptosnom(i) = ptosnom(i-1) Else ptosnom(i) = i
Next i    
MostarTabla


Print "--- Modified ranking ---"
ptosnom(n) = n
For i = n-1 To 1 Step -1
    If puntos(i) = puntos(i+1) Then ptosnom(i) = ptosnom(i+1) Else ptosnom(i) = i
Next i    
MostarTabla

Print "--- Dense ranking ---"
ptosnom(1) = 1
For i = 2 To n
    ptosnom(i) = ptosnom(i-1) - (puntos(i) <> puntos(i-1))
Next i    
MostarTabla

Print "--- Ordinal ranking ---"
For i = 1 To n
    ptosnom(i) = i
Next i
MostarTabla

Print "--- Fractional ranking ---"
i = 1
Dim As Integer j = 2
Do
    If j <= n Then If (puntos(j-1) = puntos(j)) Then j += 1
    For k As Integer = i To j-1
        ptosnom(k) = (i+j-1) / 2
    Next k
    i = j
    j += 1
Loop While i <= n
MostarTabla
Sleep
Output:
Puntuaciones a clasificar (mejores primero):
       44 Solomon
       42 Jason
       42 Errol
       41 Garry
       41 Bernard
       41 Barry
       39 Stephen

--- Standard ranking ---
 1     44 Solomon
 2     42 Jason
 2     42 Errol
 4     41 Garry
 4     41 Bernard
 4     41 Barry
 7     39 Stephen

--- Modified ranking ---
 1     44 Solomon
 3     42 Jason
 3     42 Errol
 6     41 Garry
 6     41 Bernard
 6     41 Barry
 7     39 Stephen

--- Dense ranking ---
 1     44 Solomon
 2     42 Jason
 2     42 Errol
 3     41 Garry
 3     41 Bernard
 3     41 Barry
 4     39 Stephen

--- Ordinal ranking ---
 1     44 Solomon
 2     42 Jason
 3     42 Errol
 4     41 Garry
 5     41 Bernard
 6     41 Barry
 7     39 Stephen

--- Fractional ranking ---
 1     44 Solomon
 2.5   42 Jason
 2.5   42 Errol
 4.5   41 Garry
 4.5   41 Bernard
 6     41 Barry
 7     39 Stephen


Go

package main

import (
	"fmt"
	"sort"
)

type rankable interface {
	Len() int
	RankEqual(int, int) bool
}

func StandardRank(d rankable) []float64 {
	r := make([]float64, d.Len())
	var k int
	for i := range r {
		if i == 0 || !d.RankEqual(i, i-1) {
			k = i + 1
		}
		r[i] = float64(k)
	}
	return r
}

func ModifiedRank(d rankable) []float64 {
	r := make([]float64, d.Len())
	for i := range r {
		k := i + 1
		for j := i + 1; j < len(r) && d.RankEqual(i, j); j++ {
			k = j + 1
		}
		r[i] = float64(k)
	}
	return r
}

func DenseRank(d rankable) []float64 {
	r := make([]float64, d.Len())
	var k int
	for i := range r {
		if i == 0 || !d.RankEqual(i, i-1) {
			k++
		}
		r[i] = float64(k)
	}
	return r
}

func OrdinalRank(d rankable) []float64 {
	r := make([]float64, d.Len())
	for i := range r {
		r[i] = float64(i + 1)
	}
	return r
}

func FractionalRank(d rankable) []float64 {
	r := make([]float64, d.Len())
	for i := 0; i < len(r); {
		var j int
		f := float64(i + 1)
		for j = i + 1; j < len(r) && d.RankEqual(i, j); j++ {
			f += float64(j + 1)
		}
		f /= float64(j - i)
		for ; i < j; i++ {
			r[i] = f
		}
	}
	return r
}

type scores []struct {
	score int
	name  string
}

func (s scores) Len() int                { return len(s) }
func (s scores) RankEqual(i, j int) bool { return s[i].score == s[j].score }
func (s scores) Swap(i, j int)           { s[i], s[j] = s[j], s[i] }
func (s scores) Less(i, j int) bool {
	if s[i].score != s[j].score {
		return s[i].score > s[j].score
	}
	return s[i].name < s[j].name
}

var data = scores{
	{44, "Solomon"},
	{42, "Jason"},
	{42, "Errol"},
	{41, "Garry"},
	{41, "Bernard"},
	{41, "Barry"},
	{39, "Stephen"},
}

func main() {
	show := func(name string, fn func(rankable) []float64) {
		fmt.Println(name, "Ranking:")
		r := fn(data)
		for i, d := range data {
			fmt.Printf("%4v - %2d %s\n", r[i], d.score, d.name)
		}
	}

	sort.Sort(data)
	show("Standard", StandardRank)
	show("\nModified", ModifiedRank)
	show("\nDense", DenseRank)
	show("\nOrdinal", OrdinalRank)
	show("\nFractional", FractionalRank)
}
Output:
Standard Ranking:
   1 - 44 Solomon
   2 - 42 Errol
   2 - 42 Jason
   4 - 41 Barry
   4 - 41 Bernard
   4 - 41 Garry
   7 - 39 Stephen

Modified Ranking:
   1 - 44 Solomon
   3 - 42 Errol
   3 - 42 Jason
   6 - 41 Barry
   6 - 41 Bernard
   6 - 41 Garry
   7 - 39 Stephen

Dense Ranking:
   1 - 44 Solomon
   2 - 42 Errol
   2 - 42 Jason
   3 - 41 Barry
   3 - 41 Bernard
   3 - 41 Garry
   4 - 39 Stephen

Ordinal Ranking:
   1 - 44 Solomon
   2 - 42 Errol
   3 - 42 Jason
   4 - 41 Barry
   5 - 41 Bernard
   6 - 41 Garry
   7 - 39 Stephen

Fractional Ranking:
   1 - 44 Solomon
 2.5 - 42 Errol
 2.5 - 42 Jason
   5 - 41 Barry
   5 - 41 Bernard
   5 - 41 Garry
   7 - 39 Stephen

Haskell

import Data.List (groupBy, sortBy, intercalate)

type Item = (Int, String)

type ItemList = [Item]

type ItemGroups = [ItemList]

type RankItem a = (a, Int, String)

type RankItemList a = [RankItem a]

-- make sure the input is ordered and grouped by score
prepare :: ItemList -> ItemGroups
prepare = groupBy gf . sortBy (flip compare)
  where
    gf (a, _) (b, _) = a == b

-- give an item a rank
rank
  :: Num a
  => a -> Item -> RankItem a
rank n (a, b) = (n, a, b)

-- ranking methods
standard, modified, dense, ordinal :: ItemGroups -> RankItemList Int
standard = ms 1
  where
    ms _ [] = []
    ms n (x:xs) = (rank n <$> x) ++ ms (n + length x) xs

modified = md 1
  where
    md _ [] = []
    md n (x:xs) =
      let l = length x
          nl = n + l
          nl1 = nl - 1
      in (rank nl1 <$> x) ++ md (n + l) xs

dense = md 1
  where
    md _ [] = []
    md n (x:xs) = map (rank n) x ++ md (n + 1) xs

ordinal = zipWith rank [1 ..] . concat

fractional :: ItemGroups -> RankItemList Double
fractional = mf 1.0
  where
    mf _ [] = []
    mf n (x:xs) =
      let l = length x
          o = take l [n ..]
          ld = fromIntegral l
          a = sum o / ld
      in map (rank a) x ++ mf (n + ld) xs

-- sample data
test :: ItemGroups
test =
  prepare
    [ (44, "Solomon")
    , (42, "Jason")
    , (42, "Errol")
    , (41, "Garry")
    , (41, "Bernard")
    , (41, "Barry")
    , (39, "Stephen")
    ]

-- print rank items nicely
nicePrint
  :: Show a
  => String -> RankItemList a -> IO ()
nicePrint xs items = do
  putStrLn xs
  mapM_ np items
  putStr "\n"
  where
    np (a, b, c) = putStrLn $ intercalate "\t" [show a, show b, c]

main :: IO ()
main = do
  nicePrint "Standard:" $ standard test
  nicePrint "Modified:" $ modified test
  nicePrint "Dense:" $ dense test
  nicePrint "Ordinal:" $ ordinal test
  nicePrint "Fractional:" $ fractional test
Output:
Standard:
1	44	Solomon
2	42	Jason
2	42	Errol
4	41	Garry
4	41	Bernard
4	41	Barry
7	39	Stephen

Modified:
1	44	Solomon
3	42	Jason
3	42	Errol
6	41	Garry
6	41	Bernard
6	41	Barry
7	39	Stephen

Dense:
1	44	Solomon
2	42	Jason
2	42	Errol
3	41	Garry
3	41	Bernard
3	41	Barry
4	39	Stephen

Ordinal:
1	44	Solomon
2	42	Jason
3	42	Errol
4	41	Garry
5	41	Bernard
6	41	Barry
7	39	Stephen

Fractional:
1.0	44	Solomon
2.5	42	Jason
2.5	42	Errol
5.0	41	Garry
5.0	41	Bernard
5.0	41	Barry
7.0	39	Stephen

J

Implementation:

competitors=:<;._1;._2]0 :0
 44 Solomon
 42 Jason
 42 Errol
 41 Garry
 41 Bernard
 41 Barry
 39 Stephen
)

scores=:  {."1

standard=: 1+i.~
modified=: 1+i:~
dense=: #/.~ # #\@~.
ordinal=: #\
fractional=: #/.~ # ] (+/%#)/. #\

rank=:1 :'<"0@u@:scores,.]'

Note that we assume that the competitors are already in the right order. Also, of course (as is common when using J) we use the J command line, because that is portable across operating systems (for example: the OS command line is difficult to use on phones).

Task examples:

   standard rank competitors
┌─┬──┬───────┐
144Solomon
├─┼──┼───────┤
242Jason  
├─┼──┼───────┤
242Errol  
├─┼──┼───────┤
441Garry  
├─┼──┼───────┤
441Bernard
├─┼──┼───────┤
441Barry  
├─┼──┼───────┤
739Stephen
└─┴──┴───────┘
   modified rank competitors
┌─┬──┬───────┐
144Solomon
├─┼──┼───────┤
342Jason  
├─┼──┼───────┤
342Errol  
├─┼──┼───────┤
641Garry  
├─┼──┼───────┤
641Bernard
├─┼──┼───────┤
641Barry  
├─┼──┼───────┤
739Stephen
└─┴──┴───────┘
   dense rank competitors
┌─┬──┬───────┐
144Solomon
├─┼──┼───────┤
242Jason  
├─┼──┼───────┤
242Errol  
├─┼──┼───────┤
341Garry  
├─┼──┼───────┤
341Bernard
├─┼──┼───────┤
341Barry  
├─┼──┼───────┤
439Stephen
└─┴──┴───────┘
   ordinal rank competitors
┌─┬──┬───────┐
144Solomon
├─┼──┼───────┤
242Jason  
├─┼──┼───────┤
342Errol  
├─┼──┼───────┤
441Garry  
├─┼──┼───────┤
541Bernard
├─┼──┼───────┤
641Barry  
├─┼──┼───────┤
739Stephen
└─┴──┴───────┘
   fractional rank competitors
┌───┬──┬───────┐
1  44Solomon
├───┼──┼───────┤
2.542Jason  
├───┼──┼───────┤
2.542Errol  
├───┼──┼───────┤
5  41Garry  
├───┼──┼───────┤
5  41Bernard
├───┼──┼───────┤
5  41Barry  
├───┼──┼───────┤
7  39Stephen
└───┴──┴───────┘

Java

Works with: Java version 8
import java.util.*;

public class RankingMethods {

    final static String[] input = {"44 Solomon", "42 Jason", "42 Errol",
        "41 Garry", "41 Bernard", "41 Barry", "39 Stephen"};

    public static void main(String[] args) {
        int len = input.length;

        Map<String, int[]> map = new TreeMap<>((a, b) -> b.compareTo(a));
        for (int i = 0; i < len; i++) {
            String key = input[i].split("\\s+")[0];
            int[] arr;
            if ((arr = map.get(key)) == null)
                arr = new int[]{i, 0};
            arr[1]++;
            map.put(key, arr);
        }
        int[][] groups = map.values().toArray(new int[map.size()][]);

        standardRanking(len, groups);
        modifiedRanking(len, groups);
        denseRanking(len, groups);
        ordinalRanking(len);
        fractionalRanking(len, groups);
    }

    private static void standardRanking(int len, int[][] groups) {
        System.out.println("\nStandard ranking");
        for (int i = 0, rank = 0, group = 0; i < len; i++) {
            if (group < groups.length && i == groups[group][0]) {
                rank = i + 1;
                group++;
            }
            System.out.printf("%d %s%n", rank, input[i]);
        }
    }

    private static void modifiedRanking(int len, int[][] groups) {
        System.out.println("\nModified ranking");
        for (int i = 0, rank = 0, group = 0; i < len; i++) {
            if (group < groups.length && i == groups[group][0])
                rank += groups[group++][1];
            System.out.printf("%d %s%n", rank, input[i]);
        }
    }

    private static void denseRanking(int len, int[][] groups) {
        System.out.println("\nDense ranking");
        for (int i = 0, rank = 0; i < len; i++) {
            if (rank < groups.length && i == groups[rank][0])
                rank++;
            System.out.printf("%d %s%n", rank, input[i]);
        }
    }

    private static void ordinalRanking(int len) {
        System.out.println("\nOrdinal ranking");
        for (int i = 0; i < len; i++)
            System.out.printf("%d %s%n", i + 1, input[i]);
    }

    private static void fractionalRanking(int len, int[][] groups) {
        System.out.println("\nFractional ranking");
        float rank = 0;
        for (int i = 0, tmp = 0, group = 0; i < len; i++) {
            if (group < groups.length && i == groups[group][0]) {
                tmp += groups[group++][1];
                rank = (i + 1 + tmp) / 2.0F;
            }
            System.out.printf("%2.1f %s%n", rank, input[i]);
        }
    }
}
Standard ranking
1 44 Solomon
2 42 Jason
2 42 Errol
4 41 Garry
4 41 Bernard
4 41 Barry
7 39 Stephen

Modified ranking
1 44 Solomon
3 42 Jason
3 42 Errol
6 41 Garry
6 41 Bernard
6 41 Barry
7 39 Stephen

Dense ranking
1 44 Solomon
2 42 Jason
2 42 Errol
3 41 Garry
3 41 Bernard
3 41 Barry
4 39 Stephen

Ordinal ranking
1 44 Solomon
2 42 Jason
3 42 Errol
4 41 Garry
5 41 Bernard
6 41 Barry
7 39 Stephen

Fractional ranking
1,0 44 Solomon
2,5 42 Jason
2,5 42 Errol
5,0 41 Garry
5,0 41 Bernard
5,0 41 Barry
7,0 39 Stephen

JavaScript

ES5

The task formulation doesn't seem to directly explain or determine the order of listing for players whose score is the same.

( This version chooses to use a secondary (alphabetic) sort after the numeric sort by score. That does, of course, affect the ordinal placements for some players)

(function () {
 
    var xs = 'Solomon Jason Errol Garry Bernard Barry Stephen'.split(' '),
        ns = [44, 42, 42, 41, 41, 41, 39],
 
        sorted = xs.map(function (x, i) {
            return { name: x, score: ns[i] };
        }).sort(function (a, b) {
            var c = b.score - a.score;
            return c ? c : a.name < b.name ? -1 : a.name > b.name ? 1 : 0;
        }),
 
        names = sorted.map(function (x) { return x.name; }),
        scores = sorted.map(function (x) { return x.score; }),
 
        reversed = scores.slice(0).reverse(),
        unique = scores.filter(function (x, i) {
            return scores.indexOf(x) === i;
        });
 
    // RANKINGS AS FUNCTIONS OF SCORES: SORTED, REVERSED AND UNIQUE
 
    var rankings = function (score, index) {
            return {
                name: names[index],
                score: score,

                Ordinal: index + 1,

                Standard: function (n) {
                    return scores.indexOf(n) + 1;
                }(score),

                Modified: function (n) {
                    return reversed.length - reversed.indexOf(n);
                }(score),

                Dense: function (n) {
                    return unique.indexOf(n) + 1;
                }(score),

                Fractional: function (n) {
                    return (
                        (scores.indexOf(n) + 1) +
                        (reversed.length - reversed.indexOf(n))
                    ) / 2;
                }(score)
            };
        },
 
        tbl = [
            'Name Score Standard Modified Dense Ordinal Fractional'.split(' ')
        ].concat(scores.map(rankings).reduce(function (a, x) {
            return a.concat([
                [x.name, x.score,
                    x.Standard, x.Modified, x.Dense, x.Ordinal, x.Fractional
                ]
            ]);
        }, [])),
 
        //[[a]] -> bool -> s -> s
        wikiTable = function (lstRows, blnHeaderRow, strStyle) {
            return '{| class="wikitable" ' + (
                strStyle ? 'style="' + strStyle + '"' : ''
            ) + lstRows.map(function (lstRow, iRow) {
                var strDelim = ((blnHeaderRow && !iRow) ? '!' : '|');
 
                return '\n|-\n' + strDelim + ' ' + lstRow.map(function (v) {
                    return typeof v === 'undefined' ? ' ' : v;
                }).join(' ' + strDelim + strDelim + ' ');
            }).join('') + '\n|}';
        };
 
    return wikiTable(tbl, true, 'text-align:center');
 
})();
Output:
Name Score Standard Modified Dense Ordinal Fractional
Solomon 44 1 1 1 1 1
Errol 42 2 3 2 2 2.5
Jason 42 2 3 2 3 2.5
Barry 41 4 6 3 4 5
Bernard 41 4 6 3 5 5
Garry 41 4 6 3 6 5
Stephen 39 7 7 4 7 7

ES6

((() => {
    const xs = 'Solomon Jason Errol Garry Bernard Barry Stephen'.split(' '),
        ns = [44, 42, 42, 41, 41, 41, 39];

    const sorted = xs.map((x, i) => ({
            name: x,
            score: ns[i]
        }))
        .sort((a, b) => {
            const c = b.score - a.score;
            return c ? c : a.name < b.name ? -1 : a.name > b.name ? 1 : 0;
        });

    const names = sorted.map(x => x.name),
        scores = sorted.map(x => x.score),
        reversed = scores.slice(0)
        .reverse(),
        unique = scores.filter((x, i) => scores.indexOf(x) === i);

    // RANKINGS AS FUNCTIONS OF SCORES: SORTED, REVERSED AND UNIQUE

    // rankings :: Int -> Int -> Dictonary
    const rankings = (score, index) => ({
        name: names[index],
        score,
        Ordinal: index + 1,
        Standard: scores.indexOf(score) + 1,
        Modified: reversed.length - reversed.indexOf(score),
        Dense: unique.indexOf(score) + 1,

        Fractional: (n => (
            (scores.indexOf(n) + 1) +
            (reversed.length - reversed.indexOf(n))
        ) / 2)(score)
    });

    // tbl :: [[[a]]]
    const tbl = [
            'Name Score Standard Modified Dense Ordinal Fractional'.split(' ')
        ].concat(scores.map(rankings)
        .reduce((a, x) => a.concat([
            [x.name, x.score,
                x.Standard, x.Modified, x.Dense, x.Ordinal, x.Fractional
            ]
        ]), []));

    // wikiTable :: [[[a]]] -> Bool -> String -> String
    const wikiTable = (lstRows, blnHeaderRow, strStyle) =>
        `{| class="wikitable" ${strStyle ? 'style="' + strStyle + '"' : ''}
        ${lstRows.map((lstRow, iRow) => {
            const strDelim = ((blnHeaderRow && !iRow) ? '!' : '|');

            return '\n|-\n' + strDelim + ' ' + lstRow
            .map(v => typeof v === 'undefined' ? ' ' : v)
            .join(' ' + strDelim + strDelim + ' ');
        }).join('')}\n|}`;

    return wikiTable(tbl, true, 'text-align:center');
}))();
Name Score Standard Modified Dense Ordinal Fractional
Solomon 44 1 1 1 1 1
Errol 42 2 3 2 2 2.5
Jason 42 2 3 2 3 2.5
Barry 41 4 6 3 4 5
Bernard 41 4 6 3 5 5
Garry 41 4 6 3 6 5
Stephen 39 7 7 4 7 7
Output:

jq

We assume the list of players and their scores has already been sorted, and that the list takes the form:

[ player1, score1, player2, score2, ...]

For the sake of brevity, only the ranks are printed.

# Ties share what would have been their first ordinal number
def standard_ranking:
  . as $raw
  | ([range(1;length;2) | $raw[.]]) as $scores
  | reduce range(1; $scores|length) as $i
      ([1]; if $scores[$i - 1] == $scores[$i] then . + [.[-1]]
            else . + [$i + 1]
            end) ;

def modified_ranking: 
  # The helper function resolves [ranks, tentative]
  # by appending the ranks of the ties to "ranks"
  def resolve:
    (.[1] | length) as $length
    | if $length == 0 then .[0]
      else .[1][-1] as $max
           | .[0] + ( .[1] | map( $max) )
      end ;
  . as $raw
  | ([range(1;length;2) | $raw[.]]) as $scores
  | reduce range(1; $scores|length) as $i
      # state: [ranks, tentative]
      ([ [], [1] ];
       if $scores[$i - 1] == $scores[$i] then [.[0], .[1] + [ $i + 1 ]]
       else [ resolve,  [ $i + 1 ] ]
       end )
  | resolve ;

def dense_ranking: # next available
  . as $raw
  | ([range(1;length;2) | $raw[.]]) as $scores
  | reduce range(1; $scores|length) as $i
      ([1]; if $scores[$i - 1] == $scores[$i] then . + [.[-1]]
            else . + [ .[-1] + 1]
            end );

def ordinal_ranking: # unfair to some!
  [ range(1; 1 + length/2) ] ;

def fractional_ranking: 
  # The helper function resolves [ranks, tentative]
  # by appending the averages of the tentative ranks to "ranks"
  def resolve:
    (.[1] | length) as $length
    | if $length == 0 then .[0]
      else (.[1] | add  / $length) as $avg
           | .[0] + ( .[1] | map( $avg) )
      end ;
  . as $raw
  | ([range(1;length;2) | $raw[.]]) as $scores
  | reduce range(1; $scores|length) as $i
      # state: [ranks, tentative]
      ([ [], [1] ];
       if $scores[$i - 1] == $scores[$i] then [.[0], .[1] + [ $i + 1 ]]
       else [ resolve,  [ $i + 1 ] ]
       end )
  | resolve ;
Task
def raw:
 [
 "Solomon",  44,
 "Jason"  ,  42,
 "Errol"  ,  42,
 "Garry"  ,  41,
 "Bernard",  41,
 "Barry"  ,  41,
 "Stephen",  39
] ;

def task:
 "standard:   \( raw | standard_ranking)",
 "modified:   \( raw | modified_ranking)",
 "dense:      \( raw | dense_ranking)",
 "ordinal:    \( raw | ordinal_ranking)",
 "fractional: \( raw | fractional_ranking)" ;
  
task
Output:
standard:   [1,2,2,4,4,4,7]
modified:   [1,3,3,6,6,6,7]
dense:      [1,2,2,3,3,3,4]
ordinal:    [1,2,3,4,5,6,7]
fractional: [1,2.5,2.5,5,5,5,7]

Julia

ties, a helper function used by some of the ranking methods. It lists any duplicated scores.

function ties{T<:Real}(a::Array{T,1})
    unique(a[2:end][a[2:end] .== a[1:end-1]])
end

ties assumes that the there are at least 2 scores in the list to be checked, and the calling functions are designed to avoid calls to it in this case.

Standard Ranking Function

function rankstandard{T<:Real}(a::Array{T,1})
    r = collect(1:length(a))
    1 < r[end] || return r
    for i in ties(a)
        r[a.==i] = r[a.==i][1]
    end
    return r
end

Modified Ranking Function

function rankmodified{T<:Real}(a::Array{T,1})
    indexin(a, a)
end

Dense Ranking Function

function rankdense{T<:Real}(a::Array{T,1})
    indexin(a, unique(a))
end

Ordinal Ranking Function

function rankordinal{T<:Real}(a::Array{T,1})
    collect(1:length(a))
end

For ordinal ranking, there are a variety of ways of handling tied scores. I've taken the easy way out and assumed that the position in the list already reflects any tie-breaking policy. In this case, there is not much that needs to be done.

Fractional Ranking Function

function rankfractional{T<:Real}(a::Array{T,1})
    r = float64(collect(1:length(a)))
    1.0 < r[end] || return r
    for i in ties(a)
        r[a.==i] = mean(r[a.==i])
    end
    return r
end

Main

scores = [44, 42, 42, 41, 41, 41, 39]
names = ["Solomon", "Jason", "Errol", "Garry",
         "Bernard", "Barry", "Stephen"]

srank = rankstandard(scores)
mrank = rankmodified(scores)
drank = rankdense(scores)
orank = rankordinal(scores)
frank = rankfractional(scores)

println("    Name    Score  Std  Mod  Den  Ord  Frac")
for i in 1:length(scores)
    print(@sprintf("   %-7s", names[i]))
    print(@sprintf("%5d ", scores[i]))
    print(@sprintf("%5d", srank[i]))
    print(@sprintf("%5d", mrank[i]))
    print(@sprintf("%5d", drank[i]))
    print(@sprintf("%5d", orank[i]))
    print(@sprintf("%7.2f", frank[i]))
    println()
end
Output:
    Name    Score  Std  Mod  Den  Ord  Frac
   Solomon   44     1    1    1    1   1.00
   Jason     42     2    3    2    2   2.50
   Errol     42     2    3    2    3   2.50
   Garry     41     4    6    3    4   5.00
   Bernard   41     4    6    3    5   5.00
   Barry     41     4    6    3    6   5.00
   Stephen   39     7    7    4    7   7.00

Kotlin

// version 1.0.6

/* all ranking functions assume the array of Pairs is non-empty and already sorted by decreasing order of scores
   and then, if the scores are equal, by reverse alphabetic order of names
*/

fun standardRanking(scores: Array<Pair<Int, String>>): IntArray {   
    val rankings = IntArray(scores.size)
    rankings[0] = 1
    for (i in 1 until scores.size) rankings[i] = if (scores[i].first == scores[i - 1].first) rankings[i - 1] else i + 1
    return rankings
}

fun modifiedRanking(scores: Array<Pair<Int, String>>): IntArray {   
    val rankings = IntArray(scores.size)
    rankings[0] = 1 
    for (i in 1 until scores.size) {
        rankings[i] = i + 1 
        val currScore = scores[i].first         
        for (j in i - 1 downTo 0) {
            if (currScore != scores[j].first) break
            rankings[j] = i + 1
        }       
    }
    return rankings
}

fun denseRanking(scores: Array<Pair<Int, String>>): IntArray {   
    val rankings = IntArray(scores.size)
    rankings[0] = 1
    var prevRanking = 1
    for (i in 1 until scores.size) rankings[i] = if (scores[i].first == scores[i - 1].first) prevRanking else ++prevRanking
    return rankings
}

fun ordinalRanking(scores: Array<Pair<Int, String>>) = IntArray(scores.size) { it + 1 }  

fun fractionalRanking(scores: Array<Pair<Int, String>>): DoubleArray {
    val rankings = DoubleArray(scores.size)
    rankings[0] = 1.0 
    for (i in 1 until scores.size) {
        var k = i 
        val currScore = scores[i].first         
        for (j in i - 1 downTo 0) {
            if (currScore != scores[j].first) break
            k = j
        }
        val avg = (k..i).average() + 1.0
        for (m in k..i) rankings[m] = avg       
    }
    return rankings
}    

fun printRankings(title: String, rankings: IntArray, scores: Array<Pair<Int, String>>) {
    println(title + ":")
    for (i in 0 until rankings.size) { 
        print ("${rankings[i]}  ")  
        println(scores[i].toString().removeSurrounding("(", ")").replace(",", ""))
    }
    println()
}

fun printFractionalRankings(title: String, rankings: DoubleArray, scores: Array<Pair<Int, String>>) {
    println(title + ":")
    for (i in 0 until rankings.size) { 
        print ("${"%3.2f".format(rankings[i])}  ")  
        println(scores[i].toString().removeSurrounding("(", ")").replace(",", ""))
    }
    println()
}

fun main(args: Array<String>) {
    val scores = arrayOf(44 to "Solomon",  42 to "Jason", 42 to "Errol",  41 to "Garry",
                         41 to "Bernard",  41 to "Barry", 39 to "Stephen")
    printRankings("Standard ranking", standardRanking(scores), scores)
    printRankings("Modified ranking", modifiedRanking(scores), scores)
    printRankings("Dense ranking", denseRanking(scores), scores)
    printRankings("Ordinal ranking", ordinalRanking(scores), scores)
    printFractionalRankings("Fractional ranking", fractionalRanking(scores), scores)
}
Output:
Standard ranking:
1  44 Solomon
2  42 Jason
2  42 Errol
4  41 Garry
4  41 Bernard
4  41 Barry
7  39 Stephen

Modified ranking:
1  44 Solomon
3  42 Jason
3  42 Errol
6  41 Garry
6  41 Bernard
6  41 Barry
7  39 Stephen

Dense ranking:
1  44 Solomon
2  42 Jason
2  42 Errol
3  41 Garry
3  41 Bernard
3  41 Barry
4  39 Stephen

Ordinal ranking:
1  44 Solomon
2  42 Jason
3  42 Errol
4  41 Garry
5  41 Bernard
6  41 Barry
7  39 Stephen

Fractional ranking:
1.00  44 Solomon
2.50  42 Jason
2.50  42 Errol
5.00  41 Garry
5.00  41 Bernard
5.00  41 Barry
7.00  39 Stephen

Ksh

#!/bin/ksh
exec 2> /tmp/Ranking_methods.err
# Ranking methods
#
#	# Standard. (Ties share what would have been their first ordinal number).
#	# Modified. (Ties share what would have been their last ordinal number).
#	# Dense. (Ties share the next available integer).
#	# Ordinal. ((Competitors take the next available integer. Ties are not treated otherwise).
#	# Fractional. (Ties share the mean of what would have been their ordinal numbers)

#	# Variables:
#
typeset -a arr=( '44 Solomon' '42 Jason' '42 Errol' '41 Garry' '41 Bernard' '41 Barry' '39 Stephen' )
integer i

#	# Functions:
#

#	# Function _rankStandard(arr, rankarr) - retun arr with standard ranking
#
function _rankStandard {
	typeset _ranked ; nameref _ranked="$1"

	typeset _i _j _scr _currank _prevscr _shelf
	integer _i _j _scr _currank=1 _prevscr
	typeset -a _shelf

	for ((_i=0; _i<${#arr[*]}; _i++)); do
		_scr=${arr[_i]%\ *}
		if (( _i>0 )) && (( _scr != _prevscr )); then
			for ((_j=0; _j<${#_shelf[*]}; _j++)); do
				_ranked+=( "${_currank} ${_shelf[_j]}" )
			done
			(( _currank+=${#_shelf[*]} ))
			unset _shelf ; typeset -a _shelf
		fi
		_shelf+=( "${arr[_i]}" )
		_prevscr=${_scr}
	done
	for ((_j=0; _j<${#_shelf[*]}; _j++)); do
		_ranked+=( "${_currank} ${_shelf[_j]}" )
	done
}

#	# Function _rankModified(arr, rankarr) - retun arr with modified ranking
#
function _rankModified {
	typeset _ranked ; nameref _ranked="$1"

	typeset _i _j _scr _currank _prevscr _shelf
	integer _i _j _scr _currank=0 _prevscr
	typeset -a _shelf

	for ((_i=0; _i<${#arr[*]}; _i++)); do
		_scr=${arr[_i]%\ *}
		if (( _i>0 )) && (( _scr != _prevscr )); then
			for ((_j=0; _j<${#_shelf[*]}; _j++)); do
				_ranked+=( "${_currank} ${_shelf[_j]}" )
			done
			unset _shelf ; typeset -a _shelf
		fi
		_shelf+=( "${arr[_i]}" )
		(( _currank++ ))
		_prevscr=${_scr}
	done
	for ((_j=0; _j<${#_shelf[*]}; _j++)); do
		_ranked+=( "${_currank} ${_shelf[_j]}" )
	done
}

#	# Function _rankDense(arr, rankarr) - retun arr with dense ranking
#
function _rankDense {
	typeset _ranked ; nameref _ranked="$1"

	typeset _i _j _scr _currank _prevscr _shelf
	integer _i _j _scr _currank=0 _prevscr
	typeset -a _shelf

	for ((_i=0; _i<${#arr[*]}; _i++)); do
		_scr=${arr[_i]%\ *}
		if (( _i>0 )) && (( _scr != _prevscr )); then
			(( _currank++ ))
			for ((_j=0; _j<${#_shelf[*]}; _j++)); do
				_ranked+=( "${_currank} ${_shelf[_j]}" )
			done
			unset _shelf ; typeset -a _shelf
		fi
		_shelf+=( "${arr[_i]}" )
		_prevscr=${_scr}
	done
	(( _currank++ ))
	for ((_j=0; _j<${#_shelf[*]}; _j++)); do
		_ranked+=( "${_currank} ${_shelf[_j]}" )
	done
}

#	# Function _rankOrdinal(arr, rankarr) - retun arr with ordinal ranking
#
function _rankOrdinal {
	typeset _ranked ; nameref _ranked="$1"
	typeset _i ; integer _i

	for ((_i=0; _i<${#arr[*]}; _i++)); do
		_ranked+=( "$(( _i + 1 )) ${arr[_i]}" )
	done
}

#	# Function _rankFractional(arr, rankarr) - retun arr with Fractional ranking
#
function _rankFractional {
	typeset _ranked ; nameref _ranked="$1"

	typeset _i _j _scr _currank _prevscr _shelf
	integer _i _j _scr _prevscr
	typeset -F1 _currank=1.0
	typeset -a _shelf

	for ((_i=0; _i<${#arr[*]}; _i++)); do
		_scr=${arr[_i]%\ *}
		if (( _i>0 )) && (( _scr != _prevscr )); then
			(( _currank/=${#_shelf[*]} ))
			for ((_j=0; _j<${#_shelf[*]}; _j++)); do
				_ranked+=( "${_currank} ${_shelf[_j]}" )
			done
			_currank=0.0
			unset _shelf ; typeset -a _shelf
		fi
		(( _i>0 )) && (( _currank+=_i + 1 ))
		_shelf+=( "${arr[_i]}" )
		_prevscr=${_scr}
	done
	for ((_j=0; _j<${#_shelf[*]}; _j++)); do
		(( _currank/=${#_shelf[*]} ))
		_ranked+=( "${_currank} ${_shelf[_j]}" )
	done
}

 ######
# main #
 ######

printf "\n\nInput Data: ${#arr[*]} records\n---------------------\n"
for ((i=0; i< ${#arr[*]}; i++)); do
	print ${arr[i]}
done

typeset -a rankedarr
_rankStandard rankedarr
printf "\n\nStandard Ranking\n----------------\n"
for ((i=0; i< ${#rankedarr[*]}; i++)); do
	print ${rankedarr[i]}
done

unset rankedarr ; typeset -a rankedarr
_rankModified rankedarr
printf "\n\nModified Ranking\n----------------\n"
for ((i=0; i< ${#rankedarr[*]}; i++)); do
	print ${rankedarr[i]}
done

unset rankedarr ; typeset -a rankedarr
_rankDense rankedarr
printf "\n\nDense Ranking\n-------------\n"
for ((i=0; i< ${#rankedarr[*]}; i++)); do
	print ${rankedarr[i]}
done

unset rankedarr ; typeset -a rankedarr
_rankOrdinal rankedarr
printf "\n\nOrdinal Ranking\n---------------\n"
for ((i=0; i< ${#rankedarr[*]}; i++)); do
	print ${rankedarr[i]}
done

unset rankedarr ; typeset -a rankedarr
_rankFractional rankedarr
printf "\n\nFractional Ranking\n------------------\n"
for ((i=0; i< ${#rankedarr[*]}; i++)); do
	print ${rankedarr[i]}
done
Output:

Input Data: 7 records --------------------- 44 Solomon 42 Jason 42 Errol 41 Garry 41 Bernard 41 Barry 39 Stephen

Standard Ranking ---------------- 1 44 Solomon 2 42 Jason 2 42 Errol 4 41 Garry 4 41 Bernard 4 41 Barry 7 39 Stephen

Modified Ranking ---------------- 1 44 Solomon 3 42 Jason 3 42 Errol 6 41 Garry 6 41 Bernard 6 41 Barry 7 39 Stephen

Dense Ranking ------------- 1 44 Solomon 2 42 Jason 2 42 Errol 3 41 Garry 3 41 Bernard 3 41 Barry 4 39 Stephen

Ordinal Ranking --------------- 1 44 Solomon 2 42 Jason 3 42 Errol 4 41 Garry 5 41 Bernard 6 41 Barry 7 39 Stephen

Fractional Ranking ------------------ 1.0 44 Solomon 2.5 42 Jason 2.5 42 Errol 5.0 41 Garry 5.0 41 Bernard 5.0 41 Barry

7.0 39 Stephen


M2000 Interpreter

Module Ranking (output$, orderlist) {
	Open output$ for output as #k
	Gosub getdata
	Print #k, "Standard ranking:"
	skip=true
	rankval=1
	oldrank=0
	For i=1 to items
		Read rank, name$
		if skip then
			skip=false
		else.if oldrank<>rank then
			rankval=i
		end if
		oldrank=rank
		Print #k, Format$("{0::-5} {2} ({1})", rankval, rank, name$)
	Next
	Gosub getdata
	Print #k,  "Modified ranking:"
	skip=true
	rankval=Items
	oldrank=0
	ShiftBack 1, -items*2  ' reverse stack items
	For i=items to 1
		Read name$, rank
		if skip then
			skip=false
		else.if oldrank<>rank then
			rankval=i
		end if
		oldrank=rank
		Data Format$("{0::-5} {2} ({1})", rankval, rank, name$)
	Next
	ShiftBack 1, -items  ' reverse stack items
	For i=1 to items
		Print #k, letter$
	Next i
	Gosub getdata
	Print #k, "Dense ranking:"
	skip=true
	Dense=Stack
	acc=1
	oldrank=0
	For i=1 to items
		Read rank, name$
		if skip then
			skip=false
			oldrank=rank
		else.if  oldrank<>rank then
			oldrank=rank
			Gosub dense
			acc=i
		end if
		Stack Dense {data Format$(" {0} ({1})",name$, rank)}	
	Next
	Gosub dense
	Gosub getdata
	Print #k, "Ordinal ranking:"
	For i=1 to items
		Print #k, Format$("{0::-5} {2} ({1})", i, Number, letter$)
	Next
	Gosub getdata
	Print #k, "Fractional ranking:"
	skip=true
	Frac=Stack
	acc=1
	oldrank=0
	For i=1 to items
		Read rank, name$
		if skip then
			skip=false
			oldrank=rank
		else.if  oldrank<>rank then
			oldrank=rank
			Gosub Fractional
			acc=I
		end if
		Stack Frac {data Format$(" {0} ({1})",name$, rank)}	
	Next
	Gosub Fractional
	Close #k
	End
	Fractional:
		val=((len(Frac)+1)/2+(acc-1))
		Stack Frac {
			while not empty
				Print #k, format$("{0:1:-5}{1}", val, letter$)
			end while
		}
	Return
	dense:
		Stack Dense {
			while not empty
				Print #k, format$("{0::-5}{1}", acc, letter$)
			end while
		}
	Return
	getdata:
		flush
		stack stack(orderlist)  // place a copy of items to current stack
		items=stack.size/2
	Return
}
Flush
Data 44, "Solomon", 42, "Jason", 42, "Errol"
Data 41, "Garry", 41, "Bernard", 41, "Barry"
Data 39, "Stephen"
// get all items from current stack to a new stack
alist=[]
// To screen
Ranking "", alist
// To file
Ranking "ranking.txt", alist
Output:
Standard ranking:
    1 Solomon (44)
    2 Jason (42)
    2 Errol (42)
    4 Garry (41)
    4 Bernard (41)
    4 Barry (41)
    7 Stephen (39)
Modified ranking:
    1 Solomon (44)
    3 Jason (42)
    3 Errol (42)
    6 Garry (41)
    6 Bernard (41)
    6 Barry (41)
    7 Stephen (39)
Dense ranking:
    1 Solomon (44)
    2 Jason (42)
    2 Errol (42)
    4 Garry (41)
    4 Bernard (41)
    4 Barry (41)
    7 Stephen (39)
Ordinal ranking:
    1 Solomon (44)
    2 Jason (42)
    3 Errol (42)
    4 Garry (41)
    5 Bernard (41)
    6 Barry (41)
    7 Stephen (39)
Fractional ranking:
  1.0 Solomon (44)
  2.5 Jason (42)
  2.5 Errol (42)
  5.0 Garry (41)
  5.0 Bernard (41)
  5.0 Barry (41)
  7.0 Stephen (39)

Mathematica/Wolfram Language

data = Transpose@{{44, 42, 42, 41, 41, 41, 39}, {"Solomon", "Jason", 
     "Errol", "Garry", "Bernard", "Barry", "Stephen"}};

rank[data_, type_] :=
 Module[{t = Transpose@{Sort@data, Range[Length@data, 1, -1]}},
  Switch[type,
   "standard", data/.Rule@@@First/@SplitBy[t, First],
   "modified", data/.Rule@@@Last/@SplitBy[t, First],
   "dense", data/.Thread[#->Range[Length@#]]&@SplitBy[t, First][[All, 1, 1]],
   "ordinal", Reverse@Ordering[data],
   "fractional", data/.Rule@@@(Mean[#]/.{a_Rational:>N[a]}&)/@ SplitBy[t, First]]]

fmtRankedData[data_, type_] := 
 Labeled[Grid[
   SortBy[ArrayFlatten@{{Transpose@{rank[data[[All, 1]], type]}, 
       data}}, First], Alignment->Left], type<>" ranking:", Top]

Grid@{fmtRankedData[data, #] & /@ {"standard", "modified", "dense", 
    "ordinal", "fractional"}}
Output:
standard ranking:
1	44	Solomon
3	42	Errol
3	42	Jason
6	41	Barry
6	41	Bernard
6	41	Garry
7	39	Stephen

modified ranking:
1	44	Solomon
2	42	Errol
2	42	Jason
4	41	Barry
4	41	Bernard
4	41	Garry
7	39	Stephen

dense ranking:
1	39	Stephen
2	41	Barry
2	41	Bernard
2	41	Garry
3	42	Errol
3	42	Jason
4	44	Solomon

ordinal ranking:
1	44	Solomon
2	42	Errol
3	42	Jason
4	41	Barry
5	41	Bernard
6	41	Garry
7	39	Stephen

fractional ranking:
1	44	Solomon
2.5	42	Errol
2.5	42	Jason
5	41	Barry
5	41	Bernard
5	41	Garry
7	39	Stephen

Modula-2

Translation of: C
MODULE RankingMethods;
FROM FormatString IMPORT FormatString;
FROM RealStr IMPORT RealToFixed;
FROM Terminal IMPORT WriteString,WriteLn,ReadChar;

PROCEDURE WriteCard(c : CARDINAL);
VAR buf : ARRAY[0..15] OF CHAR;
BEGIN
    FormatString("%c", buf, c);
    WriteString(buf)
END WriteCard;

TYPE Entry = RECORD
    name : ARRAY[0..15] OF CHAR;
    score : CARDINAL;
END;

PROCEDURE OrdinalRanking(CONST entries : ARRAY OF Entry);
VAR
    buf : ARRAY[0..31] OF CHAR;
    i : CARDINAL;
BEGIN
    WriteString("Ordinal Ranking");
    WriteLn;
    WriteString("---------------");
    WriteLn;

    FOR i:=0 TO HIGH(entries) DO
        FormatString("%c\t%c\t%s\n", buf, i + 1, entries[i].score, entries[i].name);
        WriteString(buf)
    END;

    WriteLn
END OrdinalRanking;

PROCEDURE StandardRanking(CONST entries : ARRAY OF Entry);
VAR
    buf : ARRAY[0..31] OF CHAR;
    i,j : CARDINAL;
BEGIN
    WriteString("Standard Ranking");
    WriteLn;
    WriteString("---------------");
    WriteLn;

    j := 1;
    FOR i:=0 TO HIGH(entries) DO
        FormatString("%c\t%c\t%s\n", buf, j, entries[i].score, entries[i].name);
        WriteString(buf);
        IF entries[i+1].score < entries[i].score THEN
            j := i + 2
        END
    END;

    WriteLn
END StandardRanking;

PROCEDURE DenseRanking(CONST entries : ARRAY OF Entry);
VAR
    buf : ARRAY[0..31] OF CHAR;
    i,j : CARDINAL;
BEGIN
    WriteString("Dense Ranking");
    WriteLn;
    WriteString("---------------");
    WriteLn;

    j := 1;
    FOR i:=0 TO HIGH(entries) DO
        FormatString("%c\t%c\t%s\n", buf, j, entries[i].score, entries[i].name);
        WriteString(buf);
        IF entries[i+1].score < entries[i].score THEN
            INC(j)
        END
    END;

    WriteLn
END DenseRanking;

PROCEDURE ModifiedRanking(CONST entries : ARRAY OF Entry);
VAR
    buf : ARRAY[0..31] OF CHAR;
    i,j,count : CARDINAL;
BEGIN
    WriteString("Modified Ranking");
    WriteLn;
    WriteString("---------------");
    WriteLn;

    i := 0;
    j := 1;
    WHILE i < HIGH(entries) DO
        IF entries[i].score # entries[i+1].score THEN
            FormatString("%c\t%c\t%s\n", buf, i+1, entries[i].score, entries[i].name);
            WriteString(buf);

            count := 1;
            FOR j:=i+1 TO HIGH(entries)-1 DO
                IF entries[j].score # entries[j+1].score THEN
                    BREAK
                END;
                INC(count)
            END;

            j := 0;
            WHILE j < count-1 DO
                FormatString("%c\t%c\t%s\n", buf, i+count+1, entries[i+j+1].score, entries[i+j+1].name);
                WriteString(buf);
                INC(j)
            END;
            i := i + count - 1
        END;
        INC(i)
    END;

    FormatString("%c\t%c\t%s\n\n", buf, HIGH(entries)+1, entries[HIGH(entries)].score, entries[HIGH(entries)].name);
    WriteString(buf)
END ModifiedRanking;

PROCEDURE FractionalRanking(CONST entries : ARRAY OF Entry);
VAR
    buf : ARRAY[0..32] OF CHAR;
    i,j,count : CARDINAL;
    sum : REAL;
BEGIN
    WriteString("Fractional Ranking");
    WriteLn;
    WriteString("---------------");
    WriteLn;

    sum := 0.0;
    i := 0;
    WHILE i <= HIGH(entries) DO
        IF (i = HIGH(entries) - 1) OR (entries[i].score # entries[i+1].score) THEN
            RealToFixed(FLOAT(i+1),1,buf);
            WriteString(buf);
            FormatString("\t%c\t%s\n", buf, entries[i].score, entries[i].name);
            WriteString(buf)
        ELSE
            sum := FLOAT(i);
            count := 1;

            j := i;
            WHILE entries[j].score = entries[j+1].score DO
                sum := sum + FLOAT(j + 1);
                INC(count);
                INC(j)
            END;
            FOR j:=0 TO count-1 DO
                RealToFixed(sum/FLOAT(count)+1.0,1,buf);
                WriteString(buf);
                FormatString("\t%c\t%s\n", buf, entries[i+j].score, entries[i+j].name);
                WriteString(buf)
            END;
            i := i + count - 1
        END;
        INC(i)
    END
END FractionalRanking;

(* Main *)
TYPE EA = ARRAY[0..6] OF Entry;
VAR entries : EA;
BEGIN
    entries := EA{
        {"Solomon", 44},
        {"Jason", 42},
        {"Errol", 42},
        {"Garry", 41},
        {"Bernard", 41},
        {"Barry", 41},
        {"Stephen", 39}
    };

    OrdinalRanking(entries);
    StandardRanking(entries);
    DenseRanking(entries);
    ModifiedRanking(entries);
    FractionalRanking(entries);

    ReadChar
END RankingMethods.
Output:
Ordinal Ranking
---------------
1       44      Solomon
2       42      Jason
3       42      Errol
4       41      Garry
5       41      Bernard
6       41      Barry
7       39      Stephen

Standard Ranking
---------------
1       44      Solomon
2       42      Jason
2       42      Errol
4       41      Garry
4       41      Bernard
5       41      Barry
7       39      Stephen

Dense Ranking
---------------
1       44      Solomon
2       42      Jason
2       42      Errol
3       41      Garry
3       41      Bernard
3       41      Barry
4       39      Stephen

Modified Ranking
---------------
1       44      Solomon
3       42      Jason
3       42      Errol
6       41      Garry
6       41      Bernard
6       41      Barry
7       39      Stephen

Fractional Ranking
---------------
1.0     44      Solomon
2.5     42      Jason
2.5     42      Errol
5.0     41      Garry
5.0     41      Bernard
5.0     41      Barry
7.0     39      Stephen

Nim

Using an auxiliary table

To simplify, it’s convenient to build a table giving for each score the list of competitor names.

import algorithm, sequtils, stats, tables

type
  Record = tuple[score: int; name: string]                  # Input data.
  Groups = OrderedTable[int, seq[string]]                   # Maps score to list of names.
  Rank = tuple[rank: int; name: string; score: int]         # Result.
  FractRank = tuple[rank: float; name: string; score: int]  # Result (fractional).

func cmp(a, b: (int, seq[string])): int =
  ## Comparison function needed to sort the groups.
  cmp(a[0], b[0])

func toGroups(records: openArray[Record]): Groups =
  ## Build a "Groups" table from the records.
  for record in records:
    result.mgetOrPut(record.score, @[]).add record.name
  # Sort the list of names by alphabetic order.
  for score in result.keys:
    sort(result[score])
  # Sort the groups by decreasing score.
  result.sort(cmp, Descending)

func standardRanks(groups: Groups): seq[Rank] =
  var rank = 1
  for score, names in groups.pairs:
    for name in names:
      result.add (rank, name, score)
    inc rank, names.len

func modifiedRanks(groups: Groups): seq[Rank] =
  var rank = 0
  for score, names in groups.pairs:
    inc rank, names.len
    for name in names:
      result.add (rank, name, score)

func denseRanks(groups: Groups): seq[Rank] =
  var rank = 0
  for score, names in groups.pairs:
    inc rank
    for name in names:
      result.add (rank, name, score)

func ordinalRanks(groups: Groups): seq[Rank] =
  var rank = 0
  for score, names in groups.pairs:
    for name in names:
      inc rank
      result.add (rank, name, score)

func fractionalRanks(groups: Groups): seq[FractRank] =
  var rank = 1
  for score, names in groups.pairs:
    let fRank = mean(toSeq(rank..(rank + names.high)))
    for name in names:
      result.add (fRank, name, score)
    inc rank, names.len

when isMainModule:
  const Data = [(44, "Solomon"), (42, "Jason"), (42, "Errol"),
                (41, "Garry"), (41, "Bernard"), (41, "Barry"), (39, "Stephen")]

  let groups = Data.toGroups()
  echo "Standard ranking:"
  for (rank, name, score) in groups.standardRanks():
    echo rank, ": ", name, " ", score

  echo()
  echo "Modified ranking:"
  for (rank, name, score) in groups.modifiedRanks():
    echo rank, ": ", name, " ", score

  echo()
  echo "Dense ranking:"
  for (rank, name, score) in groups.denseRanks():
    echo rank, ": ", name, " ", score

  echo()
  echo "Ordinal ranking:"
  for (rank, name, score) in groups.ordinalRanks():
    echo rank, ": ", name, " ", score

  echo()
  echo "Fractional ranking:"
  for (rank, name, score) in groups.fractionalRanks():
    echo rank, ": ", name, " ", score
Output:
Standard ranking:
1: Solomon 44
2: Errol 42
2: Jason 42
4: Barry 41
4: Bernard 41
4: Garry 41
7: Stephen 39

Modified ranking:
1: Solomon 44
3: Errol 42
3: Jason 42
6: Barry 41
6: Bernard 41
6: Garry 41
7: Stephen 39

Dense ranking:
1: Solomon 44
2: Errol 42
2: Jason 42
3: Barry 41
3: Bernard 41
3: Garry 41
4: Stephen 39

Ordinal ranking:
1: Solomon 44
2: Errol 42
3: Jason 42
4: Barry 41
5: Bernard 41
6: Garry 41
7: Stephen 39

Fractional ranking:
1.0: Solomon 44
2.5: Errol 42
2.5: Jason 42
5.0: Barry 41
5.0: Bernard 41
5.0: Garry 41
7.0: Stephen 39

Without an auxiliary table

But it is possible to do the ranking without an auxiliary table.

import algorithm

type
  Record = tuple[score: int; name: string]                  # Input data.
  Rank = tuple[rank: int; name: string; score: int]         # Result.
  FractRank = tuple[rank: float; name: string; score: int]  # Result (fractional).

func cmp(a, b: Record): int =
  ## Record comparison function (needed for sorting).
  result = cmp(b[0], a[0])        # Reverse order.
  if result == 0:
    result = cmp(a.name, b.name)  # Alphabetical order.

func standardRanks(records: openArray[Record]): seq[Rank] =
  let records = sorted(records, cmp)
  var rank = 1
  var currScore = records[0].score
  for idx, (score, name) in records:
    if score != currScore:
      rank = idx + 1
      currScore = score
    result.add (rank, name, score)

func modifiedRanks(records: openArray[Record]): seq[Rank] =
  let records = sorted(records, cmp)
  var rank = records.len
  var currScore = records[^1].score
  for idx in countdown(records.high, 0):
    let (score, name) = records[idx]
    if score != currScore:
      rank = idx + 1
      currScore = score
    result.add (rank, name, score)
  result.reverse()

func denseRanks(records: openArray[Record]): seq[Rank] =
  let records = sorted(records, cmp)
  var rank = 1
  var currScore = records[0].score
  for (score, name) in records:
    if score != currScore:
      inc rank
      currScore = score
    result.add (rank, name, score)

func ordinalRanks(records: openArray[Record]): seq[Rank] =
  let records = sorted(records, cmp)
  var rank = 0
  for (score, name) in records:
    inc rank
    result.add (rank, name, score)

func fractionalRanks(records: openArray[Record]): seq[FractRank] =
  let records = sorted(records, cmp)
  
  # Build a list of ranks.
  var currScore = records[0].score
  var sum = 0
  var ranks: seq[float]
  var count = 0
  for idx, record in records:
    if record.score == currScore:
      inc count
      inc sum, idx + 1
    else:
      ranks.add sum / count
      count = 1
      currScore = record.score
      sum = idx + 1
  ranks.add sum / count

  # Give a rank to each record.
  currScore = records[0].score
  var rankIndex = 0
  for (score, name) in records:
    if score != currScore:
      inc rankIndex
      currScore = score
    result.add (ranks[rankIndex], name, score)

when isMainModule:

  const Data = [(44, "Solomon"), (42, "Jason"), (42, "Errol"),
                (41, "Garry"), (41, "Bernard"), (41, "Barry"), (39, "Stephen")]

  echo "Standard ranking:"
  for (rank, name, score) in Data.standardRanks():
    echo rank, ": ", name, " ", score

  echo()
  echo "Modified ranking:"
  for (rank, name, score) in Data.modifiedRanks():
    echo rank, ": ", name, " ", score

  echo()
  echo "Dense ranking:"
  for (rank, name, score) in Data.denseRanks():
    echo rank, ": ", name, " ", score

  echo()
  echo "Ordinal ranking:"
  for (rank, name, score) in Data.ordinalRanks():
    echo rank, ": ", name, " ", score

  echo()
  echo "Fractional ranking:"
  for (rank, name, score) in Data.fractionalRanks():
    echo rank, ": ", name, " ", score
Output:
Same output as with other version.

PARI/GP

Replace "2" with "2.0" in fractional if you prefer decimal to fractional.

standard(v)=v=vecsort(v,1,4); my(last=v[1][1]+1); for(i=1,#v, v[i][1]=if(v[i][1]<last,last=v[i][1]; i, v[i-1][1])); v;
modified(v)=v=vecsort(v,1,4); my(last=v[#v][1]-1); forstep(i=#v,1,-1, v[i][1]=if(v[i][1]>last,last=v[i][1]; i, v[i+1][1])); v;
dense(v)=v=vecsort(v,1,4); my(last=v[1][1]+1,rank); for(i=1,#v, v[i][1]=if(v[i][1]<last,last=v[i][1]; rank++, rank)); v;
ordinal(v)=v=vecsort(v,1,4); for(i=1,#v,v[i][1]=i); v;
fractional(v)=my(a=standard(v),b=modified(v)); vector(#v,i,[(a[i][1]+b[i][1])/2,v[i][2]]);

v=[[44,"Solomon"], [42,"Jason"], [42,"Errol"], [41,"Garry"], [41,"Bernard"], [41,"Barry"], [39,"Stephen"]];
standard(v)
modified(v)
dense(v)
ordinal(v)
fractional(v)
Output:
%1 = [[1, "Solomon"], [2, "Errol"], [2, "Jason"], [4, "Barry"], [4, "Bernard"], [4, "Garry"], [7, "Stephen"]]
%2 = [[1, "Solomon"], [3, "Errol"], [3, "Jason"], [6, "Barry"], [6, "Bernard"], [6, "Garry"], [7, "Stephen"]]
%3 = [[1, "Solomon"], [2, "Errol"], [2, "Jason"], [3, "Barry"], [3, "Bernard"], [3, "Garry"], [4, "Stephen"]]
%4 = [[1, "Solomon"], [2, "Errol"], [3, "Jason"], [4, "Barry"], [5, "Bernard"], [6, "Garry"], [7, "Stephen"]]
%5 = [[1, "Solomon"], [5/2, "Jason"], [5/2, "Errol"], [5, "Garry"], [5, "Bernard"], [5, "Barry"], [7, "Stephen"]]

Perl

Translation of: Raku
my %scores = (
    'Solomon' => 44,
    'Jason'   => 42,
    'Errol'   => 42,
    'Garry'   => 41,
    'Bernard' => 41,
    'Barry'   => 41,
    'Stephen' => 39
);

sub tiers {
    my(%s) = @_; my(%h);
    push @{$h{$s{$_}}}, $_ for keys %s;
    @{\%h}{reverse sort keys %h};
}

sub standard {
    my(%s) = @_; my($result);
    my $rank = 1;
    for my $players (tiers %s) {
        $result .= "$rank " . join(', ', sort @$players) . "\n";
        $rank += @$players;
    }
    return $result;
}

sub modified {
    my(%s) = @_; my($result);
    my $rank = 0;
    for my $players (tiers %s) {
        $rank += @$players;
        $result .= "$rank " . join(', ', sort @$players) . "\n";
    }
    return $result;
}

sub dense {
    my(%s) = @_; my($n,$result);
    $result .= sprintf "%d %s\n", ++$n, join(', ', sort @$_) for tiers %s;
    return $result;
}

sub ordinal {
    my(%s) = @_; my($n,$result);
    for my $players (tiers %s) {
        $result .= sprintf "%d %s\n", ++$n, $_ for sort @$players;
    }
    return $result;
}

sub fractional {
    my(%s) = @_; my($result);
    my $rank = 1;
    for my $players (tiers %s) {
        my $beg = $rank;
        my $end = $rank += @$players;
        my $avg = 0;
        $avg += $_/@$players for $beg .. $end-1;
        $result .= sprintf "%3.1f %s\n", $avg, join ', ', sort @$players;
    }
    return $result;
}

print "Standard:\n"    .   standard(%scores) . "\n";
print "Modified:\n"    .   modified(%scores) . "\n";
print "Dense:\n"       .      dense(%scores) . "\n";
print "Ordinal:\n"     .    ordinal(%scores) . "\n";
print "Fractional:\n"  . fractional(%scores) . "\n";
Output:
Standard:
1 Solomon
2 Errol, Jason
4 Barry, Bernard, Garry
7 Stephen

Modified:
1 Solomon
3 Errol, Jason
6 Barry, Bernard, Garry
7 Stephen

Dense:
1 Solomon
2 Errol, Jason
3 Barry, Bernard, Garry
4 Stephen

Ordinal:
1 Solomon
2 Errol
3 Jason
4 Barry
5 Bernard
6 Garry
7 Stephen

Fractional:
1.0 Solomon
2.5 Errol, Jason
5.0 Barry, Bernard, Garry
7.0 Stephen

Phix

with javascript_semantics
function ties(sequence scores)
    sequence t = {}, -- {start,num} pairs
             tdx = repeat(0,length(scores))
    integer last = -1
    for i=1 to length(scores) do
        integer curr = scores[i][1]
        if curr=last then
            t[$][2] += 1
        else
            t = append(t,{i,1})
        end if
        tdx[i] = length(t)
        last = curr
    end for
    -- eg {{{1,1},{2,2},{4,3},{7,1}},
    --     {1,2,2,3,3,3,4}}
    return {t,tdx}
end function
 
enum STANDARD,  -- eg {1,2,2,4,4,4,7}
     MODIFIED,  -- eg {1,3,3,6,6,6,7}
     DENSE,     -- (==tdx)
     ORDINAL,   -- eg {1,2,3,4,5,6,7}
     FRACTION,  -- {1,2.5,2.5,5,5,5,7}
     METHODS = $
 
function rank(integer i, method, sequence t, tdx)
    integer idx = tdx[i],
            {tx,tn} = t[idx]
    switch method
        case STANDARD: return tx
        case MODIFIED: return tx+tn-1
        case DENSE   : return idx
        case ORDINAL : return i
        case FRACTION: return tx+(tn-1)/2
    end switch
end function
 
constant scores = {{44, "Solomon"},
                   {42, "Jason"},
                   {42, "Errol"},
                   {41, "Garry"},
                   {41, "Bernard"},
                   {41, "Barry"},
                   {39, "Stephen"}}
 
sequence {t,tdx} = ties(scores)
printf(1," score name     standard modified dense ordinal fractional\n")
for i=1 to length(scores) do
    sequence ranks = repeat(0,METHODS)
    for method=1 to METHODS do
        ranks[method] = rank(i,method,t,tdx)
    end for
    printf(1,"%5d  %-7s ",scores[i])
    printf(1,"%6g %8g %6g %6g %9g\n",ranks)
end for
Output:
 score name     standard modified dense ordinal fractional
   44  Solomon      1        1      1      1         1
   42  Jason        2        3      2      2       2.5
   42  Errol        2        3      2      3       2.5
   41  Garry        4        6      3      4         5
   41  Bernard      4        6      3      5         5
   41  Barry        4        6      3      6         5
   39  Stephen      7        7      4      7         7

PowerShell

function Get-Ranking
{
    [CmdletBinding(DefaultParameterSetName="Standard")]
    [OutputType([PSCustomObject])]
    Param
    (
        [Parameter(Mandatory=$true,
                   ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true,
                   Position=0)]
        [string]
        $InputObject,

        [Parameter(Mandatory=$false,
                   ParameterSetName="Standard")]
        [switch]
        $Standard,

        [Parameter(Mandatory=$false,
                   ParameterSetName="Modified")]
        [switch]
        $Modified,

        [Parameter(Mandatory=$false,
                   ParameterSetName="Dense")]
        [switch]
        $Dense,

        [Parameter(Mandatory=$false,
                   ParameterSetName="Ordinal")]
        [switch]
        $Ordinal,

        [Parameter(Mandatory=$false,
                   ParameterSetName="Fractional")]
        [switch]
        $Fractional
    )

    Begin
    {
        function Get-OrdinalRank ([PSCustomObject[]]$Values)
        {
            for ($i = 0; $i -lt $Values.Count; $i++)
            { 
                $Values[$i].Rank = $i + 1
            }

            $Values
        }

        function Get-Rank ([PSCustomObject[]]$Scores)
        {
            foreach ($score in $Scores)
            {
                $score.Group | ForEach-Object {$_.Rank = $score.Rank}
            }

            $Scores.Group
        }

        function New-Competitor ([string]$Name, [int]$Score, [int]$Rank = 0)
        {
            [PSCustomObject]@{
                Name  = $Name
                Score = $Score
                Rank  = $Rank
            }
        }

        $competitors = @()
        $scores = @()
    }
    Process
    {
        @($input) | ForEach-Object {$competitors += New-Competitor -Name $_.Split()[1] -Score $_.Split()[0]}
    }
    End
    {
        $scores = $competitors |
            Sort-Object   -Property Score -Descending |
            Group-Object  -Property Score |
            Select-Object -Property @{Name="Score"; Expression={[int]$_.Name}}, @{Name="Rank"; Expression={0}}, Count, Group

        switch ($PSCmdlet.ParameterSetName)
        {
            "Standard"
            {
                $rank = 1

                for ($i = 0; $i -lt $scores.Count; $i++)
                { 
                    $scores[$i].Rank = $rank
                    $rank += $scores[$i].Count
                }

                Get-Rank $scores
            }
            "Modified"
            {
                $rank = 0

                foreach ($score in $scores)
                {
                    $rank = $score.Count + $rank
                    $score.Rank = $rank
                }

                Get-Rank $scores
            }
            "Dense"
            {
                for ($i = 0; $i -lt $scores.Count; $i++)
                { 
                    $scores[$i].Rank = $i + 1
                }

                Get-Rank $scores
            }
            "Ordinal"
            {
                Get-OrdinalRank $competitors
            }
            "Fractional"
            {
                Get-OrdinalRank $competitors | Group-Object -Property Score | ForEach-Object {
                    if ($_.Count -gt 1)
                    {
                        $rank = ($_.Group.Rank | Measure-Object -Average).Average

                        foreach ($competitor in $_.Group)
                        {
                            $competitor.Rank = $rank
                        }
                    }
                }

                $competitors
            }
        }
    }
}
$scores = "44 Solomon","42 Jason","42 Errol","41 Garry","41 Bernard","41 Barry","39 Stephen"
$scores | Get-Ranking -Standard
Output:
Name    Score Rank
----    ----- ----
Solomon    44    1
Jason      42    2
Errol      42    2
Garry      41    4
Bernard    41    4
Barry      41    4
Stephen    39    7
$scores | Get-Ranking -Modified
Output:
Name    Score Rank
----    ----- ----
Solomon    44    1
Jason      42    3
Errol      42    3
Garry      41    6
Bernard    41    6
Barry      41    6
Stephen    39    7
$scores | Get-Ranking -Dense
Output:
Name    Score Rank
----    ----- ----
Solomon    44    1
Jason      42    2
Errol      42    2
Garry      41    3
Bernard    41    3
Barry      41    3
Stephen    39    4
$scores | Get-Ranking -Ordinal
Output:
Name    Score Rank
----    ----- ----
Solomon    44    1
Jason      42    2
Errol      42    3
Garry      41    4
Bernard    41    5
Barry      41    6
Stephen    39    7
$scores | Get-Ranking -Fractional
Output:
Name    Score Rank
----    ----- ----
Solomon    44    1
Jason      42  2.5
Errol      42  2.5
Garry      41    5
Bernard    41    5
Barry      41    5
Stephen    39    7

Python

def mc_rank(iterable, start=1):
    """Modified competition ranking"""
    lastresult, fifo = None, []
    for n, item in enumerate(iterable, start-1):
        if item[0] == lastresult:
            fifo += [item]
        else:
            while fifo:
                yield n, fifo.pop(0)
            lastresult, fifo = item[0], fifo + [item]
    while fifo:
        yield n+1, fifo.pop(0)


def sc_rank(iterable, start=1):
    """Standard competition ranking"""
    lastresult, lastrank = None, None
    for n, item in enumerate(iterable, start):
        if item[0] == lastresult:
            yield lastrank, item
        else:
            yield n, item
            lastresult, lastrank = item[0], n


def d_rank(iterable, start=1):
    """Dense ranking"""
    lastresult, lastrank = None, start - 1,
    for item in iterable:
        if item[0] == lastresult:
            yield lastrank, item
        else:
            lastresult, lastrank = item[0], lastrank + 1
            yield lastrank, item


def o_rank(iterable, start=1):
    """Ordinal  ranking"""
    yield from enumerate(iterable, start)


def f_rank(iterable, start=1):
    """Fractional ranking"""
    last, fifo = None, []
    for n, item in enumerate(iterable, start):
        if item[0] != last:
            if fifo:
                mean = sum(f[0] for f in fifo) / len(fifo)
                while fifo:
                    yield mean, fifo.pop(0)[1]
        last = item[0]
        fifo.append((n, item))
    if fifo:
        mean = sum(f[0] for f in fifo) / len(fifo)
        while fifo:
            yield mean, fifo.pop(0)[1]


if __name__ == '__main__':
    scores = [(44, 'Solomon'),
              (42, 'Jason'),
              (42, 'Errol'),
              (41, 'Garry'),
              (41, 'Bernard'),
              (41, 'Barry'),
              (39, 'Stephen')]

    print('\nScores to be ranked (best first):')
    for s in scores:
        print('        %2i %s' % (s ))
    for ranker in [sc_rank, mc_rank, d_rank, o_rank, f_rank]:
        print('\n%s:' % ranker.__doc__)
        for rank, score in ranker(scores):
            print('  %3g, %r' % (rank, score))
Output:
Scores to be ranked (best first):
        44 Solomon
        42 Jason
        42 Errol
        41 Garry
        41 Bernard
        41 Barry
        39 Stephen

Standard competition ranking:
    1, (44, 'Solomon')
    2, (42, 'Jason')
    2, (42, 'Errol')
    4, (41, 'Garry')
    4, (41, 'Bernard')
    4, (41, 'Barry')
    7, (39, 'Stephen')

Modified competition ranking:
    1, (44, 'Solomon')
    3, (42, 'Jason')
    3, (42, 'Errol')
    6, (41, 'Garry')
    6, (41, 'Bernard')
    6, (41, 'Barry')
    7, (39, 'Stephen')

Dense ranking:
    1, (44, 'Solomon')
    2, (42, 'Jason')
    2, (42, 'Errol')
    3, (41, 'Garry')
    3, (41, 'Bernard')
    3, (41, 'Barry')
    4, (39, 'Stephen')

Ordinal  ranking:
    1, (44, 'Solomon')
    2, (42, 'Jason')
    3, (42, 'Errol')
    4, (41, 'Garry')
    5, (41, 'Bernard')
    6, (41, 'Barry')
    7, (39, 'Stephen')

Fractional ranking:
    1, (44, 'Solomon')
  2.5, (42, 'Jason')
  2.5, (42, 'Errol')
    5, (41, 'Garry')
    5, (41, 'Bernard')
    5, (41, 'Barry')
    7, (39, 'Stephen')

Racket

#lang racket
;; Tim-brown 2014-09-11

;; produces a ranking according to ranking function: rfn
;; INPUT:
;;  lst : (list (score . details))
;;  rfn : (length-scores)
;;         -> (values
;;              ranks-added                  ; how many ranks to add for the next iteration
;;              (idx . rest -> rank-offset)) ; function that produces the rank for the idx^th element
;;                                           ; in the scoring (arity must be >= 1)
(define (rank-list all-scores rfn)
  (let loop ((rank-0 0) (lst (sort all-scores > #:key car)) (acc empty))
    (cond
      [(null? lst) acc]
      [else
       (define 1st-score (caar lst))
       (define (ties-with-1st? cand) (= (car cand) 1st-score))
       (define-values (tied unranked) (splitf-at lst ties-with-1st?))
       ;; all ranking functions should properly handle a singleton tied list
       (define tied-len (length tied))
       (define tied? (> tied-len 1))
       (define-values (ranks-added rank-offset-fn) (rfn tied-len))
       (define ranked-tied (for/list ((t (in-list tied)) (i (in-naturals 1)))
                             (list* tied? (+ rank-0 (rank-offset-fn i)) t)))
       (loop (+ ranks-added rank-0) unranked (append acc ranked-tied))])))

;; Ties share what would have been their first ordinal number
(define (rank-function:Standard l) 
  (values l (thunk* 1)))

;; Ties share what would have been their last ordinal number
(define (rank-function:Modified l)
  (values l (thunk* l)))

;; Ties share the next available integer  
(define (rank-function:Dense l)
  (values 1 (thunk* 1)))

;; Competitors take the next available integer. Ties are not treated otherwise
(define (rank-function:Ordinal l)
  (values l (λ (n . _) n)))

;; Ties share the mean of what would have been their ordinal numbers
(define (rank-function:Fractional l)
  (values l (thunk* (/ (+ l 1) 2))))

(define score-board
  '((44 . Solomon)
    (42 . Jason)
    (42 . Errol)
    (41 . Garry)
    (41 . Bernard)
    (41 . Barry)
    (39 . Stephen)))

(define format-number
  (match-lambda
    [(? integer? i) i]
    [(and f (app numerator n) (app denominator d))
     (define-values (q r) (quotient/remainder n d))
     (format "~a ~a/~a" q r d)]))

(for ((fn (list
           rank-function:Standard
           rank-function:Modified
           rank-function:Dense
           rank-function:Ordinal
           rank-function:Fractional)))
  (printf "Function: ~s~%" fn)
  (for ((r (in-list (rank-list score-board fn))))
    (printf "~a ~a\t~a\t~a~%"
            (if (car r) "=" " ")
            (format-number (cadr r))
            (caddr r)
            (cdddr r)))
  (newline))
Output:
Function: #<procedure:rank-function:Standard>
  1	44	Solomon
= 2	42	Jason
= 2	42	Errol
= 4	41	Garry
= 4	41	Bernard
= 4	41	Barry
  7	39	Stephen

Function: #<procedure:rank-function:Modified>
  1	44	Solomon
= 3	42	Jason
= 3	42	Errol
= 6	41	Garry
= 6	41	Bernard
= 6	41	Barry
  7	39	Stephen

Function: #<procedure:rank-function:Dense>
  1	44	Solomon
= 2	42	Jason
= 2	42	Errol
= 3	41	Garry
= 3	41	Bernard
= 3	41	Barry
  4	39	Stephen

Function: #<procedure:rank-function:Ordinal>
  1	44	Solomon
= 2	42	Jason
= 3	42	Errol
= 4	41	Garry
= 5	41	Bernard
= 6	41	Barry
  7	39	Stephen

Function: #<procedure:rank-function:Fractional>
  1	44	Solomon
= 2 1/2	42	Jason
= 2 1/2	42	Errol
= 5	41	Garry
= 5	41	Bernard
= 5	41	Barry
  7	39	Stephen

Raku

(formerly Perl 6)

my @scores =
    Solomon => 44,
    Jason   => 42,
    Errol   => 42,
    Garry   => 41,
    Bernard => 41,
    Barry   => 41,
    Stephen => 39;

sub tiers (@s) { @s.classify(*.value).pairs.sort.reverse.map: { .value».key } }

sub standard (@s) {
    my $rank = 1;
    gather for tiers @s -> @players {
	take $rank => @players;
	$rank += @players;
    }
}

sub modified (@s) {
    my $rank = 0;
    gather for tiers @s -> @players {
	$rank += @players;
	take $rank => @players;
    }
}

sub dense (@s) { tiers(@s).map: { ++$_ => @^players } }

sub ordinal (@s) { @s.map: ++$_ => *.key }

sub fractional (@s) {
    my $rank = 1;
    gather for tiers @s -> @players {
	my $beg = $rank;
	my $end = $rank += @players;
	take [+]($beg ..^ $end) / @players => @players;
    }
}

say   "Standard:";   .perl.say for   standard @scores;
say "\nModified:";   .perl.say for   modified @scores;
say "\nDense:";      .perl.say for      dense @scores;
say "\nOrdinal:";    .perl.say for    ordinal @scores;
say "\nFractional:"; .perl.say for fractional @scores;
Output:
Standard:
1 => ["Solomon"]
2 => ["Jason", "Errol"]
4 => ["Garry", "Bernard", "Barry"]
7 => ["Stephen"]

Modified:
1 => ["Solomon"]
3 => ["Jason", "Errol"]
6 => ["Garry", "Bernard", "Barry"]
7 => ["Stephen"]

Dense:
1 => ["Solomon"]
2 => ["Jason", "Errol"]
3 => ["Garry", "Bernard", "Barry"]
4 => ["Stephen"]

Ordinal:
1 => "Solomon"
2 => "Jason"
3 => "Errol"
4 => "Garry"
5 => "Bernard"
6 => "Barry"
7 => "Stephen"

Fractional:
1.0 => ["Solomon"]
2.5 => ["Jason", "Errol"]
5.0 => ["Garry", "Bernard", "Barry"]
7.0 => ["Stephen"]

REXX

/**************************
44 Solomon  1 1 1 1 1
42 Jason    2 3 2 2 2.5
42 Errol    2 3 2 3 2.5
41 Garry    4 6 3 4 5
41 Bernard  4 6 3 5 5
41 Barry    4 6 3 6 5
39 Stephen  7 7 4 7 7
**************************/
Do i=1 To 7
  Parse Value sourceline(i+1) With rank.i name.i .
  /* say rank.i name.i */
  End
pool=0
crank=0
Do i=1 To 7
  If rank.i<>crank Then Do
    pool=pool+1
    lo.pool=i
    hi.pool=i
    n.pool=1
    ii.pool=i
    End
  Else Do
    n.pool=n.pool+1
    hi.pool=i
    ii.pool=ii.pool+i
    End
  crank=rank.i
  pool.i=pool
  End
/*
Do j=1 To pool
  Say 'pool' j n.j lo.j hi.j
  End
*/
cp=0
r=0
cnt.=0
Do i=1 To 7
  p=pool.i
  If p<>cp Then
    r=r+1
  res=rank.i left(name.i,8) lo.p hi.p r i ii.p/n.p
  If res=sourceline(i+1) Then cnt.ok=cnt.ok+1
  Say res
  cp=p
  End
Say cnt.ok 'correct lines'
Output:
44 Solomon  1 1 1 1 1
42 Jason    2 3 2 2 2.5
42 Errol    2 3 2 3 2.5
41 Garry    4 6 3 4 5
41 Bernard  4 6 3 5 5
41 Barry    4 6 3 6 5
39 Stephen  7 7 4 7 7
7 correct lines

Ruby

ar = "44 Solomon
42 Jason
42 Errol
41 Garry
41 Bernard
41 Barry
39 Stephen".lines.map{|line| line.split}
grouped = ar.group_by{|pair| pair.shift.to_i}
s_rnk = 1
m_rnk = o_rnk = 0
puts "stand.\tmod.\tdense\tord.\tfract."

grouped.each.with_index(1) do |(score, names), d_rnk|
  m_rnk += names.flatten!.size
  f_rnk = (s_rnk + m_rnk)/2.0
  names.each do |name|
    o_rnk += 1
    puts "#{s_rnk}\t#{m_rnk}\t#{d_rnk}\t#{o_rnk}\t#{f_rnk.to_s.sub(".0","")}\t#{score} #{name}"
  end
  s_rnk += names.size
end
Output:
stand.	mod.	dense	ord.	fract.
1	1	1	1	1	44 Solomon
2	3	2	2	2.5	42 Jason
2	3	2	3	2.5	42 Errol
4	6	3	4	5	41 Garry
4	6	3	5	5	41 Bernard
4	6	3	6	5	41 Barry
7	7	4	7	7	39 Stephen

Scala

This example uses a type-safe singly-linked object model with no mutable state variables, which makes it longer than the Ruby version above, but demonstrates an object-oriented functional programming approach.

object RankingMethods extends App {
    case class Score(score: Int, name: String) // incoming data
    case class Rank[Precision](rank: Precision, names: List[String]) // outgoing results (can be int or double)
    case class State[Precision](n: Int, done: List[Rank[Precision]]) { // internal state, no mutable variables
        def next(n: Int, next: Rank[Precision]) = State(n, next :: done)
    }
    def grouped[Precision](list: List[Score]) = // group names together by score, with highest first
        (scala.collection.immutable.TreeMap[Int, List[Score]]() ++ list.groupBy(-_.score))
        .values.map(_.map(_.name)).foldLeft(State[Precision](1, Nil)) _

    // Ranking methods:

    def rankStandard(list: List[Score]) =
        grouped[Int](list){case (state, names) => state.next(state.n+names.length, Rank(state.n, names))}.done.reverse

    def rankModified(list: List[Score]) =
        rankStandard(list).map(r => Rank(r.rank+r.names.length-1, r.names))

    def rankDense(list: List[Score]) =
        grouped[Int](list){case (state, names) => state.next(state.n+1, Rank(state.n, names))}.done.reverse

    def rankOrdinal(list: List[Score]) =
        list.zipWithIndex.map{case (score, n) => Rank(n+1, List(score.name))}

    def rankFractional(list: List[Score]) =
        rankStandard(list).map(r => Rank((2*r.rank+r.names.length-1.0)/2, r.names))

    // Tests:

    def parseScores(s: String) = s split "\\s+" match {case Array(s,n) => Score(s.toInt, n)}
    val test = List("44 Solomon", "42 Jason", "42 Errol", "41 Garry", "41 Bernard", "41 Barry", "39 Stephen").map(parseScores)

    println("Standard:")
    println(rankStandard(test) mkString "\n")
    println("\nModified:")
    println(rankModified(test) mkString "\n")
    println("\nDense:")
    println(rankDense(test) mkString "\n")
    println("\nOrdinal:")
    println(rankOrdinal(test) mkString "\n")
    println("\nFractional:")
    println(rankFractional(test) mkString "\n")

}
Output:
Standard:
Rank(1,List(Solomon))
Rank(2,List(Jason, Errol))
Rank(4,List(Garry, Bernard, Barry))
Rank(7,List(Stephen))

Modified:
Rank(1,List(Solomon))
Rank(3,List(Jason, Errol))
Rank(6,List(Garry, Bernard, Barry))
Rank(7,List(Stephen))

Dense:
Rank(1,List(Solomon))
Rank(2,List(Jason, Errol))
Rank(3,List(Garry, Bernard, Barry))
Rank(4,List(Stephen))

Ordinal:
Rank(1,List(Solomon))
Rank(2,List(Jason))
Rank(3,List(Errol))
Rank(4,List(Garry))
Rank(5,List(Bernard))
Rank(6,List(Barry))
Rank(7,List(Stephen))

Fractional:
Rank(1.0,List(Solomon))
Rank(2.5,List(Jason, Errol))
Rank(5.0,List(Garry, Bernard, Barry))
Rank(7.0,List(Stephen))

Sidef

Translation of: Raku
var scores = [
    Pair(Solomon => 44),
    Pair(Jason   => 42),
    Pair(Errol   => 42),
    Pair(Garry   => 41),
    Pair(Bernard => 41),
    Pair(Barry   => 41),
    Pair(Stephen => 39),
]

func tiers(s) {
    s.group_by { .value }.kv.sort.flip.map { .value.map{.key} }
}

func standard(s) {
    var rank = 1
    gather {
        for players in tiers(s) {
            take(Pair(rank, players))
            rank += players.len
        }
    }
}

func modified(s) {
    var rank = 0
    gather {
        for players in tiers(s) {
            rank += players.len
            take(Pair(rank, players))
        }
    }
}

func dense(s) {
    tiers(s).map_kv { |k,v| Pair(k+1, v) }
}

func ordinal(s) {
    s.map_kv { |k,v| Pair(k+1, v.key) }
}

func fractional(s) {
    var rank = 1
    gather {
        for players in tiers(s) {
            var beg = rank
            var end = (rank += players.len)
            take(Pair(sum(beg ..^ end) / players.len, players))
        }
    }
}

func display(r) {
    say r.map {|a| '%3s : %s' % a... }.join("\n")
}

say   "Standard:";   display(  standard(scores))
say "\nModified:";   display(  modified(scores))
say "\nDense:";      display(     dense(scores))
say "\nOrdinal:";    display(   ordinal(scores))
say "\nFractional:"; display(fractional(scores))
Output:
Standard:
  1 : ["Solomon"]
  2 : ["Jason", "Errol"]
  4 : ["Garry", "Bernard", "Barry"]
  7 : ["Stephen"]

Modified:
  1 : ["Solomon"]
  3 : ["Jason", "Errol"]
  6 : ["Garry", "Bernard", "Barry"]
  7 : ["Stephen"]

Dense:
  1 : ["Solomon"]
  2 : ["Jason", "Errol"]
  3 : ["Garry", "Bernard", "Barry"]
  4 : ["Stephen"]

Ordinal:
  1 : Solomon
  2 : Jason
  3 : Errol
  4 : Garry
  5 : Bernard
  6 : Barry
  7 : Stephen

Fractional:
  1 : ["Solomon"]
2.5 : ["Jason", "Errol"]
  5 : ["Garry", "Bernard", "Barry"]
  7 : ["Stephen"]

Tcl

proc rank {rankingMethod sortedList} {
    # Extract the groups in the data (this is pointless for ordinal...)
    set s [set group [set groups {}]]
    foreach {score who} $sortedList {
	if {$score != $s} {
	    lappend groups [llength $group]
	    set s $score
	    set group {}
	}
	lappend group $who
    }
    lappend groups [llength $group]
    # Construct the rankings; note that we have a zero-sized leading group
    set n 1; set m 0
    foreach g $groups {
	switch $rankingMethod {
	    standard {
		lappend result {*}[lrepeat $g $n]
		incr n $g
	    }
	    modified {
		lappend result {*}[lrepeat $g [incr m $g]]
	    }
	    dense {
		lappend result {*}[lrepeat $g $m]
		incr m
	    }
	    ordinal {
		for {set i 0} {$i < $g} {incr i} {
		    lappend result [incr m]
		}
	    }
	    fractional {
		set val [expr {($n + [incr n $g] - 1) / 2.0}]
		lappend result {*}[lrepeat $g [format %g $val]]
	    }
	}
    }
    return $result
}

set data {
    44 Solomon
    42 Jason
    42 Errol
    41 Garry
    41 Bernard
    41 Barry
    39 Stephen
}
foreach method {standard modified dense ordinal fractional} {
    puts "Using method '$method'...\n  Rank\tScore\tWho"
    foreach rank [rank $method $data] {score who} $data {
	puts "  $rank\t$score\t$who"
    }
}
Output:
Using method 'standard'...
  Rank	Score	Who
  1	44	Solomon
  2	42	Jason
  2	42	Errol
  4	41	Garry
  4	41	Bernard
  4	41	Barry
  7	39	Stephen
Using method 'modified'...
  Rank	Score	Who
  1	44	Solomon
  3	42	Jason
  3	42	Errol
  6	41	Garry
  6	41	Bernard
  6	41	Barry
  7	39	Stephen
Using method 'dense'...
  Rank	Score	Who
  1	44	Solomon
  2	42	Jason
  2	42	Errol
  3	41	Garry
  3	41	Bernard
  3	41	Barry
  4	39	Stephen
Using method 'ordinal'...
  Rank	Score	Who
  1	44	Solomon
  2	42	Jason
  3	42	Errol
  4	41	Garry
  5	41	Bernard
  6	41	Barry
  7	39	Stephen
Using method 'fractional'...
  Rank	Score	Who
  1	44	Solomon
  2.5	42	Jason
  2.5	42	Errol
  5	41	Garry
  5	41	Bernard
  5	41	Barry
  7	39	Stephen


True BASIC

Translation of: BASIC
LET n = 7
DIM puntos(7), ptosnom(7), nombre$(7)

SUB MostarTabla
    FOR i = 1 to n
        PRINT str$(ptosnom(i)); "   "; puntos(i); "  "; nombre$(i)
    NEXT i
    PRINT
END SUB

PRINT "Puntuaciones a clasificar (mejores primero):"
FOR i = 1 to n
    READ puntos(i), nombre$(i)
    PRINT "      "; puntos(i); "  "; nombre$(i)
NEXT i

PRINT
PRINT "--- Standard ranking ---"
LET ptosnom(1) = 1
FOR i = 2 to n
NEXT i
CALL MostarTabla

PRINT "--- Modified ranking ---"
LET ptosnom(n) = n
FOR i = n-1 to 1 step -1
    IF puntos(i) = puntos(i+1) then LET ptosnom(i) = ptosnom(i+1) else LET ptosnom(i) = i
NEXT i
CALL MostarTabla

PRINT "--- Ordinal ranking ---"
FOR i = 1 to n
    LET ptosnom(i) = i
NEXT i
CALL MostarTabla

PRINT "--- Fractional ranking ---"
LET i = 1
LET j = 2
DO
   IF j <= n then
      IF (puntos(j-1) = puntos(j)) then
         LET j = j + 1
      END IF
   END IF

   FOR k = i to j-1
       LET ptosnom(k) = (i+j-1) / 2
   NEXT k
   LET i = j
   LET j = j + 1
LOOP UNTIL i > n
CALL MOSTARTABLA

DATA 44, "Solomon", 42, "Jason", 42, "Errol", 41, "Garry", 41, "Bernard", 41, "Barry", 39, "Stephen"
END


Visual FoxPro

#DEFINE CTAB CHR(9)
#DEFINE CRLF CHR(13) + CHR(10)
LOCAL lcTxt As String, i As Integer
CLOSE DATABASES ALL
SET SAFETY OFF
CLEAR
CREATE CURSOR scores (score I, name V(8), rownum I AUTOINC)
INDEX ON score TAG score COLLATE "Machine"
SET ORDER TO 0
INSERT INTO scores (score, name) VALUES (44, "Solomon")
INSERT INTO scores (score, name) VALUES (42, "Jason")
INSERT INTO scores (score, name) VALUES (42, "Errol")
INSERT INTO scores (score, name) VALUES (41, "Garry")
INSERT INTO scores (score, name) VALUES (41, "Bernard")
INSERT INTO scores (score, name) VALUES (41, "Barry")
INSERT INTO scores (score, name) VALUES (39, "Stephen")

CREATE CURSOR ranks (sc_rank I, mod_rank I, dense I, ordinal I, fractional B(1), score I, name V(8))
INDEX ON score TAG score COLLATE "Machine"
SET ORDER TO 0
APPEND FROM DBF("scores") FIELDS score, name
Std_Comp()
Modified()
Dense()
Ordinal()
Fractional()
COPY TO ranks.txt TYPE DELIMITED WITH TAB
lcTxt = ""
FOR i = 1 TO FCOUNT()
    lcTxt = lcTxt + FIELD(i) + CTAB
ENDFOR
lcTxt = LEFT(lcTxt, LEN(lcTxt) - 1) + CRLF + FILETOSTR("ranks.txt")
STRTOFILE(lcTxt, "ranks.txt")
MODIFY FILE ranks.txt
SET SAFETY ON

FUNCTION ScoreGroup(aa)
LOCAL n As Integer
SELECT score, COUNT(*) As num FROM scores ;
GROUP BY score ORDER BY score DESC INTO ARRAY aa
n = _TALLY
RETURN n
ENDFUNC

PROCEDURE Std_Comp
LOCAL n, i, nn
LOCAL ARRAY a[1]
SELECT ranks
BLANK FIELDS sc_rank ALL
nn = ScoreGroup(@a)
n = 1
FOR i = 1 TO nn
    REPLACE sc_rank WITH n FOR score = a[i,1]
    n = n + a[i,2] 
ENDFOR	
ENDPROC

PROCEDURE Modified
LOCAL n, i, nn
LOCAL ARRAY a[1]
SELECT ranks
BLANK FIELDS mod_rank ALL
nn = ScoreGroup(@a)
n = 0
FOR i = 1 TO nn
    n = n + a[i,2]
    REPLACE mod_rank WITH n FOR score = a[i,1]
ENDFOR	
ENDPROC

PROCEDURE Dense
LOCAL n, i, nn
LOCAL ARRAY a[1]
SELECT ranks
BLANK FIELDS dense ALL
nn = ScoreGroup(@a)
SELECT ranks
n = 0
FOR i = 1 TO nn
    n = n + a[i,2]
    REPLACE dense WITH i FOR score = a[i,1]
ENDFOR	
ENDPROC

PROCEDURE Ordinal
SELECT ranks
BLANK FIELDS ordinal ALL
REPLACE ordinal WITH RECNO() ALL
ENDPROC

PROCEDURE Fractional
LOCAL i As Integer, nn As Integer
LOCAL ARRAY a[1]
SELECT ranks
BLANK FIELDS fractional ALL
SELECT CAST(AVG(rownum) As B(1)), score FROM scores ;
GROUP BY score ORDER BY score DESC INTO ARRAY a
nn = _TALLY
FOR i = 1 TO nn
    REPLACE fractional WITH a[i,1] FOR score = a[i,2]
ENDFOR	
ENDPROC
Output:
SC_RANK	MOD_RANK	DENSE	ORDINAL	FRACTIONAL	SCORE	NAME
1	1	1	1	1.0	44	"Solomon"
2	3	2	2	2.5	42	"Jason"
2	3	2	3	2.5	42	"Errol"
4	6	3	4	5.0	41	"Garry"
4	6	3	5	5.0	41	"Bernard"
4	6	3	6	5.0	41	"Barry"
7	7	4	7	7.0	39	"Stephen"

Wren

Translation of: Kotlin
Library: Wren-math
Library: Wren-fmt
import "./math" for Nums
import "./fmt" for Fmt

/* all ranking functions assume the array of Pairs is non-empty and already sorted
   by decreasing order of scores and then, if the scores are equal, by reverse 
   alphabetic order of names
*/

var standardRanking = Fn.new { |scores|
    var rankings = List.filled(scores.count, 0)
    rankings[0] = 1
    for (i in 1...scores.count) {
        rankings[i] = (scores[i][0] == scores[i-1][0]) ? rankings[i-1] : i + 1
    }
    return rankings
}

var modifiedRanking = Fn.new { |scores|
    var rankings = List.filled(scores.count, 0)
    rankings[0] = 1
    for (i in 1...scores.count) {
        rankings[i] =  i + 1
        var currScore = scores[i][0]
        for (j in i-1..0) {
            if (currScore != scores[j][0]) break
            rankings[j] = i + 1
        }
    }
    return rankings
}

var denseRanking = Fn.new { |scores|
    var rankings = List.filled(scores.count, 0)
    rankings[0] = 1
    var prevRanking = 1
    for (i in 1...scores.count) {
        rankings[i] = (scores[i][0] == scores[i-1][0]) ? prevRanking : (prevRanking = prevRanking+1)
    }
    return rankings
}

var ordinalRanking = Fn.new { |scores| (1..scores.count).toList }

var fractionalRanking = Fn.new { |scores|
    var rankings = List.filled(scores.count, 0)
    rankings[0] = 1
    for (i in 1...scores.count) {
        var k = i
        var currScore = scores[i][0]
        for (j in i-1..0) {
            if (currScore != scores[j][0]) break
            k = j
        }
        var avg = Nums.mean(k..i) + 1
        for (m in k..i) rankings[m] = avg
    }
    return rankings
}

var printRankings = Fn.new { |title, rankings, scores|
    System.print(title + ":")
    for (i in 0...rankings.count) {
        System.print("%(rankings[i])  %(scores[i][0]) %(scores[i][1])")
    }
    System.print()
}

var printFractionalRankings = Fn.new { |title, rankings, scores|
    System.print(title + ":")
    for (i in 0...rankings.count) {
        Fmt.print("$3.2f  $d $s", rankings[i], scores[i][0], scores[i][1])
    }
    System.print()
}

var scores = [[44, "Solomon"], [42, "Jason"], [42, "Errol"],  [41, "Garry"],
              [41, "Bernard"], [41, "Barry"], [39, "Stephen"]]
printRankings.call("Standard ranking", standardRanking.call(scores), scores)
printRankings.call("Modified ranking", modifiedRanking.call(scores), scores)
printRankings.call("Dense ranking", denseRanking.call(scores), scores)
printRankings.call("Ordinal ranking", ordinalRanking.call(scores), scores)
printFractionalRankings.call("Fractional ranking", fractionalRanking.call(scores), scores)
Output:
Standard ranking:
1  44 Solomon
2  42 Jason
2  42 Errol
4  41 Garry
4  41 Bernard
4  41 Barry
7  39 Stephen

Modified ranking:
1  44 Solomon
3  42 Jason
3  42 Errol
6  41 Garry
6  41 Bernard
6  41 Barry
7  39 Stephen

Dense ranking:
1  44 Solomon
2  42 Jason
2  42 Errol
3  41 Garry
3  41 Bernard
3  41 Barry
4  39 Stephen

Ordinal ranking:
1  44 Solomon
2  42 Jason
3  42 Errol
4  41 Garry
5  41 Bernard
6  41 Barry
7  39 Stephen

Fractional ranking:
1.00  44 Solomon
2.50  42 Jason
2.50  42 Errol
5.00  41 Garry
5.00  41 Bernard
5.00  41 Barry
7.00  39 Stephen

Yabasic

n = 7
dim puntos(7), ptosnom(7), nombre$(7)

sub MostarTabla()
    for i = 1 to n
        print str$(ptosnom(i)), "   ", puntos(i), "  ", nombre$(i)
    next i
    print
end sub

print "Puntuaciones a clasificar (mejores primero):"
for i = 1 to n
    read puntos(i), nombre$(i)
    print "      ", puntos(i), "  ", nombre$(i)
next i

print
print "--- Standard ranking ---"
ptosnom(1) = 1
for i = 2 to n
    if puntos(i) = puntos(i-1) then ptosnom(i) = ptosnom(i-1) else ptosnom(i) = i : fi
next i
MostarTabla()

print "--- Modified ranking ---"
ptosnom(n) = n
for i = n-1 to 1 step -1
    if puntos(i) = puntos(i+1) then ptosnom(i) = ptosnom(i+1) else ptosnom(i) = i : fi
next i
MostarTabla()

print "--- Ordinal ranking ---"
for i = 1 to n
    ptosnom(i) = i
next i
MostarTabla()

print "--- Fractional ranking ---"
i = 1
j = 2
repeat
    if j <= n then
        if (puntos(j-1) = puntos(j)) then j = j + 1 : fi
    end if
    
    for k = i to j-1
        ptosnom(k) = (i+j-1) / 2
    next k
    i = j
    j = j + 1
until i > n
MostarTabla()

data 44, "Solomon", 42, "Jason", 42, "Errol", 41, "Garry", 41, "Bernard", 41, "Barry", 39, "Stephen"
end


zkl

fcn group(scores){ // group like scores into one list --> list of lists
   sink:=List();
   scores.reduce('wrap(ps,sn,buf){
      if(sn[0]!=ps){ sink.append(buf.copy()); buf.clear(); }
      buf+sn;
      sn[0];
   },scores[0][0],buf:=List());
   sink.append(buf);
}
fcn print(list,rank){
   list.apply2('wrap(sn){ "%2s: %s (%d)".fmt(rank,sn[1],sn[0]):println(_); });
}
fcn rankViaStandard(scores){
   rank:=1;
   foreach group in (group(scores)){ print(group,rank); rank+=group.len(); }
}
fcn rankViaModified(scores){
   rank:=0;
   foreach group in (group(scores)){ rank+=group.len(); print(group,rank); }
}
fcn rankViaDense(scores){
   rank:=1;
   foreach group in (group(scores)){ print(group,rank); rank+=1; }
}
fcn rankViaOrdinal(scores){
   scores.apply2('wrap(sn,rr){ "%2s: %s (%d)".fmt(rr.inc(),sn[1],sn[0]):println(_); },Ref(1));
}
fcn rankViaFractional(scores){
   rank:=1;
   foreach group in (group(scores)){
      n:=group.len(); r:=rank.reduce(n,'+,0.0)/n; rank+=n;
      print(group,"%5.2f".fmt(r));
   }
}
   // these are sorted!?!
scores:=T(T(44,"Solomon"), T(42,"Jason"), T(42,"Errol"), T(41,"Garry"),
        T(41,"Bernard"),T(41,"Barry"),T(39,"Stephen"),);
"Standard:"  .println(); rankViaStandard(scores);
"Modified:"  .println(); rankViaModified(scores);
"Dense:"     .println(); rankViaDense(scores);
"Ordinal:"   .println(); rankViaOrdinal(scores);
"Fractional:".println(); rankViaFractional(scores);
Output:
Standard:
 1: Solomon (44)
 2: Jason (42)
 2: Errol (42)
 4: Garry (41)
 4: Bernard (41)
 4: Barry (41)
 7: Stephen (39)
Modified:
 1: Solomon (44)
 3: Jason (42)
 3: Errol (42)
 6: Garry (41)
 6: Bernard (41)
 6: Barry (41)
 7: Stephen (39)
Dense:
 1: Solomon (44)
 2: Jason (42)
 2: Errol (42)
 3: Garry (41)
 3: Bernard (41)
 3: Barry (41)
 4: Stephen (39)
Ordinal:
 1: Solomon (44)
 2: Jason (42)
 3: Errol (42)
 4: Garry (41)
 5: Bernard (41)
 6: Barry (41)
 7: Stephen (39)
Fractional:
 1.00: Solomon (44)
 2.50: Jason (42)
 2.50: Errol (42)
 5.00: Garry (41)
 5.00: Bernard (41)
 5.00: Barry (41)
 7.00: Stephen (39)