From 10f2f6c16c737eeefdbe5943594d55754e6a7976 Mon Sep 17 00:00:00 2001 From: Bob Lied Date: Tue, 10 Oct 2023 20:40:36 -0500 Subject: Task 1 done --- challenge-172/bob-lied/perl/ch-1.pl | 59 +++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 challenge-172/bob-lied/perl/ch-1.pl diff --git a/challenge-172/bob-lied/perl/ch-1.pl b/challenge-172/bob-lied/perl/ch-1.pl new file mode 100644 index 0000000000..4085bc6dd2 --- /dev/null +++ b/challenge-172/bob-lied/perl/ch-1.pl @@ -0,0 +1,59 @@ +#!/usr/bin/env perl +# vim:set ts=4 sw=4 sts=4 et ai wm=0 nu: +#============================================================================= +# ch-1.pl Perl Weekly Challenge 172 Task 1 Prime Partition +#============================================================================= +# Copyright (c) 2023, Bob Lied +#============================================================================= +# 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. +#============================================================================= + +use v5.38; +use Math::Prime::Util qw/forpart/; +use List::Util qw/uniqint/; + +use Getopt::Long; +my $Verbose = 0; +my $DoTest = 0; + +GetOptions("test" => \$DoTest, "verbose" => \$Verbose); +exit(!runTest()) if $DoTest; + +sub noDup(@list) +{ + return scalar(uniqint(@list)) == scalar(@list); +} + +sub primePartition($m, $n) +{ + use Data::Dumper; + my @part; + forpart { push @part, [ @_ ] if noDup(@_) } $m, { n => $n, prime => 1} ; + + 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(18, 2), [ [5,13], [7,11] ], "Example 1"); + is( primePartition(19, 3), [ [3,5,11] ], "Example 2"); + + done_testing; +} -- cgit From 2cffde4d041fad2d6c977f81d0d0d633dec21467 Mon Sep 17 00:00:00 2001 From: Bob Lied Date: Tue, 10 Oct 2023 21:06:31 -0500 Subject: Task 2 checkpoint --- challenge-172/bob-lied/perl/ch-2.pl | 70 +++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 challenge-172/bob-lied/perl/ch-2.pl diff --git a/challenge-172/bob-lied/perl/ch-2.pl b/challenge-172/bob-lied/perl/ch-2.pl new file mode 100644 index 0000000000..49b526e9e8 --- /dev/null +++ b/challenge-172/bob-lied/perl/ch-2.pl @@ -0,0 +1,70 @@ +#!/usr/bin/env perl +# vim:set ts=4 sw=4 sts=4 et ai wm=0 nu: +#============================================================================= +# ch-2.pl Perl Weekly Challenge 172 Task 2 Five-number Summary +#============================================================================= +# Copyright (c) 2023, Bob Lied +#============================================================================= +# 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: +# the sample minimum (smallest observation) +# the lower quartile or first quartile +# the median (the middle value) +# the upper quartile or third quartile +# the sample maximum (largest observation) +#============================================================================= + +use v5.38; +use builtin qw/true false/; no warnings "experimental::builtin"; + + +use Getopt::Long; +my $Verbose = 0; +my $DoTest = 0; + +GetOptions("test" => \$DoTest, "verbose" => \$Verbose); +exit(!runTest()) if $DoTest; + +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 @summary = ( + $sorted[0], + 0, + median(\@sorted), + 1, + $sorted[-1] + ); +} + +sub runTest +{ + use Test2::V0; + + is( fiveSummary(0, 0, 1, 2, 63, 61, 27, 13), + [0.0, 0.5, 7.5, 44.0, 63.0 ], "Example 1"); + + done_testing; +} -- cgit From f5cf1052b7b9df42c9de547165c93a7eec3b708d Mon Sep 17 00:00:00 2001 From: Bob Lied Date: Tue, 10 Oct 2023 21:08:48 -0500 Subject: Update README --- challenge-172/bob-lied/README | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/challenge-172/bob-lied/README b/challenge-172/bob-lied/README index c231e3a589..fe223977ff 100644 --- a/challenge-172/bob-lied/README +++ b/challenge-172/bob-lied/README @@ -1,3 +1,3 @@ -Solutions to weekly challenge 138 by Bob Lied +Solutions to weekly challenge 172 by Bob Lied -https://perlweeklychallenge.org/blog/perl-weekly-challenge-138/ +https://perlweeklychallenge.org/blog/perl-weekly-challenge-172/ -- cgit From dffd2da5d8674935ab48cbe4054aca53cc09ef84 Mon Sep 17 00:00:00 2001 From: Bob Lied Date: Sun, 26 Nov 2023 08:40:22 -0600 Subject: Week 172 solutions --- challenge-172/bob-lied/perl/ch-1.pl | 20 +++++++++++++--- challenge-172/bob-lied/perl/ch-2.pl | 46 ++++++++++++++++++++++++++++++++----- 2 files changed, 57 insertions(+), 9 deletions(-) diff --git a/challenge-172/bob-lied/perl/ch-1.pl b/challenge-172/bob-lied/perl/ch-1.pl index 4085bc6dd2..da6a73c1c8 100644 --- a/challenge-172/bob-lied/perl/ch-1.pl +++ b/challenge-172/bob-lied/perl/ch-1.pl @@ -18,8 +18,6 @@ #============================================================================= use v5.38; -use Math::Prime::Util qw/forpart/; -use List::Util qw/uniqint/; use Getopt::Long; my $Verbose = 0; @@ -28,14 +26,30 @@ 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 Data::Dumper; + use Math::Prime::Util qw/forpart/; my @part; forpart { push @part, [ @_ ] if noDup(@_) } $m, { n => $n, prime => 1} ; diff --git a/challenge-172/bob-lied/perl/ch-2.pl b/challenge-172/bob-lied/perl/ch-2.pl index 49b526e9e8..d73be53695 100644 --- a/challenge-172/bob-lied/perl/ch-2.pl +++ b/challenge-172/bob-lied/perl/ch-2.pl @@ -20,8 +20,7 @@ #============================================================================= 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; @@ -30,6 +29,24 @@ my $DoTest = 0; GetOptions("test" => \$DoTest, "verbose" => \$Verbose); exit(!runTest()) if $DoTest; +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 ); @@ -42,7 +59,7 @@ sub median($ref) { # Even length, take average of middle 2 my $mid = $len / 2; - return ( $ref->[$mid] + $ref->[$mid+1] ) / 2; + return ( $ref->[$mid] + $ref->[$mid-1] ) / 2; } } @@ -50,19 +67,36 @@ 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], - 0, - median(\@sorted), - 1, + median( [ @sorted[0 .. $lowtop ] ]), + median( \@sorted ), + median( [ @sorted[ $hibottom .. $#list] ]), $sorted[-1] ); + return \@summary; } sub runTest { use Test2::V0; + 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"); -- cgit