Update all new Tasks
This commit is contained in:
parent
00a190b0a6
commit
91df62d461
5697 changed files with 93386 additions and 804 deletions
23
Task/Ranking-methods/00DESCRIPTION
Normal file
23
Task/Ranking-methods/00DESCRIPTION
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
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 [[wp:Ranking|different ways]].
|
||||
|
||||
;Task:
|
||||
The following scores are accrued for all competitors of a competition (in best-first order):
|
||||
<pre>44 Solomon
|
||||
42 Jason
|
||||
42 Errol
|
||||
41 Garry
|
||||
41 Bernard
|
||||
41 Barry
|
||||
39 Stephen</pre>
|
||||
|
||||
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:
|
||||
# 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).
|
||||
See the [[wp:Ranking|wikipedia article]] for a fuller description.
|
||||
|
||||
Show here, on this page, the ranking of the test scores under each of the numbered ranking methods.
|
||||
100
Task/Ranking-methods/AWK/ranking-methods.awk
Normal file
100
Task/Ranking-methods/AWK/ranking-methods.awk
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
##
|
||||
## 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()}
|
||||
113
Task/Ranking-methods/Go/ranking-methods.go
Normal file
113
Task/Ranking-methods/Go/ranking-methods.go
Normal file
|
|
@ -0,0 +1,113 @@
|
|||
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)
|
||||
}
|
||||
72
Task/Ranking-methods/Haskell/ranking-methods.hs
Normal file
72
Task/Ranking-methods/Haskell/ranking-methods.hs
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
import Data.List (groupBy, sort, 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 . reverse . sort
|
||||
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) = map (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 map (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
|
||||
19
Task/Ranking-methods/J/ranking-methods-1.j
Normal file
19
Task/Ranking-methods/J/ranking-methods-1.j
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
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,.]'
|
||||
80
Task/Ranking-methods/J/ranking-methods-2.j
Normal file
80
Task/Ranking-methods/J/ranking-methods-2.j
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
standard rank competitors
|
||||
┌─┬──┬───────┐
|
||||
│1│44│Solomon│
|
||||
├─┼──┼───────┤
|
||||
│2│42│Jason │
|
||||
├─┼──┼───────┤
|
||||
│2│42│Errol │
|
||||
├─┼──┼───────┤
|
||||
│4│41│Garry │
|
||||
├─┼──┼───────┤
|
||||
│4│41│Bernard│
|
||||
├─┼──┼───────┤
|
||||
│4│41│Barry │
|
||||
├─┼──┼───────┤
|
||||
│7│39│Stephen│
|
||||
└─┴──┴───────┘
|
||||
modified rank competitors
|
||||
┌─┬──┬───────┐
|
||||
│1│44│Solomon│
|
||||
├─┼──┼───────┤
|
||||
│3│42│Jason │
|
||||
├─┼──┼───────┤
|
||||
│3│42│Errol │
|
||||
├─┼──┼───────┤
|
||||
│6│41│Garry │
|
||||
├─┼──┼───────┤
|
||||
│6│41│Bernard│
|
||||
├─┼──┼───────┤
|
||||
│6│41│Barry │
|
||||
├─┼──┼───────┤
|
||||
│7│39│Stephen│
|
||||
└─┴──┴───────┘
|
||||
dense rank competitors
|
||||
┌─┬──┬───────┐
|
||||
│1│44│Solomon│
|
||||
├─┼──┼───────┤
|
||||
│2│42│Jason │
|
||||
├─┼──┼───────┤
|
||||
│2│42│Errol │
|
||||
├─┼──┼───────┤
|
||||
│3│41│Garry │
|
||||
├─┼──┼───────┤
|
||||
│3│41│Bernard│
|
||||
├─┼──┼───────┤
|
||||
│3│41│Barry │
|
||||
├─┼──┼───────┤
|
||||
│4│39│Stephen│
|
||||
└─┴──┴───────┘
|
||||
ordinal rank competitors
|
||||
┌─┬──┬───────┐
|
||||
│1│44│Solomon│
|
||||
├─┼──┼───────┤
|
||||
│2│42│Jason │
|
||||
├─┼──┼───────┤
|
||||
│3│42│Errol │
|
||||
├─┼──┼───────┤
|
||||
│4│41│Garry │
|
||||
├─┼──┼───────┤
|
||||
│5│41│Bernard│
|
||||
├─┼──┼───────┤
|
||||
│6│41│Barry │
|
||||
├─┼──┼───────┤
|
||||
│7│39│Stephen│
|
||||
└─┴──┴───────┘
|
||||
fractional rank competitors
|
||||
┌───┬──┬───────┐
|
||||
│1 │44│Solomon│
|
||||
├───┼──┼───────┤
|
||||
│2.5│42│Jason │
|
||||
├───┼──┼───────┤
|
||||
│2.5│42│Errol │
|
||||
├───┼──┼───────┤
|
||||
│5 │41│Garry │
|
||||
├───┼──┼───────┤
|
||||
│5 │41│Bernard│
|
||||
├───┼──┼───────┤
|
||||
│5 │41│Barry │
|
||||
├───┼──┼───────┤
|
||||
│7 │39│Stephen│
|
||||
└───┴──┴───────┘
|
||||
75
Task/Ranking-methods/Java/ranking-methods.java
Normal file
75
Task/Ranking-methods/Java/ranking-methods.java
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
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]);
|
||||
}
|
||||
}
|
||||
}
|
||||
45
Task/Ranking-methods/Perl-6/ranking-methods.pl6
Normal file
45
Task/Ranking-methods/Perl-6/ranking-methods.pl6
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
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:"; .say for standard @scores;
|
||||
say "\nModified:"; .say for modified @scores;
|
||||
say "\nDense:"; .say for dense @scores;
|
||||
say "\nOrdinal:"; .say for ordinal @scores;
|
||||
say "\nFractional:"; .say for fractional @scores;
|
||||
74
Task/Ranking-methods/Python/ranking-methods.py
Normal file
74
Task/Ranking-methods/Python/ranking-methods.py
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
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))
|
||||
1
Task/Ranking-methods/README
Normal file
1
Task/Ranking-methods/README
Normal file
|
|
@ -0,0 +1 @@
|
|||
Data source: http://rosettacode.org/wiki/Ranking_methods
|
||||
77
Task/Ranking-methods/Racket/ranking-methods.rkt
Normal file
77
Task/Ranking-methods/Racket/ranking-methods.rkt
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
#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))
|
||||
23
Task/Ranking-methods/Ruby/ranking-methods.rb
Normal file
23
Task/Ranking-methods/Ruby/ranking-methods.rb
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
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.delete_at(0).to_i}
|
||||
s_rnk = 1
|
||||
m_rnk = o_rnk = f_rnk = 0
|
||||
puts "stand.\tmod.\tdense\tord.\tfract."
|
||||
|
||||
grouped.each.with_index do |(score, names), i|
|
||||
d_rnk = i + 1
|
||||
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.gsub(".0","")}\t#{score} #{name}"
|
||||
end
|
||||
s_rnk += names.size
|
||||
end
|
||||
44
Task/Ranking-methods/Scala/ranking-methods.scala
Normal file
44
Task/Ranking-methods/Scala/ranking-methods.scala
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
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")
|
||||
|
||||
}
|
||||
56
Task/Ranking-methods/Tcl/ranking-methods.tcl
Normal file
56
Task/Ranking-methods/Tcl/ranking-methods.tcl
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
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"
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue