This is my response to The Weekly Challenge #276.
@hours
.
Input: @hours = (12, 12, 30, 24, 24)
Output: 2
Pair 1: (12, 12)
Pair 2: (24, 24)
Example 2:
Input: @hours = (72, 48, 24, 5)
Output: 3
Pair 1: (72, 48)
Pair 2: (72, 24)
Pair 3: (48, 24)
Example 3:
Input: @hours = (12, 18, 24)
Output: 0
File: complete-day
#! /usr/bin/env raku
unit sub MAIN (*@hours where all(@hours) ~~ UInt && @hours.elems > 1, # [1]
:v(:$verbose));
my $pairs = 0; # [2]
for @hours.combinations(2) -> ($first, $second) # [3]
{
next if $first == $second == 0; # [4]
if ($first + $second) %% 24 # [5]
{
$pairs++; # [5a]
say ": Pair $pairs: ($first, $second)" if $verbose;
}
}
say $pairs; # [6]
[1] Ensure that all the hour values are unsigned integers (the UInt
type), i.e. not negative, and that we have at least two of them.
[2] The result will end up here.
[3] Iterate over all the combinations
of two
values from the input. We put the two values in their own variables instead
of an array, just for fun.
See docs.raku.org/routine/comabinations for more information about comabinations
.
[4] Skip the current combination if both values are zero, as
0 %% 24 -> True
and that will screw up the check in [5].
[5] Add the two values and check if the result is divisible (%%
) by
24. Increase the counter if it is [5a].
See docs.raku.org/routine/%%
for more information about the Divisibility Operator %%
.
[6] Print the result.
Running it:
$ ./complete-day 12 12 30 24 24
2
$ ./complete-day 72 48 24 5
3
$ ./complete-day 12 18 24
0
Looking good.
With verbose mode:
$ ./complete-day -v 12 12 30 24 24
: Pair 1: (12, 12)
: Pair 2: (24, 24)
2
$ ./complete-day -v 72 48 24 5
: Pair 1: (72, 48)
: Pair 2: (72, 24)
: Pair 3: (48, 24)
3
$ ./complete-day -v 12 18 24
0
Zeroes are fine:
$ ./complete-day -v 0 0 12 24
: Pair 1: (0, 24)
: Pair 2: (0, 24)
2
$ ./complete-day -v 0 0 12
0
@ints
.
Input: @ints = (1, 2, 2, 4, 1, 5)
Ouput: 4
The maximum frequency is 2.
The elements 1 and 2 has the maximum frequency.
Example 2:
Input: @ints = (1, 2, 3, 4, 5)
Ouput: 5
The maximum frequency is 1.
The elements 1, 2, 3, 4 and 5 has the maximum frequency.
#! /usr/bin/env raku
unit sub MAIN (*@ints where all(@ints) ~~ Int
&& all(@ints) > 0
&& @ints.elems > 0, # [1]
:v(:$verbose));
my $bag = @ints.Bag; # [2]
my $max-freq = $bag.values.max; # [3]
say ": The maximum frequency is $max-freq" if $verbose;
say $bag.grep( *.value == $max-freq ) * $max-freq; # [4]
[1] Ensure at least one element, all of which are positive integers.
[2] Turn the input inta a Bag
, a hash like structure
that counts the frequency of each distinct value.
See docs.raku.org/routine/Bag for more information about Bag
.
[3] Then we apply values
to get the frequencies (of the distinct
values), and max
to get the highest one.
[4] Use grep
to get the highest frequencies (as there may be more
than one). The result is still a Bag, which is then coerced to its length
when we use it in numeric context. Then we multiply this with the highest
value (the frequency of each one) to get the result - which we print.
Running it:
$ ./maximum-frequency 1 2 2 4 1 5
4
$ ./maximum-frequency 1 2 3 4 5
5
Looking good.
With verbose mode:
$ ./maximum-frequency -v 1 2 2 4 1 5
: The maximum frequency is 2
4
$ ./maximum-frequency -v 1 2 3 4 5
: The maximum frequency is 1
5
And that's it.