aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--challenge-318/bob-lied/README.md6
-rw-r--r--challenge-318/bob-lied/perl/ch-1.pl59
-rw-r--r--challenge-318/bob-lied/perl/ch-2.pl81
3 files changed, 143 insertions, 3 deletions
diff --git a/challenge-318/bob-lied/README.md b/challenge-318/bob-lied/README.md
index 6f5780a79d..4fc0332efa 100644
--- a/challenge-318/bob-lied/README.md
+++ b/challenge-318/bob-lied/README.md
@@ -1,4 +1,4 @@
-# Solutions to weekly challenge 317 by Bob Lied
+# Solutions to weekly challenge 318 by Bob Lied
-## [PWC](https://perlweeklychallenge.org/blog/perl-weekly-challenge-317/)
-## [GitHub](https://github.com/boblied/perlweeklychallenge-club/tree/master/challenge-317/bob-lied)
+## [PWC](https://perlweeklychallenge.org/blog/perl-weekly-challenge-318/)
+## [GitHub](https://github.com/boblied/perlweeklychallenge-club/tree/master/challenge-318/bob-lied)
diff --git a/challenge-318/bob-lied/perl/ch-1.pl b/challenge-318/bob-lied/perl/ch-1.pl
new file mode 100644
index 0000000000..414321bec5
--- /dev/null
+++ b/challenge-318/bob-lied/perl/ch-1.pl
@@ -0,0 +1,59 @@
+#!/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 318 Task 1 Group Position
+#=============================================================================
+# You are given a string of lowercase letters. Write a script to find the
+# position of all groups in the given string. Three or more consecutive
+# letters form a group. Return "” if none found.
+# Example 1 Input: $str = "abccccd"
+# Output: "cccc"
+# Example 2 Input: $str = "aaabcddddeefff"
+# Output: "aaa", "dddd", "fff"
+# Example 3 Input: $str = "abcdd"
+# Output: ""
+#=============================================================================
+
+use v5.40;
+
+
+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('", "', groupPosition($_)->@*), '"' for @ARGV;
+
+#=============================================================================
+sub groupPosition($str)
+{
+ my @group;
+ push @group, $1 while ( $str =~ m/((.)\2{2,})/g );
+ return \@group;
+}
+
+sub runTest
+{
+ use Test2::V0;
+
+ is( groupPosition("abccccd"), [ "cccc" ], "Example 1");
+ is( groupPosition("aaabcddddeefff"), [ "aaa", "dddd", "fff" ], "Example 2");
+ is( groupPosition("abcdd"), [ ], "Example 3");
+
+ done_testing;
+}
diff --git a/challenge-318/bob-lied/perl/ch-2.pl b/challenge-318/bob-lied/perl/ch-2.pl
new file mode 100644
index 0000000000..f1e1d79da7
--- /dev/null
+++ b/challenge-318/bob-lied/perl/ch-2.pl
@@ -0,0 +1,81 @@
+#!/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 318 Task 2 Reverse Equals
+#=============================================================================
+# You are given two arrays of integers, each containing the same elements
+# as the other. Write a script to return true if one array can be made to
+# equal the other by reversing exactly one contiguous subarray.
+# Example 1 Input: @source = (3, 2, 1, 4); @target = (1, 2, 3, 4)
+# Output: true
+# Reverse elements: 0-2
+#
+# Example 2 Input: @source = (1, 3, 4); @target = (4, 1, 3)
+# Output: false
+#
+# Example 3 Input: @source = (2); @target = (2)
+# Output: true
+#=============================================================================
+
+use v5.40;
+
+use Getopt::Long;
+my $DoTest = false;
+
+GetOptions("test" => \$DoTest);
+#=============================================================================
+
+exit(!runTest()) if $DoTest;
+
+# Command line usage: two lists given as strings,
+# Example: perl ch-2.pl "1 2 3 4" "1 3 2 4"
+
+say revEq( [split(/[\D]/, $ARGV[0])], [split(/[\D]/, $ARGV[1])]) ? "true" : "false";
+
+#=============================================================================
+sub revEq ($source, $target)
+{
+ use List::Util qw/zip/;
+ use List::MoreUtils qw/first_index last_index/;
+
+ # Arrays must be the same size
+ return false if $source->$#* != $target->$#*;
+
+ # Combine the two arrays into pairs
+ my @pair = zip($source, $target);
+
+ # Find the left segment of equal elements
+ my $left = first_index { $_->[0] != $_->[1] } @pair;
+
+ # If strings are equal, we can stop
+ return true if $left == -1;
+
+ # Find the right segment of equal elements
+ my $right = last_index { $_->[0] != $_->[1] } @pair;
+
+ # Extract the middle that could be reversed.
+ my @midsrc = $source->@[$left .. $right];
+ my @midtrg = $target->@[$left .. $right];
+
+ # Check that one is the reverse of the other
+ while ( @midsrc && shift @midsrc == pop @midtrg ) {}
+ return @midsrc == 0;
+}
+
+sub runTest
+{
+ use Test2::V0;
+
+ is( revEq([3,2,1,4], [1,2,3,4]), true, "Example 1");
+ is( revEq([1,3,4 ], [4,1,3 ]), false, "Example 2");
+ is( revEq([2 ], [2 ]), true, "Example 3");
+
+ is( revEq([2,3,4,1], [2,3,4,1]), true, "Equal arrays");
+ is( revEq([ ], [ ]), true, "Empty arrays");
+ is( revEq([2,1,4,3], [2,3,4,1]), true, "Right side");
+ is( revEq([2,1,4,3], [2,4,1,3]), true, "Middle");
+
+ done_testing;
+}