diff options
| author | Mohammad Sajid Anwar <Mohammad.Anwar@yahoo.com> | 2024-01-02 11:16:47 +0000 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-01-02 11:16:47 +0000 |
| commit | ca2a93e05c838ef0bdd86b01c8def081c1586088 (patch) | |
| tree | 14d6e1c70a442e2aa696e9a0b8764526f91111ea | |
| parent | d406d35523e9972dc948f8bc7e7d802b56ed2714 (diff) | |
| parent | 139908fe65d29944783accaa97e86d13a2e81515 (diff) | |
| download | perlweeklychallenge-club-ca2a93e05c838ef0bdd86b01c8def081c1586088.tar.gz perlweeklychallenge-club-ca2a93e05c838ef0bdd86b01c8def081c1586088.tar.bz2 perlweeklychallenge-club-ca2a93e05c838ef0bdd86b01c8def081c1586088.zip | |
Merge pull request #9335 from ajmetz/new-branch
Challenge 249 - Committing andrew_mehta folder containing README, a Pā¦
| -rw-r--r-- | challenge-249/andrew_mehta/README | 1 | ||||
| -rwxr-xr-x | challenge-249/andrew_mehta/perl/Ch_1.pm | 500 | ||||
| -rw-r--r-- | challenge-249/andrew_mehta/perl/lib/CodeBoilerplate.pm | 44 | ||||
| -rw-r--r-- | challenge-249/andrew_mehta/perl/lib/TestBoilerplate.pm | 42 | ||||
| -rwxr-xr-x | challenge-249/andrew_mehta/perl/t2/Ch_1.t | 312 |
5 files changed, 899 insertions, 0 deletions
diff --git a/challenge-249/andrew_mehta/README b/challenge-249/andrew_mehta/README new file mode 100644 index 0000000000..45287ff20d --- /dev/null +++ b/challenge-249/andrew_mehta/README @@ -0,0 +1 @@ +Solution by Andrew Mehta.
\ No newline at end of file diff --git a/challenge-249/andrew_mehta/perl/Ch_1.pm b/challenge-249/andrew_mehta/perl/Ch_1.pm new file mode 100755 index 0000000000..193e77dbad --- /dev/null +++ b/challenge-249/andrew_mehta/perl/Ch_1.pm @@ -0,0 +1,500 @@ +use Object::Pad 0.807; +use strict; +use warnings; + +package EqualPairs v1.0.0; +class EqualPairs { + + use File::Basename; + use lib dirname(__FILE__)."/lib"; + use CodeBoilerplate; + use Data::Dumper qw(Dumper); # Used in input validation check warnings. + use Pod::Text::Color; + +=pod Name, Synopsis, Description + +=encoding utf8 + +=head1 NAME + +EqualPairs - Additional Class / Package within Ch_1.pm file. + +=cut + +=head1 SYNOPSIS + + my @input = (3, 2, 3, 2, 2, 2); + my $answer_to_task_1 = EqualPairs->new->input(@input)->pretty_output; + +=cut + +=head1 DESCRIPTION + +For the construction of new EqualPairs object instances, +used in providing the answer +to the Perl Weekly Challenge 249 +Task 1 (set 25th December 2023). + +Package omits... + + 1; + +...at the end, as this is not needed +with feature bundles v5.37 or higher, +as documented at +L<https://perldoc.perl.org/functions/require>. + +=cut + +=head1 METHODS + +=over + +=item new(input => $array_reference); + + # With default empty input: + my $equal_pairs_object = EqualPairs->new; + + # With input provided as array reference: + my $array_reference = [3, 2, 3, 2, 2, 2]; + my $equal_pairs_object = EqualPairs->new(input => $array_reference); + +Constructs and returns a new object instance. +Optionally, the constructor +can set the input object attribute. + +=cut + + field $input :param = []; + +=item output; + + my @empty_array = EqualPairs->new->output; + my @array_of_array_references = EqualPairs->new->input(3, 2, 3, 2, 2, 2)->output; + +Returns an array, containing an array reference +for each equal pair found during input processing. + +If no pairs of equal numbers are found, +or no input has been set yet, +will return an empty array. + +=cut + + field @output :reader = (); + + my $new_line = "\n"; + my $line_reference_prefix = 'Reported'; + + method $filter_input { + + # Initial Values: + my $filtered = []; + my $changes = 0; + my $array_reference = $input + && ( + (ref $input) eq 'ARRAY' + ); + + # Filter Out Undef: + push $filtered->@* , map { + if (defined $ARG) { + $ARG; + } + else { + $changes++; + (); + }; + } $input->@* + if $array_reference; + + # Output: + $input = $changes? $filtered: + $input; + return $self; + } + + method $validate_input { + + # Initial Values: + my @errors = (); + my $error_count = 0; + local $SIG{__WARN__} = sub { + push @errors, sprintf('[%s] - %s', ++$error_count, shift); + }; + my $error_text = { + + intro => $new_line.'Please address these errors and try again:'.$new_line, + + pod => 'Printing Plain Old Documentation below '. + 'should it prove helpful...'.$new_line, + + input_false => 'No value found '. + "for object instance's input field / object attribute. ". + $line_reference_prefix, + + expected_array_ref => 'Expected input to be an array reference.'.$new_line. + 'Found ref to return "%s".'.$new_line. + 'When dumped with Data::Dumper, input is as follows:'.$new_line. + '%s'. + $line_reference_prefix, + + empty => 'Input array reference was found to be empty, '. + 'and needs to be populated with digits to proceed. '. + $line_reference_prefix, + + not_even => 'Expected an even number of elements in the list of digits '. + 'and found %s element%s. '. + $line_reference_prefix, + + not_all_integers => 'Expected input array reference to contain only integer digits.'.$new_line. + 'When dumped with Data::Dumper, input is as follows:'.$new_line. + '%s'. + $line_reference_prefix, + + plural => 's', + + singular => q{}, + + exit_reason => 'Exiting due to %s error%s. '. + $line_reference_prefix, + + }; + + + # Regular Expressions: + + my $matches_integer = qr/^\p{Digit}+$/; # Does not allow decimal dots nor Roman Numerals. + + + # Definitions: + + my $array_reference = $input + && ( + (ref $input) eq 'ARRAY' + ); + + my $contains_items = $array_reference + && $input->@*; + + my $even_number_of_items = $contains_items + && !( # Negated + (scalar $input->@*) % 2 + ); + + my $all_integers = $contains_items + && scalar $input->@* == scalar map { + $ARG =~ $matches_integer? $ARG: + (); + } $input->@*; + + + # Checks: + + warn $error_text->{'input_false'} + unless $input; + + warn sprintf($error_text->{'expected_array_ref'}, (ref $input) , Dumper($input),) + unless $array_reference; + + warn $error_text->{'empty'} + unless $contains_items; + + warn sprintf( + + $error_text->{'not_even'}, scalar $input->@*, + + scalar $input->@* == 1? $error_text->{'singular'}: + $error_text->{'plural'}, + + ) + unless $even_number_of_items; + + warn sprintf($error_text->{'not_all_integers'}, Dumper($input),) + unless $all_integers; + + + + # Output: + + if (@errors) { + + say join $new_line, ($error_text->{'intro'}, @errors); + say $error_text->{'pod'}; + + Pod::Text::Color->new->parse_from_file(__FILE__); + + die sprintf( + + $error_text->{'exit_reason'}, scalar @errors, + + (scalar @errors == 1)? $error_text->{'singular'}: + $error_text->{'plural'}, + + ); + }; + + return $self; + + } + + method $process_input { + + # Initial Values: + my @equal_pairs = (); + my @sorted_input = sort {$a <=> $b} $input->@*; + my @full_range_of_input = (0..$#sorted_input); + + # Processing: + for (@full_range_of_input) { + + last if ($#sorted_input < 1); + + my ($a, $b) = (shift @sorted_input, shift @sorted_input); + my $equal_pair = $a == $b? [$a, $b]: + undef; + + if ($equal_pair) { + push @equal_pairs , $equal_pair; + } + else { + unshift @sorted_input , $b; + }; + + }; + + # Output: + @output = @equal_pairs; + return $self; + + } + +=item input(@array); + + # Set input via array indirectly: + my @array = (3, 2, 3, 2, 2, 2); + my $equal_pairs_object = EqualPairs->new->input(@array); + + # Set input via array directly: + my $equal_pairs_object = EqualPairs->new->input(3, 2, 3, 2, 2, 2); + +Returns the object instance for method chaining. +Requires that a list of values be provided as input, +and that the list adhere to validation rules, +or the script will be aborted/die. + +To be valid, input must be an even numbered list of integer digits. + +Automatically processes the input, +and sets the L<"output"|/output;> object attribute. + +=cut + + method input (@params) { + $input = @params? \@params: + $input; + return $self->$filter_input->$validate_input->$process_input; + } + +=item pretty_output; + + say EqualPairs->new->input(3, 2, 3, 2, 2, 2)->pretty_output; + +Returns a string that can be displayed. +Uses the values of the object instance's output object attribute +(as can be obtained via the L<"output"|/output;> getter method) +to generate a friendly output message intended for screen display, +that lists the equal pairs the script has found after processing the input, +or states no equal pairs were found. + +=back + +=cut + + method pretty_output { + + # Initial Values: + my $first = 1; + my $text = { + leader => 'Here are your equal pairs:'.$new_line. + 'Output: ', + blank => 'No equal pairs found.', + }; + + # Processing: + my $pretty_output = @output? $text->{'leader'}: + $text->{'blank'}; + + foreach my $pair (@output) { + + $pretty_output .= ',' + unless $first; + $first = undef if $first; + $pretty_output .= '('.$pair->[0].','.$pair->[1].')'; + + } + + # Output: + return $pretty_output; + + } + +=head1 AUTHOR + +Andrew Mehta + +=cut + +} + +package Ch_1 v1.0.0; +class Ch_1 { + use File::Basename; + use lib dirname(__FILE__)."/lib"; + use CodeBoilerplate; + +=pod Name, Version, Synopsis, Description + +=encoding utf8 + +=head1 NAME + +Ch_1 - Perl Weekly Challenge 249 - Task 1 (Set 25th December 2023). + +=head1 VERSION + +v1.0.0 + +=cut + +=head1 SYNOPSIS + + # Run at the command line with input: + perl ./Ch_1.pm 3 2 3 2 2 2 + + # Use Perl Module: + use Ch_1; + my @input = (3, 2, 3, 2, 2, 2); + my $answer_to_task_1 = Ch_1->answer(@input); + my @equal_pairs = Ch_1->answer_data(@input); + +=head1 DESCRIPTION + +Contains L<"answer"|/answer(@array);> +and L<"answer_data"|/answer_data(@array);> methods +to the Perl Weekly Challenge 249 Task 1 +(set 25th December 2023). +When executed (ran from the command line), +the L<"answer"|/answer(@array);> method is ran, +and its return value output to C<STDOUT>. + +Alternatively, the script can be used as a Perl Module, +and the L<"answer"|/answer(@array);> +and L<"answer_data"|/answer_data(@array);> methods +invoked directly, returning a string for output +and an array of array references for data manipulation, +respectively. + +Package omits... + + 1; + +...at the end, as this is not needed +with feature bundles v5.37 or higher, +as documented at +L<https://perldoc.perl.org/functions/require>. + +=cut + +=head1 CLASS METHODS + +=over + +=item answer(@array); + + use Ch_1; + my @input = (3, 2, 3, 2, 2, 2); + my $answer_to_task_1 = Ch_1->answer(@input); + +Outputs the answer to +Perl Weekly Challenge 249 Task 1 +(set 25th December 2023). +Takes a list consisting of an even number of digits as input. +Returns a string containing output messages. + +=back + +=cut + + method answer :common (@input) { + return EqualPairs->new->input(@input)->pretty_output; + } + +=over + +=item answer_data(@array); + + use Ch_1; + my @input = (3, 2, 3, 2, 2, 2); + my @equal_pairs = Ch_1->answer_data(@input); + +Takes a list consisting of an even number of digits as input. + +Returns an array of array references, +where each array reference is a pair of equal integers. +This is the underlaying output data that +is used in the display-friendly L<"answer"|/answer(@array);>. + +If no pairs of equal numbers are found, +will return an empty array. + + +=back + +=cut + + method answer_data :common (@input) { + return EqualPairs->new->input(@input)->output; + } + + say Ch_1->answer(@ARGV) unless caller; # If you omit the class name (Ch_1-> or __PACKAGE__->), + # @input will be missing the first @ARGV value + # - presumably shifted off to $self by Object::Pad. + +=head1 AUTHOR + +Andrew Mehta + +=cut + +} + +__END__ + +Task 1: Equal Pairs +Submitted by: Mohammad S Anwar + +You are given an array of integers with even number of elements. + +Write a script to divide the given array into equal pairs such that: + +a) Each element belongs to exactly one pair. +b) The elements present in a pair are equal. + +================= + +Example 1 + +Input: @ints = (3, 2, 3, 2, 2, 2) +Output: (2, 2), (3, 3), (2, 2) + +There are 6 elements in @ints. +They should be divided into 6 / 2 = 3 pairs. +@ints is divided into the pairs (2, 2), (3, 3), and (2, 2) satisfying all the conditions. + +Example 2 + +Input: @ints = (1, 2, 3, 4) +Output: () + +There is no way to divide @ints 2 pairs such that the pairs satisfy every condition. diff --git a/challenge-249/andrew_mehta/perl/lib/CodeBoilerplate.pm b/challenge-249/andrew_mehta/perl/lib/CodeBoilerplate.pm new file mode 100644 index 0000000000..8f1e8cc6d6 --- /dev/null +++ b/challenge-249/andrew_mehta/perl/lib/CodeBoilerplate.pm @@ -0,0 +1,44 @@ +package CodeBoilerplate; + +use strict; +use warnings; +use utf8; + +my $feature_bundle; +my $version_number_to_use; + +BEGIN { + $version_number_to_use = '5.38'; + $feature_bundle = ':'.$version_number_to_use; +}; + +use feature "$feature_bundle"; + +use Import::Into; +use English; + +our $VERSION = 'v2.0.0'; + +sub import { + + # Initial Variables: + my $calling_module_level_depth = 1; + + # Processing / Declaring what to import: + $ARG ->import for qw(strict warnings utf8); + feature ->import ($feature_bundle); + English ->import::into ($calling_module_level_depth); + + #UTF-8 the default on standard input and output: + binmode STDIN, ":encoding(UTF-8)"; + binmode STDOUT, ":encoding(UTF-8)"; + binmode STDERR, ":encoding(UTF-8)"; + +} + +# Protect subclasses using AUTOLOAD +sub DESTROY { } + +1; + +__END__
\ No newline at end of file diff --git a/challenge-249/andrew_mehta/perl/lib/TestBoilerplate.pm b/challenge-249/andrew_mehta/perl/lib/TestBoilerplate.pm new file mode 100644 index 0000000000..d45c1d8cc8 --- /dev/null +++ b/challenge-249/andrew_mehta/perl/lib/TestBoilerplate.pm @@ -0,0 +1,42 @@ +package TestBoilerplate; + +use CodeBoilerplate; +use Import::Into; +use Test::Output; +use Test2::V0; +use Test2::Tools::Compare; +use Test2::Tools::Exception; + +our $VERSION = 'v2.0.0'; + +sub import { + + # Initial Variables: + my $calling_module_level_depth = 1; + my @compare_imports = qw{ + is like isnt unlike + match mismatch validator + hash array bag object meta number float rounded within string subset bool + in_set not_in_set check_set + item field call call_list call_hash prop check all_items all_keys all_vals all_values + etc end filter_items + T F D DF E DNE FDNE U L + event fail_events + exact_ref + }; + + # Processing / Declaring what to import: + CodeBoilerplate ->import::into ($calling_module_level_depth); + Test::Output ->import::into ($calling_module_level_depth); + Test2::V0 ->import::into ($calling_module_level_depth); + Test2::Tools::Compare ->import::into ($calling_module_level_depth, @compare_imports); + Test2::Tools::Exception ->import::into ($calling_module_level_depth); + +} + +# Protect subclasses using AUTOLOAD +sub DESTROY { } + +1; + +__END__ diff --git a/challenge-249/andrew_mehta/perl/t2/Ch_1.t b/challenge-249/andrew_mehta/perl/t2/Ch_1.t new file mode 100755 index 0000000000..e4b7235133 --- /dev/null +++ b/challenge-249/andrew_mehta/perl/t2/Ch_1.t @@ -0,0 +1,312 @@ + +# Custom Libraries: +use Path::Tiny; +use lib path(__FILE__)->parent->parent->realpath->stringify; +use lib path(__FILE__)->parent->sibling('lib')->realpath->stringify; + +# Standard Test Boilerplate: +use TestBoilerplate; + +# Specific Modules used: +use Ch_1; + +=pod Name, Version, Synopsis, Description + +=encoding utf8 + +=head1 NAME + +Ch_1.t Test File. + +=head1 VERSION + +v1.0.0 + +=cut + +our $VERSION = 'v1.0.0'; + +=head1 SYNOPSIS + + yath -v # Will automatically run tests found in the ./t2 folder ( such as this test ), in verbose mode. + +=head1 DESCRIPTION + +This unit test, tests the C<Ch_1.pm> Perl modulino, +originally made for the Perl Weekly Challenge 249 +Task 1 (set 25th December 2023). + +It tests for the C<Ch_1> class +and that class' C<answer> and C<answer_data> methods; +then tests the output of these methods, +given a variety of input test data +and output expectations. + +For each piece of provided test data, +this unit test +checks for errors, +and if the script dies or lives; +and then checks for output, +and if output is as expected. +Finally it checks that +the challenge rules have been met: + +=over + +=item 1 + +Each element belongs to exactly one pair. + +=item 2 + +The elements present in a pair are equal. + +=back + +Both Input Data and Output Expectations +are set in a single array +within the source code +of this unit test script. + +=cut + +# Initial Values: +my $text = { + prefix => '[Test Case %04d] - %s - %s.', + result_prefix => "Here are your equal pairs:\nOutput: ", + no_pairs_result => 'No equal pairs found', + true => 'Output is true', + 'dies' => 'Programme died', + delivers_result => 'Programme delivered result and did not die', + error => 'Error(s) found', + no_error => 'No Error(s) found', + address_errors => 'address these errors', + expected => 'Contained expected output - "%s"', + class => 'Class Name As Expected', + methods => 'Expected Methods Present', + two => 'Pair %d consists of two values: (%d,%d)', + frequency => 'Each input element of "%d" that became paired (%d out of %d) belongs to exactly one pair', + equal => 'Pair %d elements are equal: (%d,%d)', +}; +my $error = { + uneven => '[1] - Expected an even number of elements', + non_integer => '[1] - Expected input array reference to contain only integer digits', + empty => '[1] - Input array reference was found to be empty', + die_message => 'Exiting due to', +}; +my $value_delimiter = ", "; +my $matches_die_message = qr/\Q$error->{'die_message'}/; +my $matches_error = qr/\Q$text->{'address_errors'}/; +my $matches_result = qr/( + \Q$text->{'result_prefix'}\E + | + \Q$text->{'no_pairs_result'}\E + )/x; +my $test_name = sub { sprintf($text->{prefix}, @ARG) }; +my $test_count = 1; +my $expected_class = 'Ch_1'; +my @expected_methods = qw(answer answer_data); + +# Test Data: +my @test_data = ( + # Test Name # Input: #Expected Output + 'Odd Number of Elements' => [qw(1 2 3)] => $error->{'uneven'}, + 'Letter Elements' => [qw(a a a b b b)] => $error->{'non_integer'}, + 'Digits and Letters' => [qw(1 a 1 b 1 b)] => $error->{'non_integer'}, + 'Words' => [qw(cat sat mat different)] => $error->{'non_integer'}, + 'No Equal Integer Pairs' => [qw(1 2 3 4)] => $text->{'no_pairs_result'}, + 'No Elements' => [qw()] => $error->{'empty'}, + 'One Large Digit' => [qw(999999999)] => $error->{'uneven'}, + 'Lots Of Large Digits 1' => [qw( + 112 16648 19999 + 9999999 9999999 + 112 88888888888 + 88888888888 112 + 19999 + )] => 'Output: (112,112),(19999,19999),(9999999,9999999),(88888888888,88888888888)', + 'Lots Of Large Digits 2' => [qw( + 112 16648 19999 + 9999999 9999999 + 112 88888888888 + 88888888888 112 + 19999 233333556 + )] => $error->{'uneven'}, + 'End Odd List With Undef' => [qw( + 112 16648 19999 + 9999999 9999999 + 112 88888888888 + 88888888888 112 + 19999 + ),undef] => 'Output: (112,112),(19999,19999),(9999999,9999999),(88888888888,88888888888)', + 'End Even List With Undef' => [qw( + 112 16648 19999 + 9999999 9999999 + 112 88888888888 + 88888888888 112 + 19999 233333556 + ),undef] => $error->{'uneven'}, + 'Odd List With '. + 'Undef In Middle' => [qw( + 112 16648 19999 + 9999999 9999999 + 112), undef, qw( + 88888888888 + 88888888888 112 + 19999 + )] => 'Output: (112,112),(19999,19999),(9999999,9999999),(88888888888,88888888888)', + 'Even List '. + 'With Undef In Middle' => [qw( + 112 16648 19999 + 9999999 9999999 + 112), undef, qw( + 88888888888 + 88888888888 112 + 19999 233333556 + )] => $error->{'uneven'}, + 'Four Byte Unicode 1' => [qw(š š)] => $error->{'non_integer'}, + 'Four Byte Unicode 2' => [qw(š 1)] => $error->{'non_integer'}, + 'Four Byte Unicode 3' => [qw(š š 1 1)] => $error->{'non_integer'}, + 'Odd List With '. + 'All Elements Undef' => [undef,undef,undef] => $error->{'empty'}, + 'Even List With '. + 'All Elements Undef' => [undef,undef,undef,undef] => $error->{'empty'}, + 'Single Digits Test 1' => [qw( 1 2 3 4 4 4 5 6 )] => 'Output: (4,4)', + 'Single Digits Test 2' => [qw( 1 2 3 4 4 4 5 6 5 6 )] => 'Output: (4,4),(5,5),(6,6)', + 'Non-single Digits Test 1' => [qw( + 01 02 33 44 44 44 + 5555 66 5555 66 01 01 + )] => 'Output: (01,01),(44,44),(66,66),(5555,5555)', + 'Many Similar Numbers 1' => [qw( + 1 1 1 1 1 1 1 1 + 23 23 23 23 23 + 2023 2023 2023 + 400000 400000 + 400000 400000 + 400000 400000 + 9999999999999 + 9999999999999 + )] => 'Output: (1,1),(1,1),(1,1),(1,1),'. + '(23,23),(23,23),(2023,2023),'. + '(400000,400000),(400000,400000),(400000,400000),'. + '(9999999999999,9999999999999)', + 'Nonsense' => [qw( gfhdsjsahsgshhjsh )] => $text->{'address_errors'}, +); + +# Test Processing: + +isa_ok( + Ch_1 => [$expected_class], + $test_name->($test_count++, $text->{'class'}, $expected_class) +); + +can_ok( + Ch_1 => [@expected_methods], + $test_name->($test_count++, $text->{'methods'}, join($value_delimiter, @expected_methods)) +); + +# Test Data Processing: + +for my ($name, $input, $expected_string) (@test_data) { + + my $matches_expected = qr/\Q$expected_string/; + my $output = combined_from( + sub { + my $successful_output = undef; + warn $successful_output + if + lives { $successful_output = Ch_1->answer($input->@*) } + && defined $successful_output; + } + ); + my $delivers_result = 0; + + if ($EVAL_ERROR) { + like( + $output => $matches_error, + $test_name->($test_count++, $name, $text->{'error'}) + ); + + like( + $EVAL_ERROR => $matches_die_message, + $test_name->($test_count++, $name, $text->{'dies'}) + ); + } + else { + unlike( + $output => $matches_error, #unlike + $test_name->($test_count++, $name, $text->{'no_error'}) #unlike + ); + $delivers_result = + like( + $output => $matches_result, + $test_name->($test_count++, $name, $text->{'delivers_result'}) + ); + }; + + is( + $output => T(), + $test_name->($test_count++, $name, $text->{'true'}) + ); + + like( + $output => $matches_expected, + $test_name->($test_count++, $name, sprintf($text->{'expected'}, $expected_string)) + ); + + # Test Challenge Rules: + if ($delivers_result) { + + # Initial Values: + my @output_data = Ch_1->answer_data($input->@*); + + if (@output_data) { + + # Initial Values: + my %input_frequency = (); + my %output_frequency = (); + my @flattened_output_data = (); + push @flattened_output_data , $ARG->@* for @output_data; + my $pair_count = 1; + + # Process Frequencies: + $input_frequency{$ARG}++ for map {defined $ARG? $ARG:()} $input->@*; + $output_frequency{$ARG}++ for map {defined $ARG? $ARG:()} @flattened_output_data; + + # Test Processing: + + # a) Each element belongs to exactly one pair. + for my $input_item (sort {$a <=> $b} keys %input_frequency) { + exists $output_frequency{$input_item} + && ok( + $output_frequency{$input_item} <= $input_frequency{$input_item} <= $output_frequency{$input_item} + 1, + $test_name->($test_count++, $name, sprintf($text->{'frequency'}, $input_item, $output_frequency{$input_item}, $input_frequency{$input_item})), + ); + }; + + # b) The elements present in a pair are equal. + for my $pair (@output_data) { + is( + scalar $pair->@* => 2, + $test_name->($test_count++, $name, sprintf($text->{'two'}, $pair_count, $pair->@*)), + ) + && is( + $pair->[0] => $pair->[1], + $test_name->($test_count++, $name, sprintf($text->{'equal'}, $pair_count++, $pair->@*)), + ); + }; + + }; + + }; + +} + +done_testing(); + +=head1 AUTHOR + +Andrew Mehta + +=cut + +__END__ |
