Peter’s blog ✴ Week 214 ✴ 24 April 2023
THE WEEKLY CHALLENGE
All about points
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.
Example 1 Input: = (1,2,4,3,5) Output: (5,4,S,B,G) Score 1 is the 5th rank. Score 2 is the 4th rank. Score 4 is the 2nd rank i.e. Silver (S). Score 3 is the 3rd rank i.e. Bronze (B). Score 5 is the 1st rank i.e. Gold (G). Example 2 Input: = (8,5,6,7,4) Output: (G,4,B,S,5) Score 8 is the 1st rank i.e. Gold (G). Score 4 is the 4th rank. Score 6 is the 3rd rank i.e. Bronze (B). Score 7 is the 2nd rank i.e. Silver (S). Score 4 is the 5th rank. Example 3 Input: = (3,5,4,2) Output: (B,G,S,4) Example 4 Input: = (2,5,2,1,7,5,1) Output: (4,S,4,6,G,S,6)
This is perhaps not as easy as it sounds, but I did it like this:
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]);
Peter made the task appears simpler and easy to follow by his simple discussion. Bonus you get to play with his solution. Well done.
#!/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); }
18 lines of code
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
Any content of this website which has been created by Peter Campbell Smith is in the public domain