aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBob Lied <boblied+github@gmail.com>2025-08-24 22:48:05 -0500
committerBob Lied <boblied+github@gmail.com>2025-08-24 22:48:05 -0500
commit105122e5cc3e47b07ed7f7e8a1c0fff27ed3df91 (patch)
treeb68b23b663c86690972edb4946582afbfd22ed90
parent923952d5af66503e9cd8d065a329f304796eab80 (diff)
downloadperlweeklychallenge-club-105122e5cc3e47b07ed7f7e8a1c0fff27ed3df91.tar.gz
perlweeklychallenge-club-105122e5cc3e47b07ed7f7e8a1c0fff27ed3df91.tar.bz2
perlweeklychallenge-club-105122e5cc3e47b07ed7f7e8a1c0fff27ed3df91.zip
Week 336 solutions
-rw-r--r--challenge-336/bob-lied/README.md6
-rw-r--r--challenge-336/bob-lied/perl/ch-1.pl84
-rw-r--r--challenge-336/bob-lied/perl/ch-2.pl96
3 files changed, 183 insertions, 3 deletions
diff --git a/challenge-336/bob-lied/README.md b/challenge-336/bob-lied/README.md
index 44956b4173..7584e174a8 100644
--- a/challenge-336/bob-lied/README.md
+++ b/challenge-336/bob-lied/README.md
@@ -1,5 +1,5 @@
-# Solutions to weekly challenge 334 by Bob Lied
+# Solutions to weekly challenge 336 by Bob Lied
-## [PWC](https://perlweeklychallenge.org/blog/perl-weekly-challenge-334/)
-## [GitHub](https://github.com/boblied/perlweeklychallenge-club/tree/master/challenge-334/bob-lied)
+## [PWC](https://perlweeklychallenge.org/blog/perl-weekly-challenge-336/)
+## [GitHub](https://github.com/boblied/perlweeklychallenge-club/tree/master/challenge-336/bob-lied)
[Blog](https://dev.to/boblied/pwc-334-first-we-do-the-range-sum-then-we-take-manhattan-3n62)
diff --git a/challenge-336/bob-lied/perl/ch-1.pl b/challenge-336/bob-lied/perl/ch-1.pl
new file mode 100644
index 0000000000..f35ca918cf
--- /dev/null
+++ b/challenge-336/bob-lied/perl/ch-1.pl
@@ -0,0 +1,84 @@
+#!/usr/bin/env perl
+# vim:set ts=4 sw=4 sts=4 et ai wm=0 nu:
+#=============================================================================
+# Copyright (c) 2025, Bob Lied
+#=============================================================================
+# ch-1.pl Perl Weekly Challenge 336 Task 1 Equal Group
+#=============================================================================
+# You are given an array of integers. Write a script to return true if the
+# given array can be divided into one or more groups: each group must be of
+# the same size as the others, with at least two members, and with all members
+# having the same value.
+# Example 1 Input: @ints = (1,1,2,2,2,2)
+# Output: true
+# Groups: (1,1), (2,2), (2,2)
+# Example 2 Input: @ints = (1,1,1,2,2,2,3,3)
+# Output: false
+# Groups: (1,1,1), (2,2,2), (3,3)
+# Example 3 Input: @ints = (5,5,5,5,5,5,7,7,7,7,7,7)
+# Output: true
+# Groups: (5,5,5,5,5,5), (7,7,7,7,7,7)
+# Example 4 Input: @ints = (1,2,3,4)
+# Output: false
+# Example 5 Input: @ints = (8,8,9,9,10,10,11,11)
+# Output: true
+# Groups: (8,8), (9,9), (10,10), (11,11)
+#=============================================================================
+
+use v5.42;
+use feature 'keyword_all'; no warnings 'experimental::keyword_all';
+
+
+use Getopt::Long;
+my $Verbose = false;
+my $DoTest = false;
+my $Benchmark = 0;
+
+GetOptions("test" => \$DoTest, "verbose" => \$Verbose, "benchmark:i" => \$Benchmark);
+my $logger;
+{
+ use Log::Log4perl qw(:easy);
+ Log::Log4perl->easy_init({ level => ($Verbose ? $DEBUG : $INFO ),
+ layout => "%d{HH:mm:ss.SSS} %p{1} %m%n" });
+ $logger = Log::Log4perl->get_logger();
+}
+#=============================================================================
+
+exit(!runTest()) if $DoTest;
+exit( runBenchmark($Benchmark) ) if $Benchmark;
+
+say equalGroup(@ARGV) ? "true": "false";
+
+#=============================================================================
+sub equalGroup(@ints)
+{
+ my %freq;
+ $freq{$_}++ for @ints;
+ my @group = sort { $a <=> $b } values %freq;
+
+ my $small = shift @group;
+ return $small != 1 && all { $_ % $small == 0 } @group;
+}
+
+sub runTest
+{
+ use Test2::V0;
+
+ is( equalGroup(1,1,2,2,2,2), true, "Example 1");
+ is( equalGroup(1,1,1,2,2,2,3), false, "Example 2");
+ is( equalGroup(5,5,5,5,5,5,7,7,7,7,7,7), true, "Example 3");
+ is( equalGroup(1,2,3,4), false, "Example 4");
+ is( equalGroup(8,8,9,9,10,10,11,11), true, "Example 5");
+
+ done_testing;
+}
+
+sub runBenchmark($repeat)
+{
+ use Benchmark qw/cmpthese/;
+
+ cmpthese($repeat, {
+ label => sub { },
+ });
+}
+
diff --git a/challenge-336/bob-lied/perl/ch-2.pl b/challenge-336/bob-lied/perl/ch-2.pl
new file mode 100644
index 0000000000..a962ecb18e
--- /dev/null
+++ b/challenge-336/bob-lied/perl/ch-2.pl
@@ -0,0 +1,96 @@
+#!/usr/bin/env perl
+# vim:set ts=4 sw=4 sts=4 et ai wm=0 nu:
+#=============================================================================
+# Copyright (c) 2025, Bob Lied
+#=============================================================================
+# ch-2.pl Perl Weekly Challenge 336 Task 2 Final Score
+#=============================================================================
+# 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
+#=============================================================================
+
+use v5.42;
+use List::Util qw/sum0/;
+
+
+use Getopt::Long;
+my $Verbose = false;
+my $DoTest = false;
+my $Benchmark = 0;
+
+GetOptions("test" => \$DoTest, "verbose" => \$Verbose, "benchmark:i" => \$Benchmark);
+my $logger;
+{
+ use Log::Log4perl qw(:easy);
+ Log::Log4perl->easy_init({ level => ($Verbose ? $DEBUG : $INFO ),
+ layout => "%d{HH:mm:ss.SSS} %p{1} %m%n" });
+ $logger = Log::Log4perl->get_logger();
+}
+#=============================================================================
+
+exit(!runTest()) if $DoTest;
+exit( runBenchmark($Benchmark) ) if $Benchmark;
+
+say finalScore(@ARGV);
+
+#=============================================================================
+sub finalScore(@score)
+{
+ my $final = 0;
+ my @stack;
+ for my $in ( @score )
+ {
+ if ( $in eq 'C' ) { pop @stack if @stack; }
+ elsif ( $in eq 'D' ) { push @stack, 2*$stack[-1] if @stack; }
+ elsif ( $in eq '+' ) { push @stack, $stack[-1] + $stack[-2] if @stack >= 2; }
+ else { push @stack, $in; }
+ }
+ return sum0 @stack;
+}
+
+sub runTest
+{
+ use Test2::V0;
+
+ is( finalScore(qw(5 2 C D +)), 30, "Example 1");
+ is( finalScore(qw(5 -2 4 C D 9 + +)), 27, "Example 2");
+
+ is( finalScore(qw(D 2)), 2, "Nonsense, initial D");
+ is( finalScore(qw(C 3)), 3, "Nonsense, initial C");
+ is( finalScore(qw(+ 3)), 3, "Nonsense, initial +");
+ is( finalScore(qw(3 + 3)), 6, "Nonsense, + with one arg");
+ is( finalScore(qw(1 2 3 C C C)), 0, 'Cancel everything');
+
+ done_testing;
+}
+
+sub runBenchmark($repeat)
+{
+ use Benchmark qw/cmpthese/;
+
+ cmpthese($repeat, {
+ label => sub { },
+ });
+}