aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--challenge-172/bob-lied/perl/ch-1.pl45
-rw-r--r--challenge-172/bob-lied/perl/ch-2.pl72
2 files changed, 103 insertions, 14 deletions
diff --git a/challenge-172/bob-lied/perl/ch-1.pl b/challenge-172/bob-lied/perl/ch-1.pl
index ae612614de..1d3ba6d645 100644
--- a/challenge-172/bob-lied/perl/ch-1.pl
+++ b/challenge-172/bob-lied/perl/ch-1.pl
@@ -8,6 +8,14 @@
# You are given two positive integers, $m and $n.
# Write a script to find out the Prime Partition of the given number.
# No duplicates allowed.
+# Example 1 Input: $m = 18, $n = 2
+# Output: 5, 13 or 7, 11
+# Example 2 Input: $m = 19, $n = 3
+# Output: 3, 5, 11
+#####
+# A prime partition is a set of primes that sums to the target number.
+# There is a function in Math::Prime::Util that does this.
+#=============================================================================
# https://en.wikipedia.org/wiki/Partition_(number_theory)
# Example 1: Input: $m = 18, $n = 2
# Output: 5, 13 or 7, 11
@@ -18,8 +26,6 @@
use v5.38;
use builtin qw/true false/; no warnings "experimental::builtin";
-use Math::Prime::Util qw/forpart partitions/;
-
use Getopt::Long;
my $Verbose = 0;
my $DoTest = 0;
@@ -27,21 +33,48 @@ my $DoTest = 0;
GetOptions("test" => \$DoTest, "verbose" => \$Verbose);
exit(!runTest()) if $DoTest;
+my $M = shift;
+my $N = shift;
+
+die "Usage: $0 m n" unless $M && $N;
+die "n must be <= m/2" unless $N <= $M/2;
+my $answer = primePartition($M, $N);
+if ( $Verbose )
+{
+ say join(" or ", map { join(", ", $_->@*) } $answer->@*);
+}
+else
+{
+ say "$_->@*" for $answer->@*;
+}
+
+sub noDup(@list)
+{
+ use List::Util qw/uniqint/;
+ return scalar(uniqint(@list)) == scalar(@list);
+}
+
sub primePartition($m, $n)
{
+ use Math::Prime::Util qw/forpart/;
my @part;
- forpart { push @part, [ @_ ] } $m, { n => $n, prime => 1 };
+ forpart { push @part, [ @_ ] if noDup(@_) } $m, { n => $n, prime => 1} ;
- return @part;
+ return \@part;
}
sub runTest
{
use Test2::V0;
+ use builtin qw/true false/; no warnings "experimental::builtin";
+
+ is( noDup(1,2,3,4), true, "noDup true");
+ is( noDup(1,1,3,4), false, "noDup false begin");
+ is( noDup(1,2,2,4), false, "noDup false middle");
+ is( noDup(1,2,4,4), false, "noDup false end");
- is( primePartition(19, 3), [ [3,5,11] ], "Example 2");
is( primePartition(18, 2), [ [5,13], [7,11] ], "Example 1");
+ is( primePartition(19, 3), [ [3,5,11] ], "Example 2");
done_testing;
}
-
diff --git a/challenge-172/bob-lied/perl/ch-2.pl b/challenge-172/bob-lied/perl/ch-2.pl
index 10542c894e..ff9f7ac26c 100644
--- a/challenge-172/bob-lied/perl/ch-2.pl
+++ b/challenge-172/bob-lied/perl/ch-2.pl
@@ -7,9 +7,6 @@
#=============================================================================
# You are given an array of integers.
# Write a script to compute the five-number summary of the given set
-# of integers. You can find the definition and example in the wikipedia page.
-# https://en.wikipedia.org/wiki/Five-number_summary
-#
# The five-number summary is a set of descriptive statistics that provides
# information about a dataset. It consists of the five most important
# sample percentiles:
@@ -18,13 +15,12 @@
# the median (the middle value)
# the upper quartile or third quartile
# the sample maximum (largest observation)
-#
# Example 1: Input: @int = (0, 0, 1, 2, 63, 61, 27, 13)
# Output: 0.00 0.75 7.50 20.88 35.50 63.00
#=============================================================================
use v5.38;
-use builtin qw/true false/; no warnings "experimental::builtin";
+use builtin qw/floor ceil/; no warnings "experimental::builtin";
use Getopt::Long;
my $Verbose = 0;
@@ -33,16 +29,76 @@ my $DoTest = 0;
GetOptions("test" => \$DoTest, "verbose" => \$Verbose);
exit(!runTest()) if $DoTest;
-sub fiveNumSum(@int)
+show(fiveSummary(@ARGV));
+
+sub show($five)
+{
+ if ( $Verbose )
+ {
+ printf " minimum: %12.3f\n", $five->[0];
+ printf "1st quartile: %12.3f\n", $five->[1];
+ printf " median: %12.3f\n", $five->[2];
+ printf "3nd quartile: %12.3f\n", $five->[3];
+ printf " maximum: %12.3f\n", $five->[4];
+ }
+ else
+ {
+ say "(", join(", ", $five->@*), ")";
+ }
+}
+
+sub median($ref)
+{
+ my $len = scalar( @$ref );
+ if ( $len % 2 )
+ {
+ # Odd length, take middle element
+ return $ref->[ int($len/2) ];
+ }
+ else
+ {
+ # Even length, take average of middle 2
+ my $mid = $len / 2;
+ return ( $ref->[$mid] + $ref->[$mid-1] ) / 2;
+ }
+}
+
+sub fiveSummary(@list)
{
+ my @sorted = sort { $a <=> $b } @list;
+ my $len = scalar( @list );
+ my $mid = $len / 2;
+ my ($lowtop, $hibottom);
+ if ( $len % 2 )
+ {
+ # Odd
+ $lowtop = $hibottom = floor($mid);
+ }
+ else
+ {
+ # Even
+ $lowtop = ($hibottom = $mid) - 1;
+ }
+
+ my @summary = (
+ $sorted[0],
+ median( [ @sorted[0 .. $lowtop ] ]),
+ median( \@sorted ),
+ median( [ @sorted[ $hibottom .. $#list] ]),
+ $sorted[-1]
+ );
+ return \@summary;
}
sub runTest
{
use Test2::V0;
- is(0, 1, "FAIL");
+ is( median([3,5,7]), 5, "Median odd length");
+ is( median([3,5,7,9]), 6, "Median even length");
+
+ is( fiveSummary(0, 0, 1, 2, 63, 61, 27, 13),
+ [0.0, 0.5, 7.5, 44.0, 63.0 ], "Example 1");
done_testing;
}
-