Task: Ranking methods




Go: package main

import (
	"fmt"
	"sort"
)

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

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

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

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

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

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

type scores []struct {
	score int
	name  string
}

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

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

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

	sort.Sort(data)
	show("Standard", StandardRank)
	show("\nModified", ModifiedRank)
	show("\nDense", DenseRank)
	show("\nOrdinal", OrdinalRank)
	show("\nFractional", FractionalRank)
}


Java: 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]);
        }
    }
}