1 #!/usr/bin/perl
  2 # https://theweeklychallenge.org/blog/perl-weekly-challenge-214/#TASK1
  3 #
  4 # Task 1: Rank Score
  5 # ==================
  6 #
  7 # You are given a list of scores (>=1).
  8 #
  9 # Write a script to rank each score in descending order. First three will get
 10 # medals i.e. G (Gold), S (Silver) and B (Bronze). Rest will just get the
 11 # ranking number.
 12 #
 13 #     Using the standard model of giving equal scores equal rank, then
 14 #     advancing that number of ranks.
 15 #
 16 ## Example 1
 17 ##
 18 ## Input: @scores = (1,2,4,3,5)
 19 ## Output: (5,4,S,B,G)
 20 ##
 21 ## Score 1 is the 5th rank.
 22 ## Score 2 is the 4th rank.
 23 ## Score 4 is the 2nd rank i.e. Silver (S).
 24 ## Score 3 is the 3rd rank i.e. Bronze (B).
 25 ## Score 5 is the 1st rank i.e. Gold (G).
 26 #
 27 ## Example 2
 28 ##
 29 ## Input: @scores = (8,5,6,7,4)
 30 ## Output: (G,4,B,S,5)
 31 ##
 32 ## Score 8 is the 1st rank i.e. Gold (G).
 33 ## Score 4 is the 4th rank.
 34 ## Score 6 is the 3rd rank i.e. Bronze (B).
 35 ## Score 7 is the 2nd rank i.e. Silver (S).
 36 ## Score 4 is the 5th rank.
 37 #
 38 ## Example 3
 39 ##
 40 ## Input: @list = (3,5,4,2)
 41 ## Output: (B,G,S,4)
 42 #
 43 ## Example 4
 44 ##
 45 ## Input: @scores = (2,5,2,1,7,5,1)
 46 ## Output: (4,S,4,6,G,S,6)
 47 #
 48 ############################################################
 49 ##
 50 ## discussion
 51 ##
 52 ############################################################
 53 #
 54 # First, we fill a hash with the amount of hits for each score
 55 # Then we sort the found scores and calculate their rank
 56 # Then we put the rank of each element in the scores into
 57 # the result array.
 58 
 59 use strict;
 60 use warnings;
 61 
 62 rank_score(1,2,4,3,5);
 63 rank_score(8,5,6,7,4);
 64 rank_score(3,5,4,2);
 65 rank_score(2,5,2,1,7,5,1);
 66 
 67 sub rank_score {
 68    my @scores = @_;
 69    print "Input: (" . join (",", @scores) . ")\n";
 70    my %seen = ();
 71    my %ranks = ();
 72    my %medal = (
 73       1 => "G",
 74       2 => "S",
 75       3 => "B"
 76    );
 77    # How often do we have each score?
 78    foreach my $score (@scores) {
 79       $seen{$score}++;
 80    }
 81    # Starting with the first rank, we fill the ranks hash
 82    # If the rank is < 4 we have a medal, so let's assign that
 83    # from the %medal hash. Otherwise, we have a numbered rank
 84    # that we can assign directly
 85    my $rank = 1;
 86    foreach my $key (sort {$b<=>$a} keys %seen) {
 87       if($rank < 4) {
 88          $ranks{$key} = $medal{$rank};
 89       } else {
 90          $ranks{$key} = $rank;
 91       }
 92       $rank += $seen{$key};
 93    }
 94    # now we can put together the result
 95    my @result = ();
 96    foreach my $score (@scores) {
 97       push @result, $ranks{$score};
 98    }
 99    print "Output: (" . join(",", @result) . ")\n";
100 }
101