diff options
| author | boblied <boblied@gmail.com> | 2023-01-14 08:35:37 -0600 |
|---|---|---|
| committer | boblied <boblied@gmail.com> | 2023-01-14 08:42:05 -0600 |
| commit | cc1f739c471caea91f0130d50949686bce7a659e (patch) | |
| tree | 35583369b4a0c922bc08b6536302df8b390e62a2 | |
| parent | ffd56fc1d6c761709c368e9742f06865c791b861 (diff) | |
| download | perlweeklychallenge-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.pl | 125 | ||||
| -rw-r--r-- | challenge-187/bob-lied/perl/ch-2.pl | 95 |
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; +} |
