aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMohammad S Anwar <Mohammad.Anwar@yahoo.com>2022-12-10 18:06:48 +0000
committerGitHub <noreply@github.com>2022-12-10 18:06:48 +0000
commit79fa1a944de42fcb638baf9a310da311bd9e1183 (patch)
treec7f845120b784431904760de0fd33faba69200ba
parent7ecd8ea3f1a28c9f1a9fc415f9e7475e1bbb9d56 (diff)
parent14675adfc5a065e22b2ad04a84510248c41f343c (diff)
downloadperlweeklychallenge-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/README4
-rw-r--r--challenge-183/bob-lied/perl/ch-1.pl112
-rw-r--r--challenge-183/bob-lied/perl/ch-2.pl96
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;
+}