aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorE. Choroba <choroba@matfyz.cz>2023-04-28 22:17:37 +0200
committerE. Choroba <choroba@matfyz.cz>2023-04-28 22:17:37 +0200
commit9bd049b95c1e03d11fc552c7ac8e5f285547bc00 (patch)
tree3c965c1fe44579ce7be569906e84071e9bee3267
parent579fa7b88b8b452e6c7b52cb203c72cefab01a1c (diff)
downloadperlweeklychallenge-club-9bd049b95c1e03d11fc552c7ac8e5f285547bc00.tar.gz
perlweeklychallenge-club-9bd049b95c1e03d11fc552c7ac8e5f285547bc00.tar.bz2
perlweeklychallenge-club-9bd049b95c1e03d11fc552c7ac8e5f285547bc00.zip
Add solutions to 214: Rank Score & Collect Points by E. Choroba
-rwxr-xr-xchallenge-214/e-choroba/perl/ch-1.pl49
-rwxr-xr-xchallenge-214/e-choroba/perl/ch-2.pl39
2 files changed, 88 insertions, 0 deletions
diff --git a/challenge-214/e-choroba/perl/ch-1.pl b/challenge-214/e-choroba/perl/ch-1.pl
new file mode 100755
index 0000000000..385e2ba1cf
--- /dev/null
+++ b/challenge-214/e-choroba/perl/ch-1.pl
@@ -0,0 +1,49 @@
+#! /usr/bin/perl
+use warnings;
+use strict;
+use experimental qw( signatures );
+
+{ my @MEDALS = qw( G S B );
+
+ sub rank_score(@scores) {
+ my %uniq;
+ @uniq{ sort { $a <=> $b } @scores } = reverse 0 .. $#scores;
+ return [map $MEDALS[$_] // 1 + $_, map $uniq{$_}, @scores]
+ }
+
+ sub rank_score_naive(@scores) {
+ return [
+ map $MEDALS[$_] // 1 + $_,
+ map {
+ my $s = $_;
+ scalar grep $s < $_, @scores
+ } @scores
+ ]
+ }
+}
+
+
+use Test2::V0;
+plan 2 * 4 + 1;
+
+for my $rank_score (*rank_score_naive{CODE}, *rank_score{CODE}) {
+ is $rank_score->(1, 2, 4, 3, 5), [qw[ 5 4 S B G ]], 'Example 1';
+ is $rank_score->(8, 5, 6, 7, 4), [qw[ G 4 B S 5 ]], 'Example 2';
+ is $rank_score->(3, 5, 4, 2), [qw[ B G S 4 ]], 'Example 3';
+ is $rank_score->(2, 5, 2, 1, 7, 5, 1), [qw[ 4 S 4 6 G S 6 ]], 'Example 4';
+}
+
+
+my @arr = map int rand 20, 1 .. 100;
+is rank_score_naive(@arr), rank_score(@arr), 'same';
+
+use Benchmark qw{ cmpthese };
+cmpthese(-3, {
+ naive => sub { rank_score_naive(@arr) },
+ optimised => sub { rank_score(@arr) },
+});
+
+__END__
+ Rate naive optimised
+naive 2214/s -- -89%
+optimised 20641/s 832% --
diff --git a/challenge-214/e-choroba/perl/ch-2.pl b/challenge-214/e-choroba/perl/ch-2.pl
new file mode 100755
index 0000000000..a057ae0dab
--- /dev/null
+++ b/challenge-214/e-choroba/perl/ch-2.pl
@@ -0,0 +1,39 @@
+#!/usr/bin/perl
+use warnings;
+use strict;
+use experimental qw( signatures );
+
+use List::Util qw{ max };
+
+
+sub collect_points(@list) {
+ return max(_collect_points(@list))
+}
+
+sub _collect_points(@list) {
+ return scalar @list if 1 >= @list;
+
+ my %scores;
+ my $pos = 0;
+ while ($pos <= $#list) {
+ my $next = $pos;
+ ++$next while $next < $#list && $list[ $next + 1 ] == $list[$pos];
+
+ my @rest = _collect_points(@list[0 .. $pos - 1, $next + 1 .. $#list]);
+ my $length = 1 + $next - $pos;
+ @scores{ map $length * $length + $_, @rest } = ();
+ $pos = $next + 1;
+ }
+ return keys %scores
+}
+
+
+use Test::More tests => 4 + 2;
+
+is collect_points(2, 4, 3, 3, 3, 4, 5, 4, 2), 23, 'Example 1';
+is collect_points(1, 2, 2, 2, 2, 1), 20, 'Example 2';
+is collect_points(1), 1, 'Example 3';
+is collect_points(2, 2, 2, 1, 1, 2, 2, 2), 40, 'Example 4';
+
+is collect_points(1, 2), 2, 'Simple 2';
+is collect_points(1, 1), 4, 'Simple 4';