Grouping and scoring
Weekly challenge 336 — 25 August 2025
Week 336: 25 Aug 2025
You are given an array of scores by a team. Write a script to find the total score of the given team. The score can be any integer, +, C or D. The + adds the sum of previous two scores. The score C invalidates the previous score. The score D will double the previous score.
Example 1 Input: @scores = ('5','2','C','D','+') Output: 30 Round 1: 5 Round 2: 5 + 2 Round 3: 5 (invalidate the previous score 2) Round 4: 5 + 10 (double the previous score 5) Round 5: 5 + 10 + 15 (sum of previous two scores) Total Scores: 30 Example 2 Input: @scores = ('5','-2','4','C','D','9','+','+') Output: 27 Round 1: 5 Round 2: 5 + (-2) Round 3: 5 + (-2) + 4 Round 4: 5 + (-2) (invalidate the previous score 4) Round 5: 5 + (-2) + (-4) (double the previous score -2) Round 6: 5 + (-2) + (-4) + 9 Round 7: 5 + (-2) + (-4) + 9 + 5 (sum of previous two scores) Round 8: 5 + (-2) + (-4) + 9 + 5 + 14 (sum of previous two scores) Total Scores: 27 Example 3 Input: @scores = ('7','D','D','C','+','3') Output: 45 Round 1: 7 Round 2: 7 + 14 (double the previous score 7) Round 3: 7 + 14 + 28 (double the previous score 14) Round 4: 7 + 14 (invalidate the previous score 28) Round 5: 7 + 14 + 21 (sum of previous two scores) Round 6: 7 + 14 + 21 + 3 Total Scores: 45 Example 4 Input: @scores = ('-5','-10','+','D','C','+') Output: -55 Round 1: (-5) Round 2: (-5) + (-10) Round 3: (-5) + (-10) + (-15) (sum of previous two scores) Round 4: (-5) + (-10) + (-15) + (-30) (double the previous score -15) Round 5: (-5) + (-10) + (-15) (invalidate the previous score -30) Round 6: (-5) + (-10) + (-15) + (-25) (sum of previous two scores) Total Scores: -55 Example 5 Input: @scores = ('3','6','+','D','C','8','+','D','-2', 'C','+') Output: 128 Round 1: 3 Round 2: 3 + 6 Round 3: 3 + 6 + 9 (sum of previous two scores) Round 4: 3 + 6 + 9 + 18 (double the previous score 9) Round 5: 3 + 6 + 9 (invalidate the previous score 18) Round 6: 3 + 6 + 9 + 8 Round 7: 3 + 6 + 9 + 8 + 17 (sum of previous two scores) Round 8: 3 + 6 + 9 + 8 + 17 + 34 (double the previous score 17) Round 9: 3 + 6 + 9 + 8 + 17 + 34 + (-2) Round 10: 3 + 6 + 9 + 8 + 17 + 34 (invalidate the previous score -2) Round 11: 3 + 6 + 9 + 8 + 17 + 34 + 51 (sum of previous two scores) Total Scores: 128
After a bit of thought I decide that two scans through the data was the way to go.
In the first scan we delete any 'C' element and the element preceding it.
In the second scan we update in place any element containing 'D' or '+' according to the stated rules.
We then total the array, and that's the answer.
We aren't told what to do if the first element isn't numeric, or if '+' appears in the second, so I have reported these as bad data. This also applies if the 'C' elements leave the array empty (eg '1', 'C', '2', 'C').
#!/usr/bin/perl # Blog: http://ccgi.campbellsmiths.force9.co.uk/challenge use v5.26; # The Weekly Challenge - 2025-08-25 use utf8; # Week 336 - task 2 - Final score use warnings; # Peter Campbell Smith binmode STDOUT, ':utf8'; use Encode; final_score('5', '2', 'C', 'D', '+'); final_score('5', '-2', '4', 'C', 'D', '9', '+', '+'); final_score('7', 'D', 'D', 'C', '+', '3'); final_score('-5', '-10', '+', 'D', 'C', '+'); final_score('3', '6', '+', 'D', 'C', '8', '+', 'D', '-2', 'C', '+'); final_score('C', '1', '2'); final_score('D', '1', '2'); final_score('+', '1', '2'); final_score('1', '+', '2'); final_score('1', 'C', '2', 'C'); sub final_score { my (@scores, $total, $prev1, $prev2, $score, $i); say qq[\nInput: ('] . join(qq[', '], @_) . q[')]; # get rid of C and scores preceding a C $scores[0] = $_[0]; for ($i = 1; $i < scalar @_; $i ++) { if ($_[$i] eq 'C') { pop @scores; } else { push @scores, $_[$i]; } } # bad input if (scalar @scores == 0 or $scores[0] !~ m|^-?\d+$| or $scores[1] eq '+') { say qq[Output: bad data]; return; } # handle D and + for $i (1 .. $#scores) { if ($scores[$i] eq '+' and $i >= 2) { $scores[$i] = $scores[$i - 1] + $scores[$i - 2]; } elsif ($scores[$i] eq 'D') { $scores[$i] = $scores[$i - 1] * 2; } } $total += $_ for @scores; say qq[Output: $total]; }
Input: ('5', '2', 'C', 'D', '+') Output: 30 Input: ('5', '-2', '4', 'C', 'D', '9', '+', '+') Output: 27 Input: ('7', 'D', 'D', 'C', '+', '3') Output: 45 Input: ('-5', '-10', '+', 'D', 'C', '+') Output: -55 Input: ('3', '6', '+', 'D', 'C', '8', '+', 'D', '-2', 'C', '+') Output: 128 Input: ('C', '1', '2') Output: bad data Input: ('D', '1', '2') Output: bad data Input: ('+', '1', '2') Output: bad data Input: ('1', '+', '2') Output: bad data Input: ('1', 'C', '2', 'C') Output: bad data
Any content of this website which has been created by Peter Campbell Smith is in the public domain