#+title: Challenge 187
#+date: 2022-10-27
#+html_link_up: ../
#+export_file_name: index
#+options: toc:nil
#+setupfile: ~/.emacs.d/org-templates/level-2.org
* Task 1 - Days Together
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.
#+begin_src
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
#+end_src
** Raku
We convert the date to an integer representing number of days since the
start of the year. Then simply subtract the minimum of end days with
maximum of start days. The goal is to find the common days.
#+begin_src raku
sub MAIN() {
my @schedules = %( foo => <12-01 20-01>, bar => <15-01 18-01> ),
%( foo => <02-03 12-03>, bar => <13-03 14-03> ),
%( foo => <02-03 12-03>, bar => <11-03 15-03> ),
%( foo => <30-03 05-04>, bar => <28-03 02-04> );
for @schedules -> %schedule {
put days-together(%schedule) ~ " day(s)";
}
}
#| date-to-int takes a date in "DD-MM" form and converts it to an
#| integer.
sub date-to-int(Str $date --> Int) {
my @days-in-month = 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31;
given $date.split("-").map(*.Int) {
return $_[0] + ([+] @days-in-month[^ ($_[1] - 1)])
}
}
#| days-together returns the days foo & bar are together.
sub days-together(%schedule --> Int) {
my $foo-start = date-to-int %schedule[0];
my $foo-end = date-to-int %schedule[1];
my $bar-start = date-to-int %schedule[0];
my $bar-end = date-to-int %schedule[1];
return min($foo-end, $bar-end) - max($foo-start, $bar-start) + 1;
}
#+end_src
* Task 2 - Mask Code
You are given a list of codes in many random format.
Write a script to mask first four characters (a-z,0-9) and keep the rest
as it is.
#+begin_src
Example 1
Input: @list = ('ab-cde-123', '123.abc.420', '3abc-0010.xy')
Output: ('xx-xxe-123', 'xxx.xbc.420', 'xxxx-0010.xy')
Example 2
Input: @list = ('1234567.a', 'a-1234-bc', 'a.b.c.d.e.f')
Output: ('xxxx567.a', 'x-xxx4-bc', 'x.x.x.x.e.f')
#+end_src
** Raku
Takes an array of codes as input. Loops over characters of a code and
prints every character except first four matching the regex "\w".
#+begin_src raku
unit sub MAIN(*@codes);
for @codes -> $code {
my Int $count;
for $code.comb {
given $_ {
when /\w/ { print ($count++ < 4 ?? "x" !! $_) }
default { .print }
}
}
put "";
}
#+end_src