# 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<>();
clusters.add(1);
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 {
clusters.add(1);
}
}
double[] rankings = new double[scores.length];
int index = 0;
for (int cluster : clusters) {
double ranking = index + (1 + cluster) / 2.0;
Arrays.fill(rankings, index, index += cluster, ranking);
}
// rankings = [1, 2.5, 2.5, 4]
```

## Comments

Be the first to comment!