perl logo Perl logo (Thanks to Olaf Alders)

The weekly challenge 336 - Task 2: Final Score

  1 #!/usr/bin/env perl
  2 # https://theweeklychallenge.org/blog/perl-weekly-challenge-336/#TASK2
  3 #
  4 # Task 2: Final Score
  5 # ===================
  6 #
  7 # You are given an array of scores by a team.
  8 #
  9 # Write a script to find the total score of the given team. The score can be
 10 # any integer, +, C or D. The + adds the sum of previous two scores. The score
 11 # C invalidates the previous score. The score D will double the previous score.
 12 #
 13 ## Example 1
 14 ##
 15 ## Input: @scores = ("5","2","C","D","+")
 16 ## Output: 30
 17 ##
 18 ## Round 1: 5
 19 ## Round 2: 5 + 2
 20 ## Round 3: 5 (invalidate the previous score 2)
 21 ## Round 4: 5 + 10 (double the previous score 5)
 22 ## Round 5: 5 + 10 + 15 (sum of previous two scores)
 23 ##
 24 ## Total Scores: 30
 25 #
 26 #
 27 ## Example 2
 28 ##
 29 ## Input: @scores = ("5","-2","4","C","D","9","+","+")
 30 ## Output: 27
 31 ##
 32 ## Round 1: 5
 33 ## Round 2: 5 + (-2)
 34 ## Round 3: 5 + (-2) + 4
 35 ## Round 4: 5 + (-2) (invalidate the previous score 4)
 36 ## Round 5: 5 + (-2) + (-4) (double the previous score -2)
 37 ## Round 6: 5 + (-2) + (-4) + 9
 38 ## Round 7: 5 + (-2) + (-4) + 9 + 5 (sum of previous two scores)
 39 ## Round 8: 5 + (-2) + (-4) + 9 + 5 + 14 (sum of previous two scores)
 40 ##
 41 ## Total Scores: 27
 42 #
 43 #
 44 ## Example 3
 45 ##
 46 ## Input: @scores = ("7","D","D","C","+","3")
 47 ## Output: 45
 48 ##
 49 ## Round 1: 7
 50 ## Round 2: 7 + 14 (double the previous score 7)
 51 ## Round 3: 7 + 14 + 28 (double the previous score 14)
 52 ## Round 4: 7 + 14 (invalidate the previous score 28)
 53 ## Round 5: 7 + 14 + 21 (sum of previous two scores)
 54 ## Round 6: 7 + 14 + 21 + 3
 55 ##
 56 ## Total Scores: 45
 57 #
 58 #
 59 ## Example 4
 60 ##
 61 ## Input: @scores = ("-5","-10","+","D","C","+")
 62 ## Output: -55
 63 ##
 64 ## Round 1: (-5)
 65 ## Round 2: (-5) + (-10)
 66 ## Round 3: (-5) + (-10) + (-15) (sum of previous two scores)
 67 ## Round 4: (-5) + (-10) + (-15) + (-30) (double the previous score -15)
 68 ## Round 5: (-5) + (-10) + (-15) (invalidate the previous score -30)
 69 ## Round 6: (-5) + (-10) + (-15) + (-25) (sum of previous two scores)
 70 ##
 71 ## Total Scores: -55
 72 #
 73 #
 74 ## Example 5
 75 ##
 76 ## Input: @scores = ("3","6","+","D","C","8","+","D","-2","C","+")
 77 ## Output: 128
 78 ##
 79 ## Round  1: 3
 80 ## Round  2: 3 + 6
 81 ## Round  3: 3 + 6 + 9 (sum of previous two scores)
 82 ## Round  4: 3 + 6 + 9 + 18 (double the previous score 9)
 83 ## Round  5: 3 + 6 + 9 (invalidate the previous score 18)
 84 ## Round  6: 3 + 6 + 9 + 8
 85 ## Round  7: 3 + 6 + 9 + 8 + 17 (sum of previous two scores)
 86 ## Round  8: 3 + 6 + 9 + 8 + 17 + 34 (double the previous score 17)
 87 ## Round  9: 3 + 6 + 9 + 8 + 17 + 34 + (-2)
 88 ## Round 10: 3 + 6 + 9 + 8 + 17 + 34 (invalidate the previous score -2)
 89 ## Round 11: 3 + 6 + 9 + 8 + 17 + 34 + 51 (sum of previous two scores)
 90 ##
 91 ## Total Scores: 128
 92 #
 93 ############################################################
 94 ##
 95 ## discussion
 96 ##
 97 ############################################################
 98 #
 99 # For each element in the scores, we add or remove an element from
100 # a stack: either push the double of the last element on the stack
101 # in case of "D", or the sum of the last two elements on the stack
102 # in case of "+", or remove the last element of the stack for a "C",
103 # or push the element otherwise (as then it's a number). In the end,
104 # we just return the sum of all elements on the stack.
105 
106 use v5.36;
107 use List::Util qw(sum);
108 
109 final_score("5","2","C","D","+");
110 final_score("5","-2","4","C","D","9","+","+");
111 final_score("7","D","D","C","+","3");
112 final_score("-5","-10","+","D","C","+");
113 final_score("3","6","+","D","C","8","+","D","-2","C","+");
114 
115 sub final_score(@scores) {
116     say "Input: (\"" . join("\", \"", @scores) . "\")";
117     my @stack = ();
118     foreach my $s (@scores) {
119         if($s eq "D") {
120             push @stack, 2 * $stack[-1];
121         } elsif ($s eq "C") {
122             pop @stack;
123         } elsif ($s eq "+") {
124             push @stack, $stack[-1] + $stack[-2];
125         } else {
126             push @stack, $s;
127         }
128     }
129     say "Output: " . sum(@stack);
130 }