aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBob Lied <boblied+github@gmail.com>2025-10-30 08:30:22 -0500
committerBob Lied <boblied+github@gmail.com>2025-10-30 08:30:22 -0500
commitb9def911dd177e070c3b0a34f5fa196f9e77af58 (patch)
tree487aff53c3b767e8bde86e938d0920cb4c945564
parent9b1eba54d5e59d05df44f336120a6a03be62a645 (diff)
downloadperlweeklychallenge-club-b9def911dd177e070c3b0a34f5fa196f9e77af58.tar.gz
perlweeklychallenge-club-b9def911dd177e070c3b0a34f5fa196f9e77af58.tar.bz2
perlweeklychallenge-club-b9def911dd177e070c3b0a34f5fa196f9e77af58.zip
Week 345 solutions and blog reference
-rw-r--r--challenge-345/bob-lied/README.md8
-rw-r--r--challenge-345/bob-lied/blog.txt1
-rw-r--r--challenge-345/bob-lied/perl/ch-1.pl84
-rw-r--r--challenge-345/bob-lied/perl/ch-2.pl115
4 files changed, 204 insertions, 4 deletions
diff --git a/challenge-345/bob-lied/README.md b/challenge-345/bob-lied/README.md
index e2bb4bd5f2..ee7721333a 100644
--- a/challenge-345/bob-lied/README.md
+++ b/challenge-345/bob-lied/README.md
@@ -1,5 +1,5 @@
-# Solutions to weekly challenge 344 by Bob Lied
+# Solutions to weekly challenge 345 by Bob Lied
-## [PWC](https://perlweeklychallenge.org/blog/perl-weekly-challenge-344/)
-## [GitHub](https://github.com/boblied/perlweeklychallenge-club/tree/master/challenge-344/bob-lied)
-[Blog](https://dev.to/boblied/pwc-344-task-2-pick-up-the-pieces-3391)
+## [PWC](https://perlweeklychallenge.org/blog/perl-weekly-challenge-345/)
+## [GitHub](https://github.com/boblied/perlweeklychallenge-club/tree/master/challenge-345/bob-lied)
+[Blog](https://dev.to/boblied/pwc-345-i-went-to-the-mountains-43i0)
diff --git a/challenge-345/bob-lied/blog.txt b/challenge-345/bob-lied/blog.txt
new file mode 100644
index 0000000000..843ad2ff8a
--- /dev/null
+++ b/challenge-345/bob-lied/blog.txt
@@ -0,0 +1 @@
+https://dev.to/boblied/pwc-345-i-went-to-the-mountains-43i0
diff --git a/challenge-345/bob-lied/perl/ch-1.pl b/challenge-345/bob-lied/perl/ch-1.pl
new file mode 100644
index 0000000000..281b1dbd5e
--- /dev/null
+++ b/challenge-345/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 345 Task 1
+#=============================================================================
+# You are given an array of integers, @ints. Find all the peaks in the array,
+# A peak is an element that is strictly greater than its left and right
+# neighbours. Return the indices of all such peak positions.
+# Example 1 Input: @ints = (1, 3, 2)
+# Output: (1)
+# Example 2 Input: @ints = (2, 4, 6, 5, 3)
+# Output: (2)
+# Example 3 Input: @ints = (1, 2, 3, 2, 4, 1)
+# Output: (2, 4)
+# Example 4 Input: @ints = (5, 3, 1)
+# Output: (0)
+# Example 5 Input: @ints = (1, 5, 1, 5, 1, 5, 1)
+# Output: (1, 3, 5)
+#=============================================================================
+
+use v5.42;
+
+
+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 '(', join(", ", peakPos(@ARGV)->@*), ')';
+
+#=============================================================================
+sub peakPos(@int)
+{
+ my @peak = ();
+ for my ($i, $n) ( indexed @int )
+ {
+ my $left = ( $i == 0 ) ? $n-1 : $int[$i-1];
+ my $right = ( $i == $#int ) ? $n-1 : $int[$i+1];
+ push @peak, $i if ( $n > $left && $n > $right );
+ }
+ return \@peak;
+}
+
+sub runTest
+{
+ use Test2::V0;
+
+ is( peakPos( 1,3,2), [ 1], "Example 1");
+ is( peakPos( 2,4,6,5,3), [ 2], "Example 2");
+ is( peakPos( 1,2,3,2,4,1), [ 2,4], "Example 3");
+ is( peakPos( 5,3,1), [ 0], "Example 4");
+ is( peakPos(1,5,1,5,1,5,1), [1,3,5], "Example 5");
+
+ is( peakPos( 1,2,3,4), [ 3], "Uphill");
+ is( peakPos( 7,7,7,7), [ ], "Flat");
+ is( peakPos( 9), [ 0], "Singleton");
+ is( peakPos( 3,3,3,8,8), [ ], "Plateau");
+
+ done_testing;
+}
+
+sub runBenchmark($repeat)
+{
+ use Benchmark qw/cmpthese/;
+
+ cmpthese($repeat, {
+ label => sub { },
+ });
+}
diff --git a/challenge-345/bob-lied/perl/ch-2.pl b/challenge-345/bob-lied/perl/ch-2.pl
new file mode 100644
index 0000000000..bb72054134
--- /dev/null
+++ b/challenge-345/bob-lied/perl/ch-2.pl
@@ -0,0 +1,115 @@
+#!/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 345 Task 2 Last Visitor
+#=============================================================================
+# You are given an integer array @ints where each element is either a
+# positive integer or -1. We process the array from left to right while
+# maintaining two lists:
+# @seen: stores previously seen positive integers (newest at the front)
+# @ans: stores the answers for each -1
+#
+# Rules:
+# If $ints[i] is a positive number -> insert it at the front of @seen
+# If $ints[i] is -1:
+# Let $x be how many -1s in a row we’ve seen before this one.
+# If $x < len(@seen) -> append seen[x] to @ans
+# Else -> append -1 to @ans
+#
+# At the end, return @ans.
+#
+# Example 1 Input: @ints = (5, -1, -1)
+# Output: (5, -1)
+# @seen = (5)
+# First -1: @ans = (5)
+# Second -1: @ans = (5, -1)
+# Example 2 Input: @ints = (3, 7, -1, -1, -1)
+# Output: (7, 3, -1)
+# @seen = (3, 7)
+# First -1: @ans = (7)
+# Second -1: @ans = (7, 3)
+# Third -1: @ans = (7, 3, -1)
+# Example 3 Input: @ints = (2, -1, 4, -1, -1)
+# Output: (2, 4, 2)
+# Example 4 Input: @ints = (10, 20, -1, 30, -1, -1)
+# Output: (20, 30, 20)
+# Example 5 Input: @ints = (-1, -1, 5, -1)
+# Output: (-1, -1, 5)
+#=============================================================================
+
+use v5.42;
+
+
+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 '(', join(", ", lastVisitor(@ARGV)->@*), ')';
+
+#=============================================================================
+sub lastVisitor(@int)
+{
+ my @seen = ();
+ my @ans = ();
+
+ my $x = 0; # Count of consecutive -1s
+ for ( @int )
+ {
+ if ( $_ > 0 )
+ {
+ $x = 0;
+ unshift @seen, $_;
+ }
+ else
+ {
+ if ( $x < @seen )
+ {
+ push @ans, $seen[$x];
+ }
+ else
+ {
+ push @ans, -1;
+ }
+ $x++;
+ }
+ }
+ return \@ans;
+}
+
+sub runTest
+{
+ use Test2::V0;
+
+ is( lastVisitor( 5, -1, -1 ), [ 5, -1 ], "Example 1");
+ is( lastVisitor( 3, 7, -1, -1, -1 ), [ 7, 3, -1], "Example 2");
+ is( lastVisitor( 2, -1, 4, -1, -1 ), [ 2, 4, 2], "Example 3");
+ is( lastVisitor(10, 20, -1, 30, -1, -1), [20, 30, 20], "Example 4");
+ is( lastVisitor(-1, -1, 5, -1 ), [-1, -1, 5], "Example 5");
+
+ done_testing;
+}
+
+sub runBenchmark($repeat)
+{
+ use Benchmark qw/cmpthese/;
+
+ cmpthese($repeat, {
+ label => sub { },
+ });
+}