All about points

Weekly challenge 214 — 24 April 2023

Week 214 - 24 Apr 2023

Task 1

You are given a list of scores (>=1). Write a script to rank each score in descending order. First three will get medals i.e. G (Gold), S (Silver) and B (Bronze). Rest will just get the ranking number. Use the standard model of giving equal scores equal rank, then advancing that number of ranks.

This is perhaps not as easy as it sounds, but I did it like this:

- Make an array of @rank_symbols: (G, S, B, 4, 5 ...) of size equal to the number of players.
- Sort the list of @scores in ascending order (@sorted)
- Loop over the sorted list setting $ranks[$sorted[$s]] = $rank_symbols[$s]

So we now have the original list in $scores[$s], and the ranks (G, S, B ...) in the same order in $ranks[$sorted[$s]].

The only slight wrinkle is when there is a tie, which is fixed with:

$ranks[$sorted[$s]] .= '=' if ($s > 0 and $sorted[$s] == $sorted[$s - 1]);

#!/usr/bin/perl use v5.16; # The Weekly Challenge - 2023-04-24 use utf8; # Week 214 task 1 - Rank score use strict; # Peter Campbell Smith use warnings; # Blog: http://ccgi.campbellsmiths.force9.co.uk/challenge rank_score(8, 5, 7, 6, 4); rank_score(8, 5, 7, 6, 5, 4); rank_score(1, 2, 2, 2, 3); rank_score(1, 12, 123, 1234, 1234, 2); sub rank_score { my (@scores, $num_players, @rank_symbols, @ranks, $s, $score, $rank, $prev, @sorted, $p, $rubric1, $rubric2, $w); # process input @scores = @_; $num_players = scalar @scores - 1; # create rank symbols - GBS456 ... $rank_symbols[$num_players - $_] = $_ > 2 ? $_ + 1: substr('GSB', $_, 1) for (0 .. $num_players); # loop over players sorted by score @sorted = sort {$a <=> $b} @scores; $w = 0; for ($s = 0; $s <= $num_players; $s ++) { # assign rank symbol to score $ranks[$sorted[$s]] = $rank_symbols[$s]; # deal with tied place $ranks[$sorted[$s]] .= '=' if ($s > 0 and $sorted[$s] == $sorted[$s - 1]); # find largest width for neat printout $w = length($sorted[$s]) if $w < length($sorted[$s]); $w = length($ranks[$sorted[$s]]) if $w < length($ranks[$sorted[$s]]); } # show answers for ($p = 0; $p <= $num_players; $p ++) { $rubric1 .= sprintf("%${w}s, ", $scores[$p]); $rubric2 .= sprintf("%${w}s, ", $ranks[$scores[$p]]); } say qq[\nInput: ] . substr($rubric1, 0, -2); say qq[Output: ] . substr($rubric2, 0, -2); }

Input: 8, 5, 7, 6, 4 Output: G, 4, S, B, 5 Input: 8, 5, 7, 6, 5, 4 Output: G, 4=, S, B, 4=, 6 Input: 1, 2, 2, 2, 3 Output: 5, S=, S=, S=, G Input: 1, 12, 123, 1234, 1234, 2 Output: 6, 4, B, G=, G=, 5

The content of
this website
is licensed by
Peter
Campbell Smith under a
Creative Commons Attribution 4.0 International Licence