Ranking methods: Difference between revisions

m
m (→‎{{header|Wren}}: Minor tidy)
 
(36 intermediate revisions by 17 users not shown)
Line 1:
{{task|Sorting Algorithms}}
[[Category:Sorting]]
{{Sorting Algorithm}}
 
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.
 
Line 27 ⟶ 30:
Show here, on this page, the ranking of the test scores under each of the numbered ranking methods.
<br><br>
 
=={{header|11l}}==
{{trans|Python}}
 
<syntaxhighlight lang="11l">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]))</syntaxhighlight>
 
{{out}}
<pre>
 
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)
</pre>
 
=={{header|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.
<syntaxhighlight lang="algol68">
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
</syntaxhighlight>
{{out}}
<pre>
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
</pre>
 
=={{header|AppleScript}}==
<syntaxhighlight lang="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)</syntaxhighlight>
 
{{output}}
<syntaxhighlight lang="applescript">"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)"</syntaxhighlight>
 
=={{header|AutoHotkey}}==
<langsyntaxhighlight AutoHotkeylang="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)
Line 50 ⟶ 584:
}
return Res%opt%
}</langsyntaxhighlight>
Example:<langsyntaxhighlight AutoHotkeylang="autohotkey">data =
(
44 Solomon
Line 68 ⟶ 602:
. "`nOrdinal Ranking:`n" Rank(data, 4)
. "`nFractional Ranking:`n" Rank(data, 5)
return</langsyntaxhighlight>
Output:<pre>Standard Ranking:
1 44 Solomon
Line 113 ⟶ 647:
5 41 Barry
7 39 Stephen</pre>
 
=={{header|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.
 
<syntaxhighlight lang="apl">standard ← ∊∘(⌊\¨⊢⊂⍳∘≢)∘(1,2≠/⊢)∘(1⌷[2]⊢),⊢
modified ← ∊∘(⌈\∘⌽¨⊢⊂⍳∘≢)∘(1,2≠/⊢)∘(1⌷[2]⊢),⊢
dense ← (+\1,2≠/1⌷[2]⊢),⊢
ordinal ← ⍳∘≢,⊢
fractional ← ∊∘((≢(/∘⊢)+/÷≢)¨⊢⊂⍳∘≢)∘(1,2≠/⊢)∘(1⌷[2]⊢),⊢</syntaxhighlight>
 
{{out}}
 
<pre> ⍝ 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 </pre>
 
=={{header|AWK}}==
{{trans|Python}}
This uses separate files for each method of ranking:
<langsyntaxhighlight lang="awk">##
## Dense ranking in file: ranking_d.awk
##
Line 217 ⟶ 821:
}
//{sc_rank()}
</syntaxhighlight>
</lang>
 
The input as a file <code>ranking.txt</code>:
Line 275 ⟶ 879:
 
C:\Users\RC\Code></pre>
 
=={{header|BASIC}}==
<syntaxhighlight lang="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</syntaxhighlight>
 
{{out}}
 
<pre>--- 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</pre>
 
=={{header|C}}==
Takes the scores as input via a file, prints out usage on incorrect invocation.
<syntaxhighlight lang="c">
<lang C>
/*Abhishek Ghosh, 5th November 2017*/
 
#include<stdlib.h>
#include<stdio.h>
Line 398 ⟶ 1,099:
return 0;
}
</syntaxhighlight>
</lang>
Input file, first row is number of records :
<pre>
Line 465 ⟶ 1,166:
7.0 39 Stephen
</pre>
 
=={{header|C#|C sharp}}==
=={{header|C sharp|C#}}==
{{trans|D}}
<langsyntaxhighlight lang="csharp">using System;
using System.Collections.Generic;
using System.Linq;
Line 603 ⟶ 1,305:
}
}
}</langsyntaxhighlight>
{{out}}
<pre>Standard Rank
Line 649 ⟶ 1,351:
5.0 41 Barry
7.0 39 Stephen</pre>
 
=={{header|C++}}==
{{trans|C#}}
<syntaxhighlight lang="cpp">#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;
}</syntaxhighlight>
{{out}}
<pre>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</pre>
 
=={{header|Cowgol}}==
<syntaxhighlight lang="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;</syntaxhighlight>
 
{{out}}
 
<pre>--- 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</pre>
 
=={{header|D}}==
<langsyntaxhighlight Dlang="d">import std.algorithm;
import std.stdio;
 
Line 817 ⟶ 1,922:
 
writeln;
}</langsyntaxhighlight>
 
{{out}}
Line 867 ⟶ 1,972:
=={{header|Elixir}}==
{{trans|Ruby}}
<langsyntaxhighlight lang="elixir">defmodule Ranking do
def methods(data) do
IO.puts "stand.\tmod.\tdense\tord.\tfract."
Line 899 ⟶ 2,004:
|> Enum.chunk(2)
|> Enum.map(fn [score,name] -> {String.to_integer(score),name} end)
|> Ranking.methods</langsyntaxhighlight>
 
{{out}}
Line 912 ⟶ 2,017:
7 7 4 7 7 39 Stephen
</pre>
 
=={{header|Factor}}==
{{works with|Factor|0.99 2019-07-10}}
<syntaxhighlight lang="factor">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</syntaxhighlight>
{{out}}
<pre>
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
</pre>
 
 
=={{header|FreeBASIC}}==
<syntaxhighlight lang="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
</syntaxhighlight>
{{out}}
<pre>
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
</pre>
 
 
=={{header|Go}}==
<langsyntaxhighlight lang="go">package main
 
import (
Line 1,026 ⟶ 2,342:
show("\nOrdinal", OrdinalRank)
show("\nFractional", FractionalRank)
}</langsyntaxhighlight>
{{out}}
<pre>
Line 1,076 ⟶ 2,392:
 
=={{header|Haskell}}==
<syntaxhighlight lang="haskell">import Data.List (groupBy, sortBy, intercalate)
<lang Haskell>
import Data.List (groupBy, sort, intercalate)
 
type Item = (Int, String)
 
type ItemList = [Item]
type ItemGroups ItemList = [ItemListItem]
 
type RankItem a = (a, Int, String)
type RankItemList a ItemGroups = [RankItem aItemList]
 
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 . reversesortBy .(flip sortcompare)
where
where gf (a, _) (b, _) = a == b
gf (a, _) (b, _) = a == b
 
-- give an item a rank
rank
rank :: Num a => a -> Item -> RankItem a
:: 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
 
standard = ms 1 where
ms _ [] = []
ms n (x:xs) = map (rank n) <$> x) ++ ms (n + length x) xs
 
modified = md 1 where
where
md _ [] = []
md n (x:xs) = let l = length x
let nll = nlength + lx
nl1nl = nln -+ 1l
in map (rank nl1) x ++ md (n= +nl l)- xs1
in (rank nl1 <$> x) ++ md (n + l) xs
 
dense = md 1 where
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
where
mf _ [] = []
mf n (x:xs) = let l = length x
let ol = take l [nlength ..]x
o = take l [n ld = fromIntegral l..]
ald = sumfromIntegral o / ldl
in map (rank a) x= ++sum mfo (n +/ ld) xs
in map (rank a) x ++ mf (n + ld) xs
 
-- sample data
test :: ItemGroups
test = prepare
prepare
[ (44, "Solomon")
, (42, "Jason")
Line 1,132 ⟶ 2,460:
, (41, "Bernard")
, (41, "Barry")
, (39, "Stephen") ]
]
 
-- print rank items nicely
nicePrint
nicePrint :: Show a => String -> RankItemList a -> IO ()
:: Show a
=> String -> RankItemList a -> IO ()
nicePrint xs items = do
putStrLn xs
mapM_ np items
putStr "\n"
where
where np (a, b, c) = putStrLn $ intercalate "\t" [show a, show b, c]
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</syntaxhighlight>
{{Out}}
</lang>
<pre>Standard:
Output:
<pre>
Standard:
1 44 Solomon
2 42 Jason
Line 1,195 ⟶ 2,525:
5.0 41 Bernard
5.0 41 Barry
7.0 39 Stephen</pre>
</pre>
 
=={{header|J}}==
Implementation:
 
<langsyntaxhighlight Jlang="j">competitors=:<;._1;._2]0 :0
44 Solomon
42 Jason
Line 1,219 ⟶ 2,548:
fractional=: #/.~ # ] (+/%#)/. #\
 
rank=:1 :'<"0@u@:scores,.]'</langsyntaxhighlight>
 
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).
Line 1,225 ⟶ 2,554:
Task examples:
 
<langsyntaxhighlight Jlang="j"> standard rank competitors
┌─┬──┬───────┐
│1│44│Solomon│
Line 1,304 ⟶ 2,633:
├───┼──┼───────┤
│7 │39│Stephen│
└───┴──┴───────┘</langsyntaxhighlight>
 
=={{header|Java}}==
{{works with|Java|8}}
<langsyntaxhighlight lang="java">import java.util.*;
 
public class RankingMethods {
Line 1,382 ⟶ 2,711:
}
}
}</langsyntaxhighlight>
 
<pre>Standard ranking
Line 1,428 ⟶ 2,757:
5,0 41 Barry
7,0 39 Stephen</pre>
 
 
=={{header|JavaScript}}==
Line 1,438 ⟶ 2,766:
( 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)
 
<langsyntaxhighlight JavaScriptlang="javascript">(function () {
var xs = 'Solomon Jason Errol Garry Bernard Barry Stephen'.split(' '),
Line 1,513 ⟶ 2,841:
return wikiTable(tbl, true, 'text-align:center');
})();</langsyntaxhighlight>
 
{{out}}
Line 1,538 ⟶ 2,866:
===ES6===
 
<langsyntaxhighlight JavaScriptlang="javascript">((() => {
const xs = 'Solomon Jason Errol Garry Bernard Barry Stephen'.split(' '),
ns = [44, 42, 42, 41, 41, 41, 39];
Line 1,596 ⟶ 2,924:
 
return wikiTable(tbl, true, 'text-align:center');
}))();</langsyntaxhighlight>
 
{| class="wikitable" style="text-align:center"
Line 1,625 ⟶ 2,953:
 
For the sake of brevity, only the ranks are printed.
<syntaxhighlight lang="jq">
<lang jq>
# Ties share what would have been their first ordinal number
def standard_ranking:
Line 1,682 ⟶ 3,010:
else [ resolve, [ $i + 1 ] ]
end )
| resolve ;</langsyntaxhighlight>Task<syntaxhighlight lang ="jq">def raw:
[
"Solomon", 44,
Line 1,701 ⟶ 3,029:
task
</syntaxhighlight>
</lang>
{{Out}}
standard: [1,2,2,4,4,4,7]
Line 1,711 ⟶ 3,039:
=={{header|Julia}}==
'''ties''', a helper function used by some of the ranking methods. It lists any duplicated scores.
<syntaxhighlight lang="julia">
<lang Julia>
function ties{T<:Real}(a::Array{T,1})
unique(a[2:end][a[2:end] .== a[1:end-1]])
end
</syntaxhighlight>
</lang>
<code>ties</code> 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'''
<syntaxhighlight lang="julia">
<lang Julia>
function rankstandard{T<:Real}(a::Array{T,1})
r = collect(1:length(a))
Line 1,728 ⟶ 3,056:
return r
end
</syntaxhighlight>
</lang>
 
'''Modified Ranking Function'''
<syntaxhighlight lang="julia">
<lang Julia>
function rankmodified{T<:Real}(a::Array{T,1})
indexin(a, a)
end
</syntaxhighlight>
</lang>
 
'''Dense Ranking Function'''
<syntaxhighlight lang="julia">
<lang Julia>
function rankdense{T<:Real}(a::Array{T,1})
indexin(a, unique(a))
end
</syntaxhighlight>
</lang>
 
'''Ordinal Ranking Function'''
<syntaxhighlight lang="julia">
<lang Julia>
function rankordinal{T<:Real}(a::Array{T,1})
collect(1:length(a))
end
</syntaxhighlight>
</lang>
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'''
<syntaxhighlight lang="julia">
<lang Julia>
function rankfractional{T<:Real}(a::Array{T,1})
r = float64(collect(1:length(a)))
Line 1,762 ⟶ 3,090:
return r
end
</syntaxhighlight>
</lang>
 
'''Main'''
<syntaxhighlight lang="julia">
<lang Julia>
scores = [44, 42, 42, 41, 41, 41, 39]
names = ["Solomon", "Jason", "Errol", "Garry",
Line 1,787 ⟶ 3,115:
println()
end
</syntaxhighlight>
</lang>
 
{{out}}
Line 1,802 ⟶ 3,130:
 
=={{header|Kotlin}}==
<langsyntaxhighlight lang="scala">// version 1.0.6
 
/* all ranking functions assume the array of Pairs is non-empty and already sorted by decreasing order of scores
Line 1,881 ⟶ 3,209:
printRankings("Ordinal ranking", ordinalRanking(scores), scores)
printFractionalRankings("Fractional ranking", fractionalRanking(scores), scores)
}</langsyntaxhighlight>
 
{{out}}
Line 1,931 ⟶ 3,259:
</pre>
 
=={{header|MathematicaKsh}}==
<syntaxhighlight lang="ksh">
<lang Mathematica>
#!/bin/ksh
data = Transpose@{{44, 42, 42, 41, 41, 41, 39}, {"Solomon", "Jason",
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</syntaxhighlight>
{{out}}<pre>
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</pre>
 
 
=={{header|M2000 Interpreter}}==
<syntaxhighlight lang="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
</syntaxhighlight>
{{out}}
<pre>
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)
</pre>
 
=={{header|Mathematica}}/{{header|Wolfram Language}}==
<syntaxhighlight lang="mathematica">data = Transpose@{{44, 42, 42, 41, 41, 41, 39}, {"Solomon", "Jason",
"Errol", "Garry", "Bernard", "Barry", "Stephen"}};
 
Line 1,951 ⟶ 3,683:
 
Grid@{fmtRankedData[data, #] & /@ {"standard", "modified", "dense",
"ordinal", "fractional"}}</syntaxhighlight>
 
</lang>
 
{{out}}
<pre>standard ranking:
standard ranking:
1 44 Solomon
3 42 Errol
Line 2,000 ⟶ 3,728:
5 41 Bernard
5 41 Garry
7 39 Stephen</pre>
 
</pre>
=={{header|Modula-2}}==
{{trans|C}}
<syntaxhighlight lang="modula2">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.</syntaxhighlight>
{{out}}
<pre>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</pre>
 
=={{header|Nim}}==
===Using an auxiliary table===
To simplify, it’s convenient to build a table giving for each score the list of competitor names.
<syntaxhighlight lang="nim">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</syntaxhighlight>
 
{{out}}
<pre>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</pre>
 
===Without an auxiliary table===
But it is possible to do the ranking without an auxiliary table.
<syntaxhighlight lang="nim">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</syntaxhighlight>
 
{{out}}
<pre>Same output as with other version.</pre>
 
=={{header|PARI/GP}}==
 
Replace "2" with "2.0" in <code>fractional</code> if you prefer decimal to fractional.
<langsyntaxhighlight lang="parigp">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;
Line 2,017 ⟶ 4,229:
dense(v)
ordinal(v)
fractional(v)</langsyntaxhighlight>
{{out}}
<pre>%1 = [[1, "Solomon"], [2, "Errol"], [2, "Jason"], [4, "Barry"], [4, "Bernard"], [4, "Garry"], [7, "Stephen"]]
Line 2,025 ⟶ 4,237:
%5 = [[1, "Solomon"], [5/2, "Jason"], [5/2, "Errol"], [5, "Garry"], [5, "Bernard"], [5, "Barry"], [7, "Stephen"]]</pre>
 
=={{header|Perl 6}}==
{{trans|Raku}}
<lang perl6>my @scores =
<syntaxhighlight lang="perl">my %scores = (
Solomon => 44,
Jason 'Solomon' => 4244,
Errol'Jason' => 42,
Garry'Errol' => 4142,
Bernard'Garry' => 41,
Barry 'Bernard' => 41,
Stephen'Barry' => 39;41,
'Stephen' => 39
);
 
sub tiers {
sub tiers (@s) { @s.classify(*.value).pairs.sort.reverse.map: { [.value».key] } }
my(%s) = @_; my(%h);
push @{$h{$s{$_}}}, $_ for keys %s;
@{\%h}{reverse sort keys %h};
}
 
sub standard (@s) {
my(%s) = @_; my($result);
my $rank = 1;
gather for my $players (tiers @%s -> @players) {
take $rankresult .=> "$rank " . join(', ', sort @$players) . "\n";
$rank += @$players;
}
return $result;
}
 
sub modified (@s) {
my(%s) = @_; my($result);
my $rank = 0;
gather for my $players (tiers @%s -> @players) {
$rank += @$players;
take $rankresult .=> "$rank " . join(', ', sort @$players) . "\n";
}
return $result;
}
 
sub dense {
sub dense (@s) { tiers(@s).map: { ++$_ => @^players } }
my(%s) = @_; my($n,$result);
$result .= sprintf "%d %s\n", ++$n, join(', ', sort @$_) for tiers %s;
return $result;
}
 
sub ordinal (@s) { @s.map: ++$_ => *.key }
my(%s) = @_; my($n,$result);
for my $players (tiers %s) {
$result .= sprintf "%d %s\n", ++$n, $_ for sort @$players;
}
return $result;
}
 
sub fractional (@s) {
my(%s) = @_; my($result);
my $rank = 1;
gather for my $players (tiers @%s -> @players) {
my $beg = $rank;
my $end = $rank += @$players;
my $avg = 0;
take [+]($beg ..^ $end) / @players => @players;
$avg += $_/@$players for $beg .. $end-1;
$result .= sprintf "%3.1f %s\n", $avg, join ', ', sort @$players;
}
return $result;
}
 
say print "Standard:\n"; .say for standard @(%scores) . "\n";
sayprint "\nModifiedModified:\n"; .say for modified @(%scores) . "\n";
sayprint "\nDenseDense:\n"; .say for dense @(%scores) . "\n";
sayprint "\nOrdinalOrdinal:\n"; .say for ordinal @(%scores) . "\n";
sayprint "\nFractionalFractional:\n"; .say for fractional @(%scores) . "\n";</langsyntaxhighlight>
{{out}}
<pre style="height:35ex">Standard:
1 => ["Solomon"]
2 =>Errol, ["Jason", "Errol"]
4 => ["Garry"Barry, "Bernard", "Barry"]Garry
7 => ["Stephen"]
 
Modified:
1 => ["Solomon"]
3 =>Errol, ["Jason", "Errol"]
6 => ["Garry"Barry, "Bernard", "Barry"]Garry
7 => ["Stephen"]
 
Dense:
1 => ["Solomon"]
2 =>Errol, ["Jason", "Errol"]
3 => ["Garry"Barry, "Bernard", "Barry"]Garry
4 => ["Stephen"]
 
Ordinal:
1 => "Solomon"
2 Errol
2 => "Jason"
3 Jason
3 => "Errol"
4 Barry
4 => "Garry"
5 => "Bernard"
6 Garry
6 => "Barry"
7 => "Stephen"
 
Fractional:
1.0 => ["Solomon"]
2.5 =>Errol, ["Jason", "Errol"]
5.0 => ["Garry"Barry, "Bernard", "Barry"]Garry
7.0 => ["Stephen"]</pre>
 
=={{header|Phix}}==
<!--<syntaxhighlight lang="phix">(phixonline)-->
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">ties</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">scores</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">t</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{},</span> <span style="color: #000080;font-style:italic;">-- {start,num} pairs</span>
<span style="color: #000000;">tdx</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">scores</span><span style="color: #0000FF;">))</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">last</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">1</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">scores</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">curr</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">scores</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">][</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">curr</span><span style="color: #0000FF;">=</span><span style="color: #000000;">last</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">t</span><span style="color: #0000FF;">[$][</span><span style="color: #000000;">2</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span>
<span style="color: #008080;">else</span>
<span style="color: #000000;">t</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">append</span><span style="color: #0000FF;">(</span><span style="color: #000000;">t</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">i</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">})</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #000000;">tdx</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">t</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">last</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">curr</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #000080;font-style:italic;">-- eg <nowiki>{{</nowiki>{1,1},{2,2},{4,3},{7,1<nowiki>}}</nowiki>,
-- {1,2,2,3,3,3,4<nowiki>}}</nowiki></span>
<span style="color: #008080;">return</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">t</span><span style="color: #0000FF;">,</span><span style="color: #000000;">tdx</span><span style="color: #0000FF;">}</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">enum</span> <span style="color: #000000;">STANDARD</span><span style="color: #0000FF;">,</span> <span style="color: #000080;font-style:italic;">-- eg {1,2,2,4,4,4,7}</span>
<span style="color: #000000;">MODIFIED</span><span style="color: #0000FF;">,</span> <span style="color: #000080;font-style:italic;">-- eg {1,3,3,6,6,6,7}</span>
<span style="color: #000000;">DENSE</span><span style="color: #0000FF;">,</span> <span style="color: #000080;font-style:italic;">-- (==tdx)</span>
<span style="color: #000000;">ORDINAL</span><span style="color: #0000FF;">,</span> <span style="color: #000080;font-style:italic;">-- eg {1,2,3,4,5,6,7}</span>
<span style="color: #000000;">FRACTION</span><span style="color: #0000FF;">,</span> <span style="color: #000080;font-style:italic;">-- {1,2.5,2.5,5,5,5,7}</span>
<span style="color: #000000;">METHODS</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">$</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">rank</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">method</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">sequence</span> <span style="color: #000000;">t</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">tdx</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">idx</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">tdx</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">],</span>
<span style="color: #0000FF;">{</span><span style="color: #000000;">tx</span><span style="color: #0000FF;">,</span><span style="color: #000000;">tn</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">t</span><span style="color: #0000FF;">[</span><span style="color: #000000;">idx</span><span style="color: #0000FF;">]</span>
<span style="color: #008080;">switch</span> <span style="color: #000000;">method</span>
<span style="color: #008080;">case</span> <span style="color: #000000;">STANDARD</span><span style="color: #0000FF;">:</span> <span style="color: #008080;">return</span> <span style="color: #000000;">tx</span>
<span style="color: #008080;">case</span> <span style="color: #000000;">MODIFIED</span><span style="color: #0000FF;">:</span> <span style="color: #008080;">return</span> <span style="color: #000000;">tx</span><span style="color: #0000FF;">+</span><span style="color: #000000;">tn</span><span style="color: #0000FF;">-</span><span style="color: #000000;">1</span>
<span style="color: #008080;">case</span> <span style="color: #000000;">DENSE</span> <span style="color: #0000FF;">:</span> <span style="color: #008080;">return</span> <span style="color: #000000;">idx</span>
<span style="color: #008080;">case</span> <span style="color: #000000;">ORDINAL</span> <span style="color: #0000FF;">:</span> <span style="color: #008080;">return</span> <span style="color: #000000;">i</span>
<span style="color: #008080;">case</span> <span style="color: #000000;">FRACTION</span><span style="color: #0000FF;">:</span> <span style="color: #008080;">return</span> <span style="color: #000000;">tx</span><span style="color: #0000FF;">+(</span><span style="color: #000000;">tn</span><span style="color: #0000FF;">-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)/</span><span style="color: #000000;">2</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">switch</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">constant</span> <span style="color: #000000;">scores</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{{</span><span style="color: #000000;">44</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"Solomon"</span><span style="color: #0000FF;">},</span>
<span style="color: #0000FF;">{</span><span style="color: #000000;">42</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"Jason"</span><span style="color: #0000FF;">},</span>
<span style="color: #0000FF;">{</span><span style="color: #000000;">42</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"Errol"</span><span style="color: #0000FF;">},</span>
<span style="color: #0000FF;">{</span><span style="color: #000000;">41</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"Garry"</span><span style="color: #0000FF;">},</span>
<span style="color: #0000FF;">{</span><span style="color: #000000;">41</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"Bernard"</span><span style="color: #0000FF;">},</span>
<span style="color: #0000FF;">{</span><span style="color: #000000;">41</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"Barry"</span><span style="color: #0000FF;">},</span>
<span style="color: #0000FF;">{</span><span style="color: #000000;">39</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"Stephen"</span><span style="color: #0000FF;">}}</span>
<span style="color: #004080;">sequence</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">t</span><span style="color: #0000FF;">,</span><span style="color: #000000;">tdx</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">ties</span><span style="color: #0000FF;">(</span><span style="color: #000000;">scores</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">" score name standard modified dense ordinal fractional\n"</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">scores</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">ranks</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">METHODS</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">method</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">METHODS</span> <span style="color: #008080;">do</span>
<span style="color: #000000;">ranks</span><span style="color: #0000FF;">[</span><span style="color: #000000;">method</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">rank</span><span style="color: #0000FF;">(</span><span style="color: #000000;">i</span><span style="color: #0000FF;">,</span><span style="color: #000000;">method</span><span style="color: #0000FF;">,</span><span style="color: #000000;">t</span><span style="color: #0000FF;">,</span><span style="color: #000000;">tdx</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%5d %-7s "</span><span style="color: #0000FF;">,</span><span style="color: #000000;">scores</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">])</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%6g %8g %6g %6g %9g\n"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">ranks</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<!--</syntaxhighlight>-->
{{out}}
<pre>
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
</pre>
 
=={{header|PowerShell}}==
<syntaxhighlight lang="powershell">
<lang PowerShell>
function Get-Ranking
{
Line 2,249 ⟶ 4,557:
}
}
</syntaxhighlight>
</lang>
<syntaxhighlight lang="powershell">
<lang PowerShell>
$scores = "44 Solomon","42 Jason","42 Errol","41 Garry","41 Bernard","41 Barry","39 Stephen"
</syntaxhighlight>
</lang>
<syntaxhighlight lang="powershell">
<lang PowerShell>
$scores | Get-Ranking -Standard
</syntaxhighlight>
</lang>
{{Out}}
<pre>
Line 2,268 ⟶ 4,576:
Stephen 39 7
</pre>
<syntaxhighlight lang="powershell">
<lang PowerShell>
$scores | Get-Ranking -Modified
</syntaxhighlight>
</lang>
{{Out}}
<pre>
Line 2,283 ⟶ 4,591:
Stephen 39 7
</pre>
<syntaxhighlight lang="powershell">
<lang PowerShell>
$scores | Get-Ranking -Dense
</syntaxhighlight>
</lang>
{{Out}}
<pre>
Line 2,298 ⟶ 4,606:
Stephen 39 4
</pre>
<syntaxhighlight lang="powershell">
<lang PowerShell>
$scores | Get-Ranking -Ordinal
</syntaxhighlight>
</lang>
{{Out}}
<pre>
Line 2,313 ⟶ 4,621:
Stephen 39 7
</pre>
<syntaxhighlight lang="powershell">
<lang PowerShell>
$scores | Get-Ranking -Fractional
</syntaxhighlight>
</lang>
{{Out}}
<pre>
Line 2,328 ⟶ 4,636:
Stephen 39 7
</pre>
 
 
=={{header|Python}}==
<langsyntaxhighlight lang="python">def mc_rank(iterable, start=1):
"""Modified competition ranking"""
lastresult, fifo = None, []
Line 2,404 ⟶ 4,711:
print('\n%s:' % ranker.__doc__)
for rank, score in ranker(scores):
print(' %3g, %r' % (rank, score))</langsyntaxhighlight>
 
{{out}}
Line 2,462 ⟶ 4,769:
 
=={{header|Racket}}==
<langsyntaxhighlight lang="racket">#lang racket
;; Tim-brown 2014-09-11
 
Line 2,538 ⟶ 4,845:
(caddr r)
(cdddr r)))
(newline))</langsyntaxhighlight>
 
{{out}}
Line 2,585 ⟶ 4,892:
= 5 41 Barry
7 39 Stephen</pre>
 
=={{header|Raku}}==
(formerly Perl 6)
<syntaxhighlight lang="raku" line>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;</syntaxhighlight>
{{out}}
<pre>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"]</pre>
 
=={{header|REXX}}==
<langsyntaxhighlight lang="rexx">/**************************
44 Solomon 1 1 1 1 1
42 Jason 2 3 2 2 2.5
Line 2,635 ⟶ 5,023:
cp=p
End
Say cnt.ok 'correct lines'</langsyntaxhighlight>
{{out}}
<pre>44 Solomon 1 1 1 1 1
Line 2,647 ⟶ 5,035:
 
=={{header|Ruby}}==
<langsyntaxhighlight lang="ruby">ar = "44 Solomon
42 Jason
42 Errol
Line 2,667 ⟶ 5,055:
end
s_rnk += names.size
end</langsyntaxhighlight>
{{out}}
<pre>
Line 2,682 ⟶ 5,070:
=={{header|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.
<langsyntaxhighlight Scalalang="scala">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)
Line 2,725 ⟶ 5,113:
println(rankFractional(test) mkString "\n")
 
}</langsyntaxhighlight>
{{out}}
<pre>Standard:
Line 2,761 ⟶ 5,149:
 
=={{header|Sidef}}==
{{trans|Perl 6Raku}}
<langsyntaxhighlight lang="ruby">var scores = [
Pair(Solomon => 44),
Pair(Jason => 42),
Line 2,823 ⟶ 5,211:
say "\nDense:"; display( dense(scores))
say "\nOrdinal:"; display( ordinal(scores))
say "\nFractional:"; display(fractional(scores))</langsyntaxhighlight>
{{out}}
<pre>
Line 2,861 ⟶ 5,249:
 
=={{header|Tcl}}==
<langsyntaxhighlight lang="tcl">proc rank {rankingMethod sortedList} {
# Extract the groups in the data (this is pointless for ordinal...)
set s [set group [set groups {}]]
Line 2,916 ⟶ 5,304:
puts " $rank\t$score\t$who"
}
}</langsyntaxhighlight>
{{out}}
<pre>
Line 2,965 ⟶ 5,353:
7 39 Stephen
</pre>
 
 
=={{header|True BASIC}}==
{{trans|BASIC}}
<syntaxhighlight lang="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
</syntaxhighlight>
 
 
=={{header|Visual FoxPro}}==
<langsyntaxhighlight lang="vfp">
#DEFINE CTAB CHR(9)
#DEFINE CRLF CHR(13) + CHR(10)
Line 3,070 ⟶ 5,521:
ENDFOR
ENDPROC
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 3,082 ⟶ 5,533:
7 7 4 7 7.0 39 "Stephen"
</pre>
 
=={{header|Wren}}==
{{trans|Kotlin}}
{{libheader|Wren-math}}
{{libheader|Wren-fmt}}
<syntaxhighlight lang="wren">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)</syntaxhighlight>
 
{{out}}
<pre>
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
</pre>
 
=={{header|Yabasic}}==
<syntaxhighlight lang="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
</syntaxhighlight>
 
 
=={{header|zkl}}==
<langsyntaxhighlight lang="zkl">fcn group(scores){ // group like scores into one list --> list of lists
sink:=List();
scores.reduce('wrap(ps,sn,buf){
Line 3,117 ⟶ 5,763:
print(group,"%5.2f".fmt(r));
}
}</langsyntaxhighlight>
<langsyntaxhighlight lang="zkl"> // 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"),);
Line 3,125 ⟶ 5,771:
"Dense:" .println(); rankViaDense(scores);
"Ordinal:" .println(); rankViaOrdinal(scores);
"Fractional:".println(); rankViaFractional(scores);</langsyntaxhighlight>
{{out}}
<pre>
9,476

edits