diff options
| author | Mohammad S Anwar <Mohammad.Anwar@yahoo.com> | 2022-12-10 18:06:48 +0000 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-12-10 18:06:48 +0000 |
| commit | 79fa1a944de42fcb638baf9a310da311bd9e1183 (patch) | |
| tree | c7f845120b784431904760de0fd33faba69200ba | |
| parent | 7ecd8ea3f1a28c9f1a9fc415f9e7475e1bbb9d56 (diff) | |
| parent | 14675adfc5a065e22b2ad04a84510248c41f343c (diff) | |
| download | perlweeklychallenge-club-79fa1a944de42fcb638baf9a310da311bd9e1183.tar.gz perlweeklychallenge-club-79fa1a944de42fcb638baf9a310da311bd9e1183.tar.bz2 perlweeklychallenge-club-79fa1a944de42fcb638baf9a310da311bd9e1183.zip | |
Merge pull request #7225 from boblied/master
Backlog week 183
| -rw-r--r-- | challenge-183/bob-lied/README | 4 | ||||
| -rw-r--r-- | challenge-183/bob-lied/perl/ch-1.pl | 112 | ||||
| -rw-r--r-- | challenge-183/bob-lied/perl/ch-2.pl | 96 |
3 files changed, 210 insertions, 2 deletions
diff --git a/challenge-183/bob-lied/README b/challenge-183/bob-lied/README index c231e3a589..1e11ead722 100644 --- a/challenge-183/bob-lied/README +++ b/challenge-183/bob-lied/README @@ -1,3 +1,3 @@ -Solutions to weekly challenge 138 by Bob Lied +Solutions to weekly challenge 183 by Bob Lied -https://perlweeklychallenge.org/blog/perl-weekly-challenge-138/ +https://perlweeklychallenge.org/blog/perl-weekly-challenge-183/ diff --git a/challenge-183/bob-lied/perl/ch-1.pl b/challenge-183/bob-lied/perl/ch-1.pl new file mode 100644 index 0000000000..ecdab9aafd --- /dev/null +++ b/challenge-183/bob-lied/perl/ch-1.pl @@ -0,0 +1,112 @@ +#!/usr/bin/env perl +# vim:set ts=4 sw=4 sts=4 et ai wm=0 nu: +#============================================================================= +# Perl Weekly Challenge Week 183 Task 1 Unique Array +#============================================================================= +# Copyright (c) 2022, Bob Lied +#============================================================================= +# You are given list of arrayrefs. +# Write a script to remove the duplicate arrayrefs from the given list. +# +# Example 1 +# Input: @list = ([1,2], [3,4], [5,6], [1,2]) +# Output: ([1,2], [3,4], [5,6]) +# +# Example 2 +# Input: @list = ([9,1], [3,7], [2,5], [2,5]) +# Output: ([9, 1], [3,7], [2,5]) +#============================================================================= + +use strict; +use warnings; +use v5.32; + +use experimental qw/ signatures /; +no warnings "experimental::signatures"; + +use FindBin qw($Bin); +use lib "$FindBin::Bin"; + +use Getopt::Long; +my $Verbose = 0; +my $DoTest = 0; + +GetOptions("test" => \$DoTest, "verbose" => \$Verbose); +exit(!runTest()) if $DoTest; + +sub hashArray($arr) +{ + # Assuming $arr is an array of scalars + # ASCII Record Separator code 30 (\036, 0x1e) + return join("\036", $arr->@*); +} + +# To avoid a O(n^2) pairwise comparison, reduce each array +# to a hash and keep a lookup table of hashes we've seen. +sub uniqArray($arr) +{ + my @result; + return [] if ! scalar($arr->@*); + + my %hash; + for my $ref ( $arr->@* ) + { + push @result, $ref unless $hash{hashArray($ref)}++; + } + return \@result; +} + +sub runTest +{ + use Test::More; + + my @TestCase = ( + { input => [ ], + output => [ ], + desc => "Empty", + }, + { input => [ [1,2] ], + output => [ [1,2] ], + desc => "Singleton", + }, + { input => [ [1,2], [3,4] ], + output => [ [1,2], [3,4] ], + desc => "Two unique", + }, + { input => [ [1,2], [1,2] ], + output => [ [1,2] ], + desc => "One duplicate" + }, + { input => [ [1,2], [1,2], [1,2], [1,2] ], + output => [ [1,2] ], + desc => "Multiple duplicate", + }, + { input => [ [3,4], [1,2], [1,2] ], + output => [ [3,4], [1,2] ], + desc => "Dup pair at end", + }, + { input => [ [1,2], [3,4], [5,6], [1,2] ], + output => [ [1,2], [3,4], [5,6] ], + desc => "Dup at end" + }, + { input => [ [9,1], [3,7], [2,5], [3,7] ], + output => [ [9, 1], [3,7], [2,5] ], + desc => "Dup in middle" + }, + { input => [ [9,1], [3,7], [2,5], [2,5], [3,7], [9,1] ], + output => [ [9, 1], [3,7], [2,5] ], + desc => "All dups" + }, + { input => [ ["a","b"], ["c","d"] ], + output => [ ["a","b"], ["c","d"] ], + desc => "Strings" + } + ); + + while ( my ($no, $tc) = each(@TestCase) ) + { + is_deeply( uniqArray($tc->{input}), $tc->{output}, $tc->{desc} ); + } + + done_testing(); +} diff --git a/challenge-183/bob-lied/perl/ch-2.pl b/challenge-183/bob-lied/perl/ch-2.pl new file mode 100644 index 0000000000..13baf2830b --- /dev/null +++ b/challenge-183/bob-lied/perl/ch-2.pl @@ -0,0 +1,96 @@ +#!/bin/env perl +# +# Task 2: Date Difference +# +# You are given two dates, $date1 and $date2 in the format YYYY-MM-DD. +# +# Write a script to find the difference between the given dates in terms +# of years and days only. +# Example: Input: $date1 = '2019-02-10' +# $date2 = '2022-11-01' +# Output: 3 years 264 days +# + +use v5.36; +use strict; +use warnings; + +use Time::Piece; +use Time::Seconds; + +use Getopt::Long; +my $Verbose = 0; +my $DoTest = 0; + +GetOptions("test" => \$DoTest, "verbose" => \$Verbose); +exit(!runTest()) if $DoTest; + +sub pluralize($n, $unit) +{ + return "" if $n == 0; + return "$n $unit" if $n == 1; + return "$n ${unit}s"; +} + +sub dateDiff($startDate, $endDate) +{ + + if ( $startDate gt $endDate ) + { + ($startDate, $endDate) = ($startDate, $endDate); + } + say "$startDate TO $endDate" if $Verbose; + + my ( $yearDiff, $dayDiff) = (0, 0); + + my ($startYear, $startMonDay) = ($startDate =~ m/(\d\d\d\d)-(\d\d-\d\d)/); + my ($endYear, $endMonDay) = ($endDate =~ m/(\d\d\d\d)-(\d\d-\d\d)/); + say "SPLIT: [$startYear]-[$startMonDay] TO [$endYear]-[$endMonDay]" if $Verbose; + + $yearDiff = $endYear - $startYear; + $startYear = $endYear; + if ( $startMonDay gt $endMonDay ) + { + $yearDiff--; + $startYear--; + } + say "years = $yearDiff" if $Verbose; + + my $st = Time::Piece->strptime("$startYear-$startMonDay", "%Y-%m-%d"); + my $et = Time::Piece->strptime("$endYear-$endMonDay", "%Y-%m-%d"); + say "$st TO $et" if $Verbose; + my $timeDiff = $et - $st; + $dayDiff = $timeDiff->days; + + my $answer; + $answer = pluralize($yearDiff, "year") + . ( ( $yearDiff != 0 && $dayDiff != 0 ) ? " " : "" ) + . ($dayDiff != 0 ? pluralize($dayDiff, "day") : "") + ; + + return $answer; +} + +sub runTest +{ + my @TestCase = ( + [ '2019-02-10', '2022-11-01', "3 years 264 days" ], + [ '2020-09-15', '2022-03-29', "1 year 195 days" ], + [ '2019-12-31', '2020-01-01', "1 day" ], + [ '2019-12-01', '2019-12-31', "30 days" ], + [ '2019-12-31', '2020-12-31', "1 year" ], + [ '2019-12-31', '2021-12-31', "2 years" ], + [ '2020-09-15', '2021-09-16', "1 year 1 day" ], + [ '2019-09-15', '2021-09-16', "2 years 1 day" ], + [ '1958-11-09', '2022-11-30', "64 years 21 days" ], + ); + + use Test::More; + + for my $test ( @TestCase ) + { + is( dateDiff($test->[0], $test->[1]), $test->[2], "@$test"); + } + + done_testing; +} |
