aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--challenge-276/athanasius/perl/ch-1.pl360
-rw-r--r--challenge-276/athanasius/perl/ch-2.pl209
-rw-r--r--challenge-276/athanasius/raku/ch-1.raku301
-rw-r--r--challenge-276/athanasius/raku/ch-2.raku179
4 files changed, 1049 insertions, 0 deletions
diff --git a/challenge-276/athanasius/perl/ch-1.pl b/challenge-276/athanasius/perl/ch-1.pl
new file mode 100644
index 0000000000..584d64fbd5
--- /dev/null
+++ b/challenge-276/athanasius/perl/ch-1.pl
@@ -0,0 +1,360 @@
+#!perl
+
+################################################################################
+=comment
+
+Perl Weekly Challenge 276
+=========================
+
+TASK #1
+-------
+*Complete Day*
+
+Submitted by: Mohammad Sajid Anwar
+
+You are given an array of integers, @hours.
+
+Write a script to return the number of pairs that forms a complete day.
+
+ A complete day is defined as a time duration that is an exact multiple of
+ 24 hours.
+
+Example 1
+
+ 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
+
+=cut
+################################################################################
+
+#--------------------------------------#
+# Copyright © 2024 PerlMonk Athanasius #
+#--------------------------------------#
+
+#===============================================================================
+=comment
+
+Assumptions
+-----------
+1. Hours are unsigned integers; negative hours are excluded.
+2. The pair (0, 0) is accepted as a "complete day" because it meets the
+ definition: "a time duration that is an exact multiple of 24 hours."
+
+Interface
+---------
+1. If no command-line arguments are given, the test suite is run. Otherwise:
+2. If an explanation of the output is required, the flag "--verbose" is entered
+ on the command-line.
+3. The input hours are entered as a non-empty list of unsigned integers at the
+ tail of the command-line.
+
+=cut
+#===============================================================================
+
+use v5.32.1; # Enables strictures
+use warnings;
+use Const::Fast;
+use Getopt::Long;
+use List::Util qw( uniqint );
+use Regexp::Common qw( number );
+use Test::More;
+
+const my $DAY => 24;
+const my $HALF_DAY => int( $DAY / 2 );
+const my $USAGE => <<END;
+Usage:
+ perl $0 [--verbose] [<hours> ...]
+ perl $0
+
+ --verbose Explain the output? [default: False]
+ [<hours> ...] A non-empty list of unsigned integers
+END
+
+#-------------------------------------------------------------------------------
+BEGIN
+#-------------------------------------------------------------------------------
+{
+ $| = 1;
+ print "\nChallenge 276, Task #1: Complete Day (Perl)\n\n";
+}
+
+#-------------------------------------------------------------------------------
+package DayPair
+#-------------------------------------------------------------------------------
+{
+ use Moo;
+ use Types::Common::Numeric qw( PositiveOrZeroInt );
+ use namespace::clean;
+
+ #- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+ has lhs =>
+ #- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+ (
+ is => 'ro',
+ isa => PositiveOrZeroInt
+ );
+
+ #- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+ has rhs =>
+ #- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+ (
+ is => 'ro',
+ isa => PositiveOrZeroInt
+ );
+
+ #- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+ sub BUILD # Sanity check
+ #- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+ {
+ my ($self) = @_;
+
+ ($self->{ lhs } + $self->{ rhs }) % $DAY == 0 or die 'Invalid DayPair';
+ }
+}
+
+#===============================================================================
+MAIN:
+#===============================================================================
+{
+ if (scalar @ARGV == 0)
+ {
+ run_tests();
+ }
+ else
+ {
+ my ($verbose, $hours) = parse_command_line();
+
+ printf "Input: \@hours = (%s)\n", join ', ', @$hours;
+
+ my $pairs = find_day_pairs( $hours );
+ my $count = scalar @$pairs;
+
+ print "Output: $count\n";
+
+ if ($verbose && $count > 0)
+ {
+ print "\n";
+
+ my $n = 1;
+
+ printf( "Pair %d: (%d, %d)\n", $n++, $_->lhs, $_->rhs ) for @$pairs;
+ }
+ }
+}
+
+#-------------------------------------------------------------------------------
+sub find_day_pairs
+#-------------------------------------------------------------------------------
+{
+ my ($hours) = @_;
+ my @pairs;
+ my @sorted_hours;
+
+ for my $hour (@$hours)
+ {
+ my $mod = $hour % $DAY;
+
+ push $sorted_hours[ $mod ]->@*, $hour;
+ }
+
+ push @pairs, pair_identical_mods( $sorted_hours[ 0 ] ); # Mod 0
+ push @pairs, pair_identical_mods( $sorted_hours[ $HALF_DAY ] ); # Mod 12
+
+ for my $i (1 .. $DAY - 1)
+ {
+ next if $i == $HALF_DAY;
+
+ if ($sorted_hours[ $i ])
+ {
+ $sorted_hours[ $i ] =
+ [ sort { $a <=> $b } uniqint $sorted_hours[ $i ]->@* ];
+ }
+ }
+
+ push @pairs, pair_complementary_mods( \@sorted_hours );
+
+ @pairs = sort { $b->lhs <=> $a->lhs || $b->rhs <=> $a->rhs } @pairs;
+
+ return \@pairs;
+}
+
+#-------------------------------------------------------------------------------
+sub pair_identical_mods
+#-------------------------------------------------------------------------------
+{
+ my ($hours_ref) = @_;
+ my @pairs;
+
+ if (defined $hours_ref && scalar @$hours_ref >= 2)
+ {
+ my @hours = sort { $b <=> $a } @$hours_ref;
+ my $last_left;
+
+ for my $i (0 .. $#hours - 1)
+ {
+ my $left = $hours[ $i ];
+
+ next if defined $last_left && $last_left == $left;
+
+ my $last_right;
+
+ for my $j ($i + 1 .. $#hours)
+ {
+ my $right = $hours[ $j ];
+
+ next if defined $last_right && $last_right == $right;
+
+ push @pairs, DayPair->new( lhs => $left, rhs => $right );
+
+ $last_right = $right;
+ }
+
+ $last_left = $left;
+ }
+ }
+
+ return @pairs;
+}
+
+#-------------------------------------------------------------------------------
+sub pair_complementary_mods
+#-------------------------------------------------------------------------------
+{
+ my ($sorted_hours) = @_;
+ my @pairs;
+
+ for my $i (1 .. $HALF_DAY - 1)
+ {
+ for my $left ($sorted_hours->[ $i ]->@*)
+ {
+ my $j = $DAY - $i;
+
+ for my $right ($sorted_hours->[ $j ]->@*)
+ {
+ my ($lhs, $rhs) = ($left > $right) ? ($left, $right)
+ : ($right, $left);
+
+ push @pairs, DayPair->new( lhs => $lhs, rhs => $rhs );
+ }
+ }
+ }
+
+ return @pairs;
+}
+
+#-------------------------------------------------------------------------------
+sub parse_command_line
+#-------------------------------------------------------------------------------
+{
+ my $verbose = 0;
+
+ GetOptions
+ (
+ verbose => \$verbose
+ ) or error( 'Error in command line arguments' );
+
+ my @hours = @ARGV;
+
+ scalar @hours > 0 or error( 'Missing command-line input' );
+
+ for (@hours)
+ {
+ / ^ $RE{num}{int} $ /x or error( qq["$_" is not a valid integer] );
+ $_ >= 0 or error( qq["$_" is negative] );
+ }
+
+ return ($verbose, \@hours);
+}
+
+#-------------------------------------------------------------------------------
+sub run_tests
+#-------------------------------------------------------------------------------
+{
+ print "Running the test suite\n";
+
+ while (my $line = <DATA>)
+ {
+ chomp $line;
+
+ while ($line =~ / \\ $ /x)
+ {
+ $line =~ s/ \\ $ / /x;
+
+ my $next = <DATA>;
+
+ $next =~ s/ ^ \s+ //x;
+ $line .= $next;
+ }
+
+ my ($test_name, $hours_str, $expected_str) = split / \| /x, $line;
+
+ for ($test_name, $hours_str, $expected_str)
+ {
+ s/ ^ \s+ //x;
+ s/ \s+ $ //x;
+ }
+
+ my @hours = split / \s+ /x, $hours_str;
+ my $pairs = find_day_pairs( \@hours );
+ my $expected = get_expected( $expected_str );
+
+ is_deeply $pairs, $expected, $test_name;
+ }
+
+ done_testing;
+}
+
+#-------------------------------------------------------------------------------
+sub get_expected
+#-------------------------------------------------------------------------------
+{
+ my ($expected_str) = @_;
+ my @expected;
+
+ for my $pair_str (split / ; \s* /x, $expected_str)
+ {
+ my ($left, $right) = split / \s+ /x, $pair_str;
+
+ push @expected, DayPair->new( lhs => $left, rhs => $right );
+ }
+
+ return \@expected;
+}
+
+#-------------------------------------------------------------------------------
+sub error
+#-------------------------------------------------------------------------------
+{
+ my ($message) = @_;
+
+ die "ERROR: $message\n$USAGE";
+}
+
+################################################################################
+
+__DATA__
+Example 1|12 12 30 24 24 |24 24; 12 12
+Example 2|72 48 24 5 |72 48; 72 24; 48 24
+Example 3|12 18 24 |
+1-off | 1 23 25 47 49 71 23 23 |71 49; 71 25; 71 1; 49 47; 49 23; 47 25; \
+ 47 1; 25 23; 23 1
+7-off | 7 17 17 31 65 |65 31; 65 7; 31 17; 17 7
+Combined |65 1 31 23 17 25 7 47 71|71 25; 71 1; 65 31; 65 7; 47 25; 47 1; \
+ 31 17; 25 23; 23 1; 17 7
diff --git a/challenge-276/athanasius/perl/ch-2.pl b/challenge-276/athanasius/perl/ch-2.pl
new file mode 100644
index 0000000000..503271fcf5
--- /dev/null
+++ b/challenge-276/athanasius/perl/ch-2.pl
@@ -0,0 +1,209 @@
+#!perl
+
+################################################################################
+=comment
+
+Perl Weekly Challenge 276
+=========================
+
+TASK #2
+-------
+*Maximum Frequency*
+
+Submitted by: Mohammad Sajid Anwar
+
+You are given an array of positive integers, @ints.
+
+Write a script to return the total number of elements in the given array which
+have the highest frequency.
+
+Example 1
+
+ Input: @ints = (1, 2, 2, 4, 1, 5)
+ Output: 4
+
+ The maximum frequency is 2.
+ The elements 1 and 2 has the maximum frequency.
+
+Example 2
+
+ Input: @ints = (1, 2, 3, 4, 5)
+ Output: 5
+
+ The maximum frequency is 1.
+ The elements 1, 2, 3, 4 and 5 has the maximum frequency.
+
+=cut
+################################################################################
+
+#--------------------------------------#
+# Copyright © 2024 PerlMonk Athanasius #
+#--------------------------------------#
+
+#===============================================================================
+=comment
+
+Assumption
+----------
+"Positive integers" are greater than zero.
+
+Interface
+---------
+1. If no command-line arguments are given, the test suite is run. Otherwise:
+2. If an explanation of the output is required, the flag "--verbose" is entered
+ on the command-line.
+3. The input integers are entered as a non-empty list at the end of the command-
+ line.
+
+=cut
+#===============================================================================
+
+use v5.32.1; # Enables strictures
+use warnings;
+use Const::Fast;
+use Getopt::Long;
+use List::Util qw( max );
+use Regexp::Common qw( number );
+use Test::More;
+
+const my $USAGE => <<END;
+Usage:
+ perl $0 [--verbose] [<ints> ...]
+ perl $0
+
+ --verbose Explain the output? [default: False]
+ [<ints> ...] A list of positive integers
+END
+
+#-------------------------------------------------------------------------------
+BEGIN
+#-------------------------------------------------------------------------------
+{
+ $| = 1;
+ print "\nChallenge 276, Task #2: Maximum Frequency (Perl)\n\n";
+}
+
+#===============================================================================
+MAIN:
+#===============================================================================
+{
+ if (scalar @ARGV == 0)
+ {
+ run_tests();
+ }
+ else
+ {
+ my ($verbose, $ints) = parse_command_line();
+
+ printf "Input: \@ints = (%s)\n", join ', ', @$ints;
+
+ my $max = max_freq( $ints );
+
+ printf "Output: %d\n", $max->{ count };
+
+ if ($verbose)
+ {
+ printf "\nMaximum frequency: %d\n", $max->{ freq };
+
+ printf "Element%s with the maximum frequency: %s\n",
+ scalar $max->{ elems }->@* == 1 ? '' : 's',
+ join ', ', $max->{ elems }->@*;
+ }
+ }
+}
+
+#-------------------------------------------------------------------------------
+sub max_freq
+#-------------------------------------------------------------------------------
+{
+ my ($ints) = @_;
+ my %freq;
+ ++$freq{ $_ } for @$ints;
+
+ my %max = (freq => max( values %freq ), count => 0);
+ my %elem;
+
+ for (@$ints)
+ {
+ if ($freq{ $_ } == $max{ freq })
+ {
+ ++$elem{ $_ };
+ ++$max{ count };
+ }
+ }
+
+ $max{ elems } = [ sort { $a <=> $b } keys %elem ];
+
+ return \%max;
+}
+
+#-------------------------------------------------------------------------------
+sub parse_command_line
+#-------------------------------------------------------------------------------
+{
+ my $verbose = 0;
+
+ GetOptions
+ (
+ verbose => \$verbose
+ ) or error( 'Invalid command-line argument' );
+
+ my @ints = @ARGV;
+
+ scalar @ints > 0 or error( 'Missing command-line input' );
+
+ for (@ints)
+ {
+ / ^ $RE{num}{int} $ /x or error( qq["$_" is not a valid integer] );
+ $_ > 0 or error( qq["$_" is not positive] );
+ }
+
+ return ($verbose, \@ints);
+}
+
+#-------------------------------------------------------------------------------
+sub run_tests
+#-------------------------------------------------------------------------------
+{
+ print "Running the test suite\n";
+
+ while (my $line = <DATA>)
+ {
+ chomp $line;
+
+ my ($test_name, $ints, $exp_max_freq, $elems, $exp_count) =
+ split / \| /x, $line;
+
+ for ($test_name, $ints, $exp_max_freq, $elems, $exp_count)
+ {
+ s/ ^ \s+ //x;
+ s/ \s+ $ //x;
+ }
+
+ my @ints = split / \s+ /x, $ints;
+ my @exp_elems = split / \s+ /x, $elems;
+ my $max = max_freq( \@ints );
+
+ is $max->{ freq }, $exp_max_freq, $test_name;
+ is_deeply $max->{ elems }, \@exp_elems, $test_name;
+ is $max->{ count }, $exp_count, $test_name;
+ }
+
+ done_testing;
+}
+
+#-------------------------------------------------------------------------------
+sub error
+#-------------------------------------------------------------------------------
+{
+ my ($message) = @_;
+
+ die "ERROR: $message\n$USAGE";
+}
+
+################################################################################
+
+__DATA__
+Example 1 |1 2 2 4 1 5|2|1 2 |4
+Example 2 |1 2 3 4 5 |1|1 2 3 4 5|5
+Single elem|7 3 7 5 7 9|3|7 |3
diff --git a/challenge-276/athanasius/raku/ch-1.raku b/challenge-276/athanasius/raku/ch-1.raku
new file mode 100644
index 0000000000..cf5c3e4b47
--- /dev/null
+++ b/challenge-276/athanasius/raku/ch-1.raku
@@ -0,0 +1,301 @@
+use v6d;
+
+################################################################################
+=begin comment
+
+Perl Weekly Challenge 276
+=========================
+
+TASK #1
+-------
+*Complete Day*
+
+Submitted by: Mohammad Sajid Anwar
+
+You are given an array of integers, @hours.
+
+Write a script to return the number of pairs that forms a complete day.
+
+ A complete day is defined as a time duration that is an exact multiple of
+ 24 hours.
+
+Example 1
+
+ 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
+
+=end comment
+################################################################################
+
+#--------------------------------------#
+# Copyright © 2024 PerlMonk Athanasius #
+#--------------------------------------#
+
+#===============================================================================
+=begin comment
+
+Assumptions
+-----------
+1. Hours are unsigned integers; negative hours are excluded.
+2. The pair (0, 0) is accepted as a "complete day" because it meets the
+ definition: "a time duration that is an exact multiple of 24 hours."
+
+Interface
+---------
+1. If no command-line arguments are given, the test suite is run. Otherwise:
+2. If an explanation of the output is required, the flag "--verbose" is entered
+ on the command-line.
+3. The input hours are entered as a non-empty list of unsigned integers at the
+ tail of the command-line.
+
+=end comment
+#===============================================================================
+
+use Test;
+
+my UInt constant DAY = 24;
+my UInt constant HALF-DAY = (DAY / 2).floor;
+
+#-------------------------------------------------------------------------------
+BEGIN
+#-------------------------------------------------------------------------------
+{
+ "\nChallenge 276, Task #1: Complete Day (Raku)\n".put;
+}
+
+#-------------------------------------------------------------------------------
+class DayPair
+#-------------------------------------------------------------------------------
+{
+ has UInt $.lhs;
+ has UInt $.rhs;
+
+ #- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+ submethod TWEAK # Sanity check
+ #- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+ {
+ ($!lhs + $!rhs) % DAY == 0 or die 'Invalid DayPair';
+ }
+}
+
+#===============================================================================
+multi sub MAIN
+(
+ #| Explain the output?
+
+ Bool:D :$verbose = False,
+
+ #| A non-empty list of unsigned integers
+
+ *@hours where { .elems > 0 && .all ~~ UInt:D }
+)
+#===============================================================================
+{
+ "Input: \@hours = (%s)\n".printf: @hours.join: ', ';
+
+ my DayPair @pairs = find-day-pairs( @hours );
+ my UInt $count = @pairs.elems;
+
+ "Output: $count".put;
+
+ if $verbose && $count > 0
+ {
+ put();
+ my UInt $n = 1;
+
+ "Pair %d: (%d, %d)\n".printf( $n++, .lhs, .rhs ) for @pairs;
+ }
+}
+
+#===============================================================================
+multi sub MAIN() # No input: run the test suite
+#===============================================================================
+{
+ run-tests();
+}
+
+#-------------------------------------------------------------------------------
+sub find-day-pairs( List:D[UInt:D] $hours --> List:D[DayPair:D] )
+#-------------------------------------------------------------------------------
+{
+ my DayPair @pairs;
+ my Array[UInt] @sorted-hours = Array[UInt].new xx DAY;
+
+ for @$hours -> UInt $hour
+ {
+ my $mod = $hour % DAY;
+
+ @sorted-hours[ $mod ].push: $hour.Int; # Prevent creation of IntStr
+ }
+
+ @pairs.push: |pair-identical-mods( @sorted-hours[ 0 ] ); # Mod 0
+ @pairs.push: |pair-identical-mods( @sorted-hours[ HALF-DAY ] ); # Mod 12
+
+ for 1 .. @sorted-hours.end -> UInt $i
+ {
+ next if $i == HALF-DAY;
+
+ @sorted-hours[ $i ] = Array[UInt].new: @sorted-hours[ $i ].unique.sort;
+ }
+
+ @pairs.push: |pair-complementary-mods( @sorted-hours );
+
+ @pairs .= sort: { $^b.lhs <=> $^a.lhs || $^b.rhs <=> $^a.rhs };
+
+ return @pairs;
+}
+
+#-------------------------------------------------------------------------------
+sub pair-identical-mods( List:D[UInt:D] $hours --> List:D[DayPair:D] )
+#-------------------------------------------------------------------------------
+{
+ my DayPair @pairs;
+
+ if $hours.elems >= 2
+ {
+ my UInt @hours = $hours.sort: { $^b <=> $^a };
+ my UInt $last-lhs;
+
+ for 0 .. @hours.end - 1 -> UInt $i
+ {
+ my UInt $lhs = @hours[ $i ];
+
+ next if $last-lhs.defined && $last-lhs == $lhs;
+
+ my UInt $last-rhs;
+
+ for $i + 1 .. @hours.end -> UInt $j
+ {
+ my UInt $rhs = @hours[ $j ];
+
+ next if $last-rhs.defined && $last-rhs == $rhs;
+
+ @pairs.push: DayPair.new: :$lhs, :$rhs;
+
+ $last-rhs = $rhs;
+ }
+
+ $last-lhs = $lhs;
+ }
+ }
+
+ return @pairs;
+}
+
+#-------------------------------------------------------------------------------
+sub pair-complementary-mods
+(
+ List:D[List:D[UInt:D]] $sorted-hours
+--> List:D[DayPair:D]
+)
+#-------------------------------------------------------------------------------
+{
+ my DayPair @pairs;
+
+ for 1 .. HALF-DAY - 1 -> UInt $i
+ {
+ for |@$sorted-hours[ $i ] -> UInt $left
+ {
+ my UInt $j = DAY - $i;
+
+ for |@$sorted-hours[ $j ] -> UInt $right
+ {
+ my UInt ($lhs, $rhs) = ($left > $right) ?? ($left, $right)
+ !! ($right, $left);
+ @pairs.push: DayPair.new: :$lhs, :$rhs;
+ }
+ }
+ }
+
+ return @pairs;
+}
+
+#-------------------------------------------------------------------------------
+sub run-tests()
+#-------------------------------------------------------------------------------
+{
+ 'Running the test suite'.put;
+
+ for test-data.lines -> Str $line
+ {
+ my Str ($test-name, $hours-str, $expected-str) = $line.split: / \| /;
+
+ for $test-name, $hours-str, $expected-str
+ {
+ s/ ^ \s+ //;
+ s/ \s+ $ //;
+ }
+
+ my UInt @hours = int-split( $hours-str );
+ my DayPair @pairs = find-day-pairs( @hours );
+ my DayPair @expected;
+
+ for $expected-str.split: / \; \s* /, :skip-empty -> Str $pair-str
+ {
+ my UInt ($lhs, $rhs) = int-split( $pair-str );
+
+ @expected.push: DayPair.new: :$lhs, :$rhs;
+ }
+
+ is-deeply @pairs, @expected, $test-name;
+ }
+
+ done-testing;
+}
+
+#-------------------------------------------------------------------------------
+sub int-split( Str:D $str --> Seq:D[Int:D] )
+#-------------------------------------------------------------------------------
+{
+ return $str.split( / \s+ /, :skip-empty ).map: { .Int };
+}
+
+#-------------------------------------------------------------------------------
+sub USAGE()
+#-------------------------------------------------------------------------------
+{
+ my Str $usage = $*USAGE;
+
+ $usage ~~ s:g/ ($*PROGRAM-NAME) /raku $0/;
+
+ $usage.put;
+}
+
+#-------------------------------------------------------------------------------
+sub test-data( --> Str:D )
+#-------------------------------------------------------------------------------
+{
+ my Str $data = q:to/END/;
+ Example 1|12 12 30 24 24 |24 24; 12 12
+ Example 2|72 48 24 5 |72 48; 72 24; 48 24
+ Example 3|12 18 24 |
+ 1-off | 1 23 25 47 49 71 23 23 |71 49; 71 25; 71 1; 49 47; 49 23; \
+ 47 25; 47 1; 25 23; 23 1
+ 7-off | 7 17 17 31 65 |65 31; 65 7; 31 17; 17 7
+ Combined |65 1 31 23 17 25 7 47 71|71 25; 71 1; 65 31; 65 7; 47 25; \
+ 47 1; 31 17; 25 23; 23 1; 17 7
+ END
+
+ $data ~~ s:g/ \\ \n \s* / /; # Concatenate backslashed lines
+
+ return $data;
+}
+
+################################################################################
diff --git a/challenge-276/athanasius/raku/ch-2.raku b/challenge-276/athanasius/raku/ch-2.raku
new file mode 100644
index 0000000000..04cfde2e7c
--- /dev/null
+++ b/challenge-276/athanasius/raku/ch-2.raku
@@ -0,0 +1,179 @@
+use v6d;
+
+################################################################################
+=begin comment
+
+Perl Weekly Challenge 276
+=========================
+
+TASK #2
+-------
+*Maximum Frequency*
+
+Submitted by: Mohammad Sajid Anwar
+
+You are given an array of positive integers, @ints.
+
+Write a script to return the total number of elements in the given array which
+have the highest frequency.
+
+Example 1
+
+ Input: @ints = (1, 2, 2, 4, 1, 5)
+ Output: 4
+
+ The maximum frequency is 2.
+ The elements 1 and 2 has the maximum frequency.
+
+Example 2
+
+ Input: @ints = (1, 2, 3, 4, 5)
+ Output: 5
+
+ The maximum frequency is 1.
+ The elements 1, 2, 3, 4 and 5 has the maximum frequency.
+
+=end comment
+################################################################################
+
+#--------------------------------------#
+# Copyright © 2024 PerlMonk Athanasius #
+#--------------------------------------#
+
+#===============================================================================
+=begin comment
+
+Assumption
+----------
+"Positive integers" are greater than zero.
+
+Interface
+---------
+1. If no command-line arguments are given, the test suite is run. Otherwise:
+2. If an explanation of the output is required, the flag "--verbose" is entered
+ on the command-line.
+3. The input integers are entered as a non-empty list at the end of the command-
+ line.
+
+=end comment
+#===============================================================================
+
+use Test;
+
+subset Pos of Int where * > 0;
+
+#-------------------------------------------------------------------------------
+BEGIN
+#-------------------------------------------------------------------------------
+{
+ "\nChallenge 276, Task #2: Maximum Frequency (Raku)\n".put;
+}
+
+#===============================================================================
+multi sub MAIN
+(
+ Bool:D :$verbose = False, #= Explain the output?
+
+ *@ints where { .elems > 0 && .all ~~ Pos:D } #= A list of positive integers
+)
+#===============================================================================
+{
+ "Input: \@ints = (%s)\n".printf: @ints.join: ', ';
+
+ my %max = max-freq( @ints );
+
+ "Output: %d\n".printf: %max< count >;
+
+ if $verbose
+ {
+ "\nMaximum frequency: %d\n".printf: %max< freq >;
+
+ "Element%s with the maximum frequency: %s\n".printf:
+ %max< elems >.elems == 1 ?? '' !! 's', %max< elems >.join: ', ';
+ }
+}
+
+#===============================================================================
+multi sub MAIN() # No input: run the test suite
+#===============================================================================
+{
+ run-tests();
+}
+
+#-------------------------------------------------------------------------------
+sub max-freq( List:D[Pos:D] $ints --> Hash:D )
+#-------------------------------------------------------------------------------
+{
+ my UInt %freq{Pos};
+ ++%freq{ $_ } for @$ints;
+
+ my %max = freq => %freq<>:v.max, count => 0;
+
+ my UInt %elem{Pos};
+
+ for @$ints
+ {
+ if %freq{ $_ } == %max< freq >
+ {
+ ++%elem{ $_ };
+ ++%max< count >;
+ }
+ }
+
+ %max< elems > = Array[Pos].new: %elem<>:k.sort;
+
+ return %max;
+}
+
+#-------------------------------------------------------------------------------
+sub run-tests()
+#-------------------------------------------------------------------------------
+{
+ 'Running the test suite'.put;
+
+ for test-data.lines -> Str $line
+ {
+ my Str ($test-name, $ints, $exp-max-freq, $elems, $exp-count) =
+ $line.split: / \| /;
+
+ for $test-name, $ints, $exp-max-freq, $elems, $exp-count
+ {
+ s/ ^ \s+ //;
+ s/ \s+ $ //;
+ }
+
+ my Pos @ints = $ints\.split( / \s+ /, :skip-empty ).map: { .Int };
+ my Pos @exp-elems = $elems.split( / \s+ /, :skip-empty ).map: { .Int };
+ my %max = max-freq( @ints );
+
+ is %max< freq >, $exp-max-freq.Int, $test-name;
+ is-deeply %max< elems >, @exp-elems, $test-name;
+ is %max< count >, $exp-count.Int, $test-name;
+ }
+
+ done-testing;
+}
+
+#-------------------------------------------------------------------------------
+sub USAGE()
+#-------------------------------------------------------------------------------
+{
+ my Str $usage = $*USAGE;
+
+ $usage ~~ s:g/ ($*PROGRAM-NAME) /raku $0/;
+
+ $usage.put;
+}
+
+#-------------------------------------------------------------------------------
+sub test-data( --> Str:D )
+#-------------------------------------------------------------------------------
+{
+ return q:to/END/;
+ Example 1 |1 2 2 4 1 5|2|1 2 |4
+ Example 2 |1 2 3 4 5 |1|1 2 3 4 5|5
+ Single elem|7 3 7 5 7 9|3|7 |3
+ END
+}
+
+################################################################################