aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--challenge-214/jeanluc2020/blog-1.txt1
-rw-r--r--challenge-214/jeanluc2020/blog-2.txt1
-rwxr-xr-xchallenge-214/jeanluc2020/perl/ch-1.pl101
-rwxr-xr-xchallenge-214/jeanluc2020/perl/ch-2.pl122
4 files changed, 225 insertions, 0 deletions
diff --git a/challenge-214/jeanluc2020/blog-1.txt b/challenge-214/jeanluc2020/blog-1.txt
new file mode 100644
index 0000000000..5d8dd8e473
--- /dev/null
+++ b/challenge-214/jeanluc2020/blog-1.txt
@@ -0,0 +1 @@
+http://gott-gehabt.de/800_wer_wir_sind/thomas/Homepage/Computer/perl/theweeklychallenge-214-1.html
diff --git a/challenge-214/jeanluc2020/blog-2.txt b/challenge-214/jeanluc2020/blog-2.txt
new file mode 100644
index 0000000000..1014d9368b
--- /dev/null
+++ b/challenge-214/jeanluc2020/blog-2.txt
@@ -0,0 +1 @@
+http://gott-gehabt.de/800_wer_wir_sind/thomas/Homepage/Computer/perl/theweeklychallenge-214-2.html
diff --git a/challenge-214/jeanluc2020/perl/ch-1.pl b/challenge-214/jeanluc2020/perl/ch-1.pl
new file mode 100755
index 0000000000..a7e35901c3
--- /dev/null
+++ b/challenge-214/jeanluc2020/perl/ch-1.pl
@@ -0,0 +1,101 @@
+#!/usr/bin/perl
+# https://theweeklychallenge.org/blog/perl-weekly-challenge-214/#TASK1
+#
+# Task 1: Rank Score
+# ==================
+#
+# 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.
+#
+# Using the standard model of giving equal scores equal rank, then
+# advancing that number of ranks.
+#
+## Example 1
+##
+## Input: @scores = (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: @scores = (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: @list = (3,5,4,2)
+## Output: (B,G,S,4)
+#
+## Example 4
+##
+## Input: @scores = (2,5,2,1,7,5,1)
+## Output: (4,S,4,6,G,S,6)
+#
+############################################################
+##
+## discussion
+##
+############################################################
+#
+# First, we fill a hash with the amount of hits for each score
+# Then we sort the found scores and calculate their rank
+# Then we put the rank of each element in the scores into
+# the result array.
+
+use strict;
+use warnings;
+
+rank_score(1,2,4,3,5);
+rank_score(8,5,6,7,4);
+rank_score(3,5,4,2);
+rank_score(2,5,2,1,7,5,1);
+
+sub rank_score {
+ my @scores = @_;
+ print "Input: (" . join (",", @scores) . ")\n";
+ my %seen = ();
+ my %ranks = ();
+ my %medal = (
+ 1 => "G",
+ 2 => "S",
+ 3 => "B"
+ );
+ # How often do we have each score?
+ foreach my $score (@scores) {
+ $seen{$score}++;
+ }
+ # Starting with the first rank, we fill the ranks hash
+ # If the rank is < 4 we have a medal, so let's assign that
+ # from the %medal hash. Otherwise, we have a numbered rank
+ # that we can assign directly
+ my $rank = 1;
+ foreach my $key (sort {$b<=>$a} keys %seen) {
+ if($rank < 4) {
+ $ranks{$key} = $medal{$rank};
+ } else {
+ $ranks{$key} = $rank;
+ }
+ $rank += $seen{$key};
+ }
+ # now we can put together the result
+ my @result = ();
+ foreach my $score (@scores) {
+ push @result, $ranks{$score};
+ }
+ print "Output: (" . join(",", @result) . ")\n";
+}
+
diff --git a/challenge-214/jeanluc2020/perl/ch-2.pl b/challenge-214/jeanluc2020/perl/ch-2.pl
new file mode 100755
index 0000000000..3001cb12f2
--- /dev/null
+++ b/challenge-214/jeanluc2020/perl/ch-2.pl
@@ -0,0 +1,122 @@
+#!/usr/bin/perl
+# https://theweeklychallenge.org/blog/perl-weekly-challenge-214/#TASK2
+#
+# Task 2: Collect Points
+# ======================
+#
+# You are given a list of numbers.
+#
+# You will perform a series of removal operations. For each operation, you
+# remove from the list N (one or more) equal and consecutive numbers, and add
+# to your score N × N.
+#
+# Determine the maximum possible score.
+#
+## Example 1:
+##
+## Input: @numbers = (2,4,3,3,3,4,5,4,2)
+## Output: 23
+##
+## We see three 3's next to each other so let us remove that first and collect 3 x 3 points.
+## So now the list is (2,4,4,5,4,2).
+## Let us now remove 5 so that all 4's can be next to each other and collect 1 x 1 point.
+## So now the list is (2,4,4,4,2).
+## Time to remove three 4's and collect 3 x 3 points.
+## Now the list is (2,2).
+## Finally remove both 2's and collect 2 x 2 points.
+## So the total points collected is 9 + 1 + 9 + 4 => 23.
+#
+## Example 2:
+##
+## Input: @numbers = (1,2,2,2,2,1)
+## Output: 20
+##
+## Remove four 2's first and collect 4 x 4 points.
+## Now the list is (1,1).
+## Finally remove the two 1's and collect 2 x 2 points.
+## So the total points collected is 16 + 4 => 20.
+#
+## Example 3:
+##
+## Input: @numbers = (1)
+## Output: 1
+#
+## Example 4:
+##
+## Input: @numbers = (2,2,2,1,1,2,2,2)
+## Output: 40
+##
+## Remove two 1's = 2 x 2 points.
+## Now the list is (2,2,2,2,2,2).
+## Then reomove six 2's = 6 x 6 points.
+#
+############################################################
+##
+## discussion
+##
+############################################################
+#
+# We calculate the maximum by trying to remove consecutive
+# same numbers from every position in the array, calculating
+# the maximum points we can get with the remaining numbers
+# and adding it to the points we generated in this first step.
+
+use strict;
+use warnings;
+use Data::Dumper;
+
+collect_points(2,4,3,3,3,4,5,4,2);
+collect_points(1,2,2,2,2,1);
+collect_points(1);
+collect_points(2,2,2,1,1,2,2,2);
+
+sub collect_points {
+ my @numbers = @_;
+ print "Input: (" . join(",", @numbers) . ")\n";
+ print "Output: " . maximum_possible(@numbers) . "\n";
+}
+
+sub maximum_possible {
+ my @numbers = @_;
+ return 0 unless @numbers;
+ my $max = 0;
+ foreach my $i (0..$#numbers) {
+ # how many points (and which rest) do we get if we remove
+ # consecutive same numbers starting at position i?
+ my ($points, @rest) = remove_consecutive($i, @numbers);
+ my $this = $points + maximum_possible(@rest);
+ $max = $this if $this > $max;
+ }
+ return $max;
+}
+
+sub remove_consecutive {
+ my ($index, @numbers) = @_;
+ return (0) unless @numbers;
+ my $points = 0;
+ my @rest = ();
+ if($index > 0) {
+ if($numbers[$index-1] == $numbers[$index]) {
+ # we've been here already in a previous call,
+ # so we can exit now
+ return (0);
+ }
+ }
+ # currently, we haven't removed anything
+ my $count = 0;
+ # just keep the rest up to the current index
+ @rest = @numbers[0..$index-1];
+ # find the last index that has the same number as the
+ # one at $index
+ my $last_index = $index;
+ foreach my $i ($index..$#numbers) {
+ last if $numbers[$i] != $numbers[$index];
+ $count++;
+ $last_index = $i;
+ }
+ # how many points did we get?
+ $points = $count * $count;
+ # keep the remaining rest of the array.
+ push @rest, @numbers[$last_index+1..$#numbers];
+ return($points, @rest);
+}