Perl Weekly Challenge 182: Unique Array and Date Difference

These are some answers to the Week 183 of the Perl Weekly Challenge organized by Mohammad S. Anwar.

Task 1: Unique Array

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])

Unique Array in Raku

The Raku solution is essentially a one-liner (more than one line because of the tests). We convert the sub-arrays into strings and use the unique built-in routine to remove duplicates.

for ([1,2], [3,4], [5,6], [1,2]), 
    ([9,1], [3,7], [2,5], [2,5]) -> @test {
    @test>>.map({"[$^a, $^b]"}).flat.unique.say;
}

This program displays the following output:

$ raku ./unique-arrays.raku
([1, 2] [3, 4] [5, 6])
([9, 1] [3, 7] [2, 5])

Unique Array in Perl

In Perl, we use the %unique hash to remove duplicates.

use strict;
use warnings;
use feature qw/say/;

for my $test ( [[1,2], [3,4], [5,6], [1,2]], 
               [[9,1], [3,7], [2,5], [2,5]] ) {
    my %unique = map { $_ => 1 } map { "[@$_]"} @$test;
    say join ", ",  keys %unique;
}

Note that, since this is not requested in the task specification, we’re not trying to keep the order of the input. It would be easy to keep the input order with an additional array.

This program displays the following output:

$ perl ./unique-arrays.pl
[3 4], [5 6], [1 2]
[3 7], [2 5], [9 1]

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 on years and days only.

Example 1

    Input: $date1 = '2019-02-10'
           $date2 = '2022-11-01'
    Output: 3 years 264 days

Example 2

    Input: $date1 = '2020-09-15'
           $date2 = '2022-03-29'
    Output: 1 year 195 days

Example 3

    Input: $date1 = '2019-12-31'
           $date2 = '2020-01-01'
    Output: 1 day

Example 4

    Input: $date1 = '2019-12-01'
           $date2 = '2019-12-31'
    Output: 30 days

Example 5

    Input: $date1 = '2019-12-31'
           $date2 = '2020-12-31'
    Output: 1 year

Example 6

    Input: $date1 = '2019-12-31'
           $date2 = '2021-12-31'
    Output: 2 years

Example 7

    Input: $date1 = '2020-09-15'
           $date2 = '2021-09-16'
    Output: 1 year 1 day

Example 8

    Input: $date1 = '2019-09-15'
           $date2 = '2021-09-16'
    Output: 2 years 1 day

Date Difference in Raku

for ('2019-02-10', '2022-11-01'), 
    ('2020-09-15', '2022-03-29'),
    ('2019-12-31', '2020-01-01'),
    ('2019-12-01', '2019-12-31'),
    ('2019-12-31', '2020-12-31'),
    ('2019-12-31', '2021-12-31'),
    ('2020-09-15', '2020-09-16'),
    ('2019-09-15', '2021-09-16') -> @test {
    my @dates = map {Date.new($_) }, sort @test;
    my $delta-y = @dates[1].year - @dates[0].year;
    my ($y, $m, $d) = @dates[0].year, @dates[0].month.fmt("%02d"), 
        @dates[0].day.fmt("%02d");
    $delta-y -= 1 if "$m$d" > join "", @dates[1].month.fmt("%02d"), 
        @dates[1].day.fmt("%02d");
    $y += $delta-y;
    my $new-date = Date.new("$y-$m-$d");
    my $delta-d = @dates[1] - $new-date;
    say "@dates[]: $delta-y year(s) {$delta-d.fmt("%3d")} day(s)";
}

This script displays the following output:

$ raku ./date-diff.raku
2019-02-10 2022-11-01: 3 year(s) 264 day(s)
2020-09-15 2022-03-29: 1 year(s) 195 day(s)
2019-12-31 2020-01-01: 0 year(s)   1 day(s)
2019-12-01 2019-12-31: 0 year(s)  30 day(s)
2019-12-31 2020-12-31: 1 year(s)   0 day(s)
2019-12-31 2021-12-31: 2 year(s)   0 day(s)
2020-09-15 2020-09-16: 0 year(s)   1 day(s)
2019-09-15 2021-09-16: 2 year(s)   1 day(s)

Wrapping up

The next week Perl Weekly Challenge will start soon. If you want to participate in this challenge, please check https://perlweeklychallenge.org/ and make sure you answer the challenge before 23:59 BST (British summer time) on October 2, 2022. And, please, also spread the word about the Perl Weekly Challenge if you can.

Leave a comment

About laurent_r

user-pic I am the author of the "Think Perl 6" book (O'Reilly, 2017) and I blog about the Perl 5 and Raku programming languages.