aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBob Lied <boblied+github@gmail.com>2025-11-03 10:51:05 -0600
committerBob Lied <boblied+github@gmail.com>2025-11-03 10:51:05 -0600
commit63a175f357a49fd05553b3f37e6d1ff506e74b4a (patch)
tree573bfdf5499aab6a92d79edb0104e6fb3055dfc5
parentf4f27bf66e78dacae8759f64053b36bd1995b34f (diff)
downloadperlweeklychallenge-club-63a175f357a49fd05553b3f37e6d1ff506e74b4a.tar.gz
perlweeklychallenge-club-63a175f357a49fd05553b3f37e6d1ff506e74b4a.tar.bz2
perlweeklychallenge-club-63a175f357a49fd05553b3f37e6d1ff506e74b4a.zip
task 1 done
-rw-r--r--challenge-346/bob-lied/README.md8
-rw-r--r--challenge-346/bob-lied/perl/ch-1.pl114
-rw-r--r--challenge-346/bob-lied/perl/ch-2.pl76
3 files changed, 194 insertions, 4 deletions
diff --git a/challenge-346/bob-lied/README.md b/challenge-346/bob-lied/README.md
index ee7721333a..f38a58abd4 100644
--- a/challenge-346/bob-lied/README.md
+++ b/challenge-346/bob-lied/README.md
@@ -1,5 +1,5 @@
-# Solutions to weekly challenge 345 by Bob Lied
+# Solutions to weekly challenge 346 by Bob Lied
-## [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)
+## [PWC](https://perlweeklychallenge.org/blog/perl-weekly-challenge-346/)
+## [GitHub](https://github.com/boblied/perlweeklychallenge-club/tree/master/challenge-346/bob-lied)
+[Blog](https://dev.to/boblied/)
diff --git a/challenge-346/bob-lied/perl/ch-1.pl b/challenge-346/bob-lied/perl/ch-1.pl
new file mode 100644
index 0000000000..f84a011408
--- /dev/null
+++ b/challenge-346/bob-lied/perl/ch-1.pl
@@ -0,0 +1,114 @@
+#!/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 346 Task 1 Longest Parenthesis
+#=============================================================================
+# You are given a string containing only ( and ).
+# Write a script to find the length of the longest valid parenthesis.
+# Example 1 Input: $str = '(()())'
+# Output: 6
+# Valid Parenthesis: '(()())'
+# Example 2 Input: $str = ')()())'
+# Output: 4
+# Valid Parenthesis: '()()' at positions 1-4.
+# Example 3 Input: $str = '((()))()(((()'
+# Output: 8
+# Valid Parenthesis: '((()))()' at positions 0-7.
+# Example 4 Input: $str = '))))((()('
+# Output: 2
+# Valid Parenthesis: '()' at positions 6-7.
+# Example 5 Input: $str = '()(()'
+# Output: 2
+# Valid Parenthesis: '()' at positions 0-1 and 3-4.
+#=============================================================================
+
+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 longestParen($_) for @ARGV;
+
+#=============================================================================
+sub longestParenSub($str)
+{
+ while ( $str =~ s/\((x*)\)/x$1x/g ) { }
+
+ use List::Util qw/max/;
+ return ( max map { length($_) } $str =~ m/x+/g ) // 0;
+}
+sub longestParen($str)
+{
+ my @stack = ( -1 );
+ my $longest = my $streak = 0;
+ my $open = 0;
+ for my ($i, $p) ( indexed split(//, $str) )
+ {
+ if ( $p eq '(' )
+ {
+ push @stack, $i;
+ }
+ else {
+ pop @stack;
+ if ( @stack )
+ {
+ my $len = $i - $stack[-1];
+ $longest = $len if $len > $longest;
+ }
+ else
+ {
+ push @stack, $i;
+ }
+ }
+ $logger->debug("$p i=$i, longest=$longest, stack=(@stack)");
+ }
+
+ return $longest;
+}
+
+sub runTest
+{
+ use Test2::V0;
+
+ is( longestParen('(()())' ), 6, "Example 1");
+ is( longestParen(')()())' ), 4, "Example 2");
+ is( longestParen('((()))()(((()'), 8, "Example 3");
+ is( longestParen('))))((()(' ), 2, "Example 4");
+ is( longestParen('()(()' ), 2, "Example 5");
+ is( longestParen(')))))' ), 0, "None )");
+ is( longestParen('(((((' ), 0, "None (");
+ is( longestParen('))(((' ), 0, "None )(");
+ is( longestParen('(((((())))))' ), 12, "All");
+
+ done_testing;
+}
+
+sub runBenchmark($repeat)
+{
+ use Benchmark qw/cmpthese/;
+
+ my $str = join('', map { int(rand(2)) % 2 ? '(' : ')' } 1..100);
+ $logger->debug($str);
+ cmpthese($repeat, {
+ stack => sub { longestParen($str) },
+ subst => sub { longestParenSub($str) },
+ });
+}
diff --git a/challenge-346/bob-lied/perl/ch-2.pl b/challenge-346/bob-lied/perl/ch-2.pl
new file mode 100644
index 0000000000..47abbaa0c6
--- /dev/null
+++ b/challenge-346/bob-lied/perl/ch-2.pl
@@ -0,0 +1,76 @@
+#!/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 346 Task 2 Magic Expression
+#=============================================================================
+# You are given a string containing only digits and a target integer.
+# Write a script to insert binary operators +, - and * between the digits
+# in the given string that evaluates to target integer.
+# Example 1 Input: $str = "123", $target = 6
+# Output: ("1*2*3", "1+2+3")
+# Example 2 Input: $str = "105", $target = 5
+# Output: ("1*0+5", "10-5")
+# Example 3 Input: $str = "232", $target = 8
+# Output: ("2*3+2", "2+3*2")
+# Example 4 Input: $str = "1234", $target = 10
+# Output: ("1*2*3+4", "1+2+3+4")
+# Example 5 Input: $str = "1001", $target = 2
+# Output: ("1+0*0+1", "1+0+0+1", "1+0-0+1", "1-0*0+1", "1-0+0+1", "1-0-0+1")
+#=============================================================================
+
+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(', ', magic(@ARGV)->@*), ')';
+
+#=============================================================================
+sub magic($str, $target)
+{
+ state @OP = ("", "-", "+", "*");
+ $logger->debug("@OP");
+ my @expr;
+ return \@expr;
+}
+
+sub runTest
+{
+ use Test2::V0;
+
+ is( magic("123", 6), ["1*2*3", "1+2+3" ] , "Example 1");
+ is( magic("105", 5), ["1*0+5", "10-5" ] , "Example 2");
+ is( magic("232", 8), ["2*3+2", "2+3*2" ] , "Example 3");
+ is( magic("1234", 10), ["1*2*3+4", "1+2+3+4"] , "Example 4");
+ is( magic("1001", 2), ["1+0*0+1", "1+0+0+1", "1+0-0+1", "1-0*0+1", "1-0+0+1", "1-0-0+1"] , "Example 5");
+
+ done_testing;
+}
+
+sub runBenchmark($repeat)
+{
+ use Benchmark qw/cmpthese/;
+
+ cmpthese($repeat, {
+ label => sub { },
+ });
+}
+