# Generating competition rankings

Descriptions of the various ranking strategies can be found here: Wikipedia: Ranking

## Standard competition ranking, “1224”

Idea: Start with ranking 1, assign same as previous if score is equal, otherwise assign `index + 1`.

``````// scores = [10, 15, 15, 20]  (sorted)
int[] rankings = new int[scores.length];
rankings[0] = 1;
for (int i = 1; i < rankings.length; i++)
rankings[i] = scores[i] == scores[i - 1] ? rankings[i - 1] : i + 1;
// rankings = [1, 2, 2, 4]
``````

## Modified competition ranking, “1334”

Idea: Same as above, but start from the end:

``````int[] rankings = new int[scores.length];
rankings[scores.length - 1] = scores.length;
for (int i = rankings.length - 2; i >= 0; i--)
rankings[i] = scores[i] == scores[i + 1] ? rankings[i + 1] : i + 1;
// rankings = [1, 3, 3, 4]
``````

## Dense ranking, “1223”

Idea: Increment ranking only if current score differs from previous:

``````int[] rankings = new int[scores.length];
rankings[0] = 1;
for (int i = 1, r = 1; i < rankings.length; i++)
rankings[i] = scores[i] == scores[i - 1] ? r : ++r;
// rankings = [1, 2, 2, 3]
``````

## Ordinal ranking, “1234”

Trivial: Ranking equals `index + 1`.

The key desirable property in ordinal ranking is that it’s stable. Luckily `Arrays.sort`, `Collections.sort` and `List.sort` are all stable.

## Fractional ranking, “1 2½ 2½ 4”

``````List<Integer> clusters = new ArrayList<>();
for (int i = 1; i < scores.length; i++) {
if (scores[i] == scores[i - 1]) {
int last = clusters.size() - 1;
clusters.set(last, clusters.get(last) + 1);
} else {