aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorboblied <boblied@gmail.com>2023-01-14 08:35:37 -0600
committerboblied <boblied@gmail.com>2023-01-14 08:42:05 -0600
commitcc1f739c471caea91f0130d50949686bce7a659e (patch)
tree35583369b4a0c922bc08b6536302df8b390e62a2
parentffd56fc1d6c761709c368e9742f06865c791b861 (diff)
downloadperlweeklychallenge-club-cc1f739c471caea91f0130d50949686bce7a659e.tar.gz
perlweeklychallenge-club-cc1f739c471caea91f0130d50949686bce7a659e.tar.bz2
perlweeklychallenge-club-cc1f739c471caea91f0130d50949686bce7a659e.zip
Week 187 Task 1 and 2
-rw-r--r--challenge-187/bob-lied/perl/ch-1.pl125
-rw-r--r--challenge-187/bob-lied/perl/ch-2.pl95
2 files changed, 220 insertions, 0 deletions
diff --git a/challenge-187/bob-lied/perl/ch-1.pl b/challenge-187/bob-lied/perl/ch-1.pl
new file mode 100644
index 0000000000..0f6d3335e1
--- /dev/null
+++ b/challenge-187/bob-lied/perl/ch-1.pl
@@ -0,0 +1,125 @@
+#!/usr/bin/env perl
+# vim:set ts=4 sw=4 sts=4 et ai wm=0 nu:
+#=============================================================================
+# ch-1.pl Perl Weekly Challenge Week 187 Task 1 Days Together
+#=============================================================================
+# Copyright (c) 2023, Bob Lied
+#=============================================================================
+# Two friends, Foo and Bar gone on holidays seperately to the same city.
+# You are given their schedule i.e. start date and end date.
+# To keep the task simple, the date is in the form DD-MM and all dates belong
+# to the same calendar year i.e. between 01-01 and 31-12. Also the year is
+# non-leap year and both dates are inclusive.
+# Write a script to find out for the given schedule, how many days they spent
+# together in the city, if at all.
+#
+# Example 1 Input: Foo => SD: '12-01' ED: '20-01'
+# Bar => SD: '15-01' ED: '18-01'
+# Output: 4 days
+#
+# Example 2 Input: Foo => SD: '02-03' ED: '12-03'
+# Bar => SD: '13-03' ED: '14-03'
+# Output: 0 day
+#
+# Example 3 Input: Foo => SD: '02-03' ED: '12-03'
+# Bar => SD: '11-03' ED: '15-03'
+# Output: 2 days
+#
+# Example 4 Input: Foo => SD: '30-03' ED: '05-04'
+# Bar => SD: '28-03' ED: '02-04'
+# Output: 4 days
+#=============================================================================
+
+use v5.36;
+
+use Getopt::Long;
+my $Verbose = 0;
+my $DoTest = 0;
+
+my %Schedule = (
+ example1 => { Foo => { SD => '12-01', ED => '20-01' },
+ Bar => { SD => '15-01', ED => '18-01' },
+ },
+ example2 => { Foo => { SD => '02-03', ED => '12-03' },
+ Bar => { SD => '13-03', ED => '14-03' },
+ },
+ example3 => { Foo => { SD => '02-03', ED => '12-03' },
+ Bar => { SD => '11-03', ED => '15-03' },
+ },
+ example4 => { Foo => { SD => '30-03', ED => '05-04' },
+ Bar => { SD => '28-03', ED => '02-04' },
+ },
+);
+
+GetOptions("test" => \$DoTest, "verbose" => \$Verbose);
+exit(!runTest()) if $DoTest;
+
+if ( @ARGV )
+{
+ my ($fooSD, $fooED, $barSD, $barED) = @ARGV;
+ say _together($fooSD, $fooED, $barSD, $barED);
+}
+else
+{
+ my $Sched="
+ Foo => SD: '12-01' ED: '20-01'
+ Bar => SD: '15-01' ED: '18-01'
+ ";
+
+ my $sch = parseSched($Sched);
+ say together('Foo', 'Bar', $sch);
+
+ $sch = parseSched( qq(X => SD: '02-03' ED: '12-03' Y => SD: '13-03' ED: '14-03') );
+ say together('X', 'Y', $sch);
+}
+
+sub parseSched($s)
+{
+ my %sched;
+ while ( $s =~ m/(\w+) => SD: '([-0-9]+)' ED: '([-0-9]+)'/g )
+ {
+ $sched{$1} = { SD => $2, ED => $3 };
+ }
+ return \%sched;
+}
+
+sub dayOfYear($ddmm)
+{
+ use Time::Piece;
+
+ # Use a non-leap year as default
+ return Time::Piece->strptime("$ddmm-2023", "%d-%m-%Y")->day_of_year;
+}
+
+sub _together($aSD, $aED, $bSD, $bED)
+{
+ my $days = 0;
+ # Test for overlapping ranges
+ if ( $aED >= $bSD && $bSD <= $aED )
+ {
+ use List::Util qw/min max/;
+ $days = min($aED, $bED) - max($aSD, $bSD) + 1;
+ }
+ return $days;
+}
+
+sub together($friendA, $friendB, $sched)
+{
+ my ($aSD, $aED) = map { dayOfYear($_) } $sched->{$friendA}->@{qw/SD ED/};
+ my ($bSD, $bED) = map { dayOfYear($_) } $sched->{$friendB}->@{qw/SD ED/};
+
+ return _together($aSD, $aED, $bSD, $bED);
+}
+
+sub runTest
+{
+ use Test2::V0;
+
+ is( together( "Foo", "Bar", $Schedule{example1} ), 4, "Example 1");
+ is( together( "Foo", "Bar", $Schedule{example2} ), 0, "Example 1");
+ is( together( "Foo", "Bar", $Schedule{example3} ), 2, "Example 1");
+ is( together( "Foo", "Bar", $Schedule{example4} ), 4, "Example 1");
+
+ done_testing;
+}
+
diff --git a/challenge-187/bob-lied/perl/ch-2.pl b/challenge-187/bob-lied/perl/ch-2.pl
new file mode 100644
index 0000000000..d77e0d27ad
--- /dev/null
+++ b/challenge-187/bob-lied/perl/ch-2.pl
@@ -0,0 +1,95 @@
+#!/usr/bin/env perl
+# vim:set ts=4 sw=4 sts=4 et ai wm=0 nu:
+#=============================================================================
+# ch-2.pl Perl Weekly Challenge Week 187 Task 2 Magical Triplets
+#=============================================================================
+# Copyright (c) 2023, Bob Lied
+#=============================================================================
+# You are given a list of positive numbers, @n, having at least 3 numbers.
+# Write a script to find the triplets (a, b, c) from the given list that
+# satisfies the following rules.
+# 1. a + b > c
+# 2. b + c > a
+# 3. a + c > b
+# 4. a + b + c is maximum.
+# In case, you end up with more than one triplet having the maximum then
+# pick the triplet where a >= b >= c.
+#
+# Example 1 Input: @n = (1, 2, 3, 2); Output: (3, 2, 2)
+# Example 2 Input: @n = (1, 3, 2); Output: ()
+# Example 3 Input: @n = (1, 1, 2, 3); Output: ()
+# Example 4 Input: @n = (2, 4, 3); Output: (4, 3, 2)
+#=============================================================================
+
+use v5.36;
+
+use Getopt::Long;
+my $Verbose = 0;
+my $DoTest = 0;
+
+GetOptions("test" => \$DoTest, "verbose" => \$Verbose);
+exit(!runTest()) if $DoTest;
+
+use Memoize;
+memoize('_check');
+sub _check($a, $b, $c)
+{
+ if ( $a + $b > $c && $b + $c > $a && $a + $c > $b )
+ {
+ say "CHECK: ($a $b $c)" if $Verbose;
+ return $a + $b + $c;
+ }
+ return -1;
+}
+
+sub magic($list)
+{
+ my $n = scalar(@$list);
+ my @result = ();
+ my $max = 0;
+
+ my ($a, $b, $c);
+ for ( my $i = 0 ; $i < $n ; $i++ )
+ {
+ for ( my $j = 0; $j < $n ; $j++ )
+ {
+ next if $j == $i;
+ ($a, $b) = $list->@[$i,$j];
+
+ for ( my $k = 0 ; $k < $n ; $k++ )
+ {
+ next if $k == $i || $k == $j;
+
+ $c = $list->[$k];
+ if ( (my $sum = _check($a, $b, $c)) > $max )
+ {
+ say " CHOSE: [$a,$b,$c] = $sum" if $Verbose;
+ @result = ($a, $b, $c);
+ $max = $sum;
+ }
+ elsif ( $sum == $max )
+ {
+ if ( $a >= $b && $b >= $c )
+ {
+ say " CHOSE: [$a,$b,$c] = $sum" if $Verbose;
+ @result = ( $a, $b, $c );
+ }
+ }
+ }
+ }
+ }
+
+ return \@result;
+}
+
+sub runTest
+{
+ use Test2::V0;
+
+ is( magic( [ 1,2,3,2] ), [3,2,2], "Example 1");
+ is( magic( [ 1,3,2 ] ), [ ], "Example 2");
+ is( magic( [ 1,1,2,3] ), [ ], "Example 3");
+ is( magic( [ 2,4,3 ] ), [4,3,2], "Example 4");
+
+ done_testing;
+}