How to rank elements of an array in Pascal

1 Answer

0 votes
program CompetitionRanking;

{$mode objfpc}{$H+}

{
    This program demonstrates how to compute "competition ranking"
    for an array of integers in Free Pascal.

    Competition Ranking Rules:
    --------------------------
    - Highest value gets rank 1
    - Equal values share the same rank
    - Next rank increases by the number of equal values

    Example:
        Values: 88, 4, 19, 4, 1, 31, 14, 1, 93, 17
        Ranks:   2, 7,  4, 7, 9,  3,  6, 9,  1,  5
}

uses SysUtils;

type
    TIntArray = array of Integer;

{
    FUNCTION: SortDescending
    ------------------------
    Sorts a dynamic array in descending order.
    We use a simple bubble sort for clarity.
}
procedure SortDescending(var arr: TIntArray);
var
    i, j, temp: Integer;
begin
    for i := 0 to High(arr) - 1 do
        for j := 0 to High(arr) - 1 - i do
            if arr[j] < arr[j + 1] then
            begin
                temp := arr[j];
                arr[j] := arr[j + 1];
                arr[j + 1] := temp;
            end;
end;

{
    FUNCTION: GetRanks
    -------------------
    Computes competition ranking for an array of integers.

    Steps:
    1. Make a sorted copy (descending)
    2. Assign ranks to each unique value
    3. Build a rank array matching the original order
}
function GetRanks(const arr: TIntArray): TIntArray;
var
    sorted: TIntArray;
    ranks: TIntArray;
    values: TIntArray;  // stores unique values
    rankList: TIntArray; // stores ranks for each unique value
    i, j, rank, count: Integer;
    exists: Boolean;
begin
    // Copy original array into sorted[]
    sorted := Copy(arr, 0, Length(arr));
    SortDescending(sorted);

    // Prepare arrays for mapping values → ranks
    SetLength(values, 0);
    SetLength(rankList, 0);

    rank := 1;

    // Assign ranks to each unique value
    for i := 0 to High(sorted) do
    begin
        exists := False;

        // Check if value already has a rank
        for j := 0 to High(values) do
            if values[j] = sorted[i] then
            begin
                exists := True;
                Break;
            end;

        // If not found, assign rank
        if not exists then
        begin
            count := Length(values);
            SetLength(values, count + 1);
            SetLength(rankList, count + 1);

            values[count] := sorted[i];
            rankList[count] := rank;
        end;

        rank := rank + 1;
    end;

    // Build ranking array in original order
    SetLength(ranks, Length(arr));

    for i := 0 to High(arr) do
        for j := 0 to High(values) do
            if arr[i] = values[j] then
            begin
                ranks[i] := rankList[j];
                Break;
            end;

    Result := ranks;
end;

{
    FUNCTION: PrintRanking
    -----------------------
    Prints the original array and its ranking.
}
procedure PrintRanking(const arr, ranks: TIntArray);
var
    i: Integer;
begin
    Write('Original array: [ ');
    for i := 0 to High(arr) do
        Write(arr[i], ' ');
    Writeln(']');

    Write('Ranking array : [ ');
    for i := 0 to High(ranks) do
        Write(ranks[i], ' ');
    Writeln(']');
end;

{
    MAIN PROGRAM
}
var
    arrayValues: TIntArray;
    rankingArray: TIntArray;
begin
    arrayValues := TIntArray.Create(88, 4, 19, 4, 1, 31, 14, 1, 93, 17);

    // Compute ranks
    rankingArray := GetRanks(arrayValues);

    // Print results
    PrintRanking(arrayValues, rankingArray);
end.


{
run:

Original array: [ 88 4 19 4 1 31 14 1 93 17 ]
Ranking array : [ 2 7 4 7 9 3 6 9 1 

}

 



answered 2 days ago by avibootz
...