Monday, August 21, 2023

TWC231

 Challenge Link

Task1

We are asked to find the min and max elements of the array and then return those elements which are not equal to them. If the array length is less than 3 items we simply return -1 since there cannot be any other elements than that of min and max:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
#!/usr/bin/env perl
use strict;
use warnings;
use List::Util qw(min max);

sub min_max
{
  my ($arr) = @_;
  return "-1\n" if @$arr < 3;
  my ($min,$max) = (min(@$arr),max(@$arr));
  sprintf "(%s)\n", join ',', grep{$_ != $min && $_ != $max} @$arr;
}

print min_max([3,2,1,4]);
print min_max([3,1]);
print min_max([2,1,3]);

Task2

The age is in the 4th position from the end of the string so we use substr to extract that and count how many of them are greater than or equal to 60:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
#!/usr/bin/env perl
use strict;
use warnings;

sub senior_citizens
{
  scalar grep{substr($_,-4,2) >= 60} @{$_[0]};
}

printf "%d\n",senior_citizens(["7868190130M7522",
			       "5303914400F9211",
			       "9273338290F4010"]);
printf "%d\n",senior_citizens(["1313579440F2036",
			       "2921522980M5644"]);

Monday, August 14, 2023

TWC230

 Challenge Link

Task1

We are asked to break the numbers which are greater than 9 to their constituent digits and splice them into the array which can be simply done with a split on an empty string in Perl:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
#!/usr/bin/env perl
use strict;
use warnings;

sub separate_digits
{
  map{split ''} @{$_[0]};
}

printf "(%s)\n", join ",", separate_digits([1,34,5,6]);
printf "(%s)\n", join ",", separate_digits([1,24,51,60]);

Task2

We are asked to count the words starting with a prefix, which can be done with the '^' symbol and the regexp's powerful mechanism. I've also used the quotemeta to escape magic characters so that the variable is correctly interpolated inside the regex pattern:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
#!/usr/bin/env perl
use strict;
use warnings;

sub count_words
{
  scalar grep{/^\Q$_[1]/} @{$_[0]};
}

printf "%d\n",count_words([qw/pay attention practice attend/],'at');
printf "%d\n",count_words([qw/janet julia java javascript/],'ja');

Sunday, August 6, 2023

TWC229

 Challenge Link

Task1

We are asked to delete the elements which are not lexicographically sorted forwards and backwards, and return the count of the deletions. We are actually not deleting anything from the array in the code, just counting them.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
#!/usr/bin/env perl
use strict;
use warnings;

sub lexicographic_order
{
  my $count = 0;
  map{
    my $s = join '',sort split '';
    $count++ if(($s ne $_) && (reverse($s) ne $_))} @{$_[0]};
  $count;
}

printf "%d\n",lexicographic_order(["abc", "bce", "cae"]);
printf "%d\n",lexicographic_order(["yxz", "cba", "mon"]);

Task2

We are asked to return the elements present at least in 2 of the arrays, so this is a simple intersection which can be accomplished by counting the elements' occurrences with a hash.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
#!/usr/bin/env perl
use strict;
use warnings;
use List::Util qw(uniq);

sub two_out_of_three
{
  my %hash;
  map{$hash{$_}++ foreach uniq @$_} @{$_[0]};
  sort{$a <=> $b} grep{$hash{$_} >= 2} keys %hash
}

printf "(%s)\n", join ',' => two_out_of_three([[1,1,2,4],[2,4],[4]]);
printf "(%s)\n", join ',' => two_out_of_three([[4,1],[2,4],[1,2]]);