diff options
| author | Mohammad S Anwar <mohammad.anwar@yahoo.com> | 2020-01-05 23:54:52 +0000 |
|---|---|---|
| committer | Mohammad S Anwar <mohammad.anwar@yahoo.com> | 2020-01-05 23:54:52 +0000 |
| commit | f8f71f733a6dfc1b564b101eb6bd74ebd71ec8f8 (patch) | |
| tree | 5fcc6532c7a24bf9f436ff583c479e2bcdc25f6a /challenge-041 | |
| parent | ca8bb6ed0261838bbc9440bdd3a97bf5576a23c7 (diff) | |
| download | perlweeklychallenge-club-f8f71f733a6dfc1b564b101eb6bd74ebd71ec8f8.tar.gz perlweeklychallenge-club-f8f71f733a6dfc1b564b101eb6bd74ebd71ec8f8.tar.bz2 perlweeklychallenge-club-f8f71f733a6dfc1b564b101eb6bd74ebd71ec8f8.zip | |
- Added solutions by Colin Crain.
Diffstat (limited to 'challenge-041')
| -rw-r--r-- | challenge-041/colin-crain/perl5/ch-1.pl | 101 | ||||
| -rw-r--r-- | challenge-041/colin-crain/perl5/ch-2.pl | 58 | ||||
| -rw-r--r-- | challenge-041/colin-crain/perl6/ch-1.p6 | 90 | ||||
| -rw-r--r-- | challenge-041/colin-crain/perl6/ch-2.p6 | 64 |
4 files changed, 313 insertions, 0 deletions
diff --git a/challenge-041/colin-crain/perl5/ch-1.pl b/challenge-041/colin-crain/perl5/ch-1.pl new file mode 100644 index 0000000000..f0589e0335 --- /dev/null +++ b/challenge-041/colin-crain/perl5/ch-1.pl @@ -0,0 +1,101 @@ +#! /opt/local/bin/perl +# +# attractors.pl +# +# PWC 41 +# TASK #1 +# Write a script to display attractive number between 1 and 50. A +# number is an attractive number if the number of its prime factors is +# also prime number. +# +# The number 20 is an attractive number, whose prime factors are 2, 2 +# and 5. The total prime factors is 3 which is also a prime number. +# +# method: first sexy primes, now attractive numbers. So many numbers, +# so many looks. I am a little concerned that all this objectifying +# might give certain less-confident numbers quantity quality issues. +# Let's not forget the truism that "all numbers are interesting"; whether +# amicable, betrothed, deficiant or slightly defective they are all +# Pythagoras' children and all deserve love. . +# +# So anyways, we will pull out our prime decomposition engine from PWC23, +# which we also saw in challenges 29 and 34. +# +# Unable to leave well enough alone, we've tuned and tightened it, +# replacing the origianal prime generating subfunction with a list of +# all primes less or equal to the upper bound, which have been made a +# user defined variable with a default of 50. +# +# We need to know the prime decomposition, but only briefly enough to +# sum it and compare this to our prime list. As we have the prime list +# already present in the function we could do the comparison then and +# there, return true or false, grep the list of calling it from 1 to +# 50 and call it a day. But merely presenting the numbers without +# demonstrating their attractiveness seemed a bit off the mark, like +# talking about a fashion show on the radio instead of going to a +# fashion show to see the runway. So a table is produced of all the +# numbers, their decompositions, and finally judgement on their +# attractiveness. It appears the group of numbers between 1 and 50, +# taken as a whole are a pretty good-looking bunch. +# + +# +# +# + +# 2020 colin crain +## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## + + + +use warnings; +use strict; +use feature ":5.26"; + +## ## ## ## ## MAIN + +my $max = shift @ARGV // 50; + +my @primes = make_prime_list($max); +my %primehash = map { $_ => 1 } @primes; + +for (2..$max) { + my @decomp = decompose($_, \@primes); + printf "%-4d--> %-20s %s\n", $_, (join ', ', @decomp), + (exists $primehash{(scalar @decomp)}) ? "$_ is attractive" : "" ; +} + +## ## ## ## ## SUBS + +sub make_prime_list { +## creates a list of all primes less than or equal to a given number + my $max = shift; + my @output = (2); + CANDIDATE: for( my $candidate = 3; $candidate <= $max; $candidate += 2 ) { + my $sqrt_candidate = sqrt( $candidate ); + for( my $test = 3; $test <= $sqrt_candidate; $test += 2 ) { + next CANDIDATE if $candidate % $test == 0; + } + push @output, $candidate; + } + return @output; +} + +sub decompose { +## given a number and a list of primes less than n/2, +## returns an array list of prime decomposition factors of the number + my ($num, $primes) = @_; + my @decomp; + my @primelist = $primes->@*; + my $prime = shift @primelist; + + while ( $prime <= $num ) { + while ($num % $prime == 0) { + $num = $num / $prime; + push @decomp, $prime; + } + last if scalar @primelist == 0; + $prime = shift @primelist; + } + return @decomp; +} diff --git a/challenge-041/colin-crain/perl5/ch-2.pl b/challenge-041/colin-crain/perl5/ch-2.pl new file mode 100644 index 0000000000..9fa8b9ebe9 --- /dev/null +++ b/challenge-041/colin-crain/perl5/ch-2.pl @@ -0,0 +1,58 @@ +#! /opt/local/bin/perl +# +# leonardo_numbers.pl +# +# PWC41 +# TASK #2 +# Write a script to display first 20 Leonardo Numbers. Please checkout wiki page for more information. +# For example: +# +# L(0) = 1 +# L(1) = 1 +# L(2) = L(0) + L(1) + 1 = 3 +# L(3) = L(1) + L(2) + 1 = 5 +# and so on. +# +# method: because we have the growing series directly available to +# refer to no recursion is required. I have made the function +# return a list for any quantity > 0, displayed with a nice little +# header. +# +# As-is can handle up to L(90) +# L(90) = 5,760,134,388,741,632,239 +# +# 2020 colin crain +## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## + + + +use warnings; +use strict; +use feature ":5.26"; + +## ## ## ## ## MAIN + +my $quan = shift @ARGV // 20; + +say "the first $quan Leonardo numbers:"; +say ""; +say "index | number"; +say "-------+--------"; + +my $i; +printf "%-2d %d\n", ++$i, $_ for make_leonardo($quan)->@*; + + +## ## ## ## ## SUBS + +sub make_leonardo { +## construct a list of the first n Leonardo numbers +## requires no recursion if we have the growing list to refer to + my $quan = shift; + my $list = [1]; + push $list->@*, 1 if $quan > 1; ## now [1,1] + while ( scalar $list->@* <= $quan-1 ) { + push $list->@*, $list->[-1] + $list->[-2] + 1; ## sum last two elements + 1 + } + return $list; +} diff --git a/challenge-041/colin-crain/perl6/ch-1.p6 b/challenge-041/colin-crain/perl6/ch-1.p6 new file mode 100644 index 0000000000..8c94ac8865 --- /dev/null +++ b/challenge-041/colin-crain/perl6/ch-1.p6 @@ -0,0 +1,90 @@ +use v6; + +# PWC 41 +# TASK #1 +# Write a script to display attractive number between 1 and 50. A +# number is an attractive number if the number of its prime factors is +# also prime number. +# +# The number 20 is an attractive number, whose prime factors are 2, 2 +# and 5. The total prime factors is 3 which is also a prime number. +# +# notice: first sexy primes, now attractive numbers. So many numbers, +# so many looks. I am a little concerned that all this objectifying +# might give certain less-confident numbers quantity quality issues. +# Let's not forget the truism that "all numbers are interesting"; whether +# amicable, betrothed, deficiant or slightly defective they are all +# Pythagorus' children and deserve love. +# +# So anyways, we will pull out our prime decomposition engine from PWC23, +# which we also saw in challenges 29 and 34. +# +# Unable to leave well enough alone, we've tuned and tightened it, +# replacing the origianal prime generating subfunction with a list of +# all primes less or equal to the upper bound, which have been made a +# user defined variable with a default of 50, and a lower bound of 2, +# the smallest prime number. +# +# We need to know the prime decomposition, but only briefly enough to +# sum it and compare this to our prime list. As we have the prime list +# already present in the function we could do the comparison then and +# there, return true or false, grep the list of calling it from 1 to +# 50 and call it a day. But merely presenting the numbers without +# demonstrating their attractiveness seemed a bit off the mark, like +# talking about a fashion show on the radio instead of going to a +# fashion show to see the runway. So a table is produced of all the +# numbers, their decompositions, and finally judgement on their +# attractiveness. It appears the group of numbers between 1 and 50, +# taken as a whole are a pretty good-looking bunch. +# +# +# +# 2020 colin crain +## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## + +sub MAIN ( Int:D $max where {$max > 2} = 50 ) { + + my @primes = make_prime_list($max); + my $primeset = Set.new(@primes); + + for (2..$max) { + my @decomp = decompose($_, @primes); + printf "%-5d --> %-20s %s\n", $_, (@decomp.join: ', '), (@decomp.elems ∈ $primeset) ?? "$_ is attractive" !! ""; + } +} + + +## ## ## ## ## SUBS + +sub make_prime_list ( Int:D $max where {$max > 2} = 50 ) { +## creates a list of all primes less than or equal to a given number + my @output = [2]; + CANDIDATE: loop ( my $candidate = 3; $candidate <= $max; $candidate += 2 ) { + my $sqrt_candidate = $candidate.sqrt; + loop ( my $test = 3; $test <= $sqrt_candidate; $test += 2 ) { + next CANDIDATE if $candidate % $test == 0; + } + @output.push: $candidate; + } + return @output; +} + + +sub decompose ( $extnum, @primes) { +## given a number and a list of primes less than n/2, +## returns an array list of prime decomposition factors of the number + my @decomp; + my $num = $extnum; + my @primelist = @primes; + my $prime = shift @primelist; + + while ( $prime <= $num ) { + while ($num %% $prime) { + $num /= $prime; + @decomp.push: $prime; + } + last unless @primelist.elems; + $prime = @primelist.shift; + } + return @decomp; +} diff --git a/challenge-041/colin-crain/perl6/ch-2.p6 b/challenge-041/colin-crain/perl6/ch-2.p6 new file mode 100644 index 0000000000..24d7125c74 --- /dev/null +++ b/challenge-041/colin-crain/perl6/ch-2.p6 @@ -0,0 +1,64 @@ +use v6; + +# +# leonardo_numbers.p6 +# +# PWC41 +# TASK #2 +# Write a script to display first 20 Leonardo Numbers. Please checkout wiki page for more information. +# For example: +# +# L(0) = 1 +# L(1) = 1 +# L(2) = L(0) + L(1) + 1 = 3 +# L(3) = L(1) + L(2) + 1 = 5 +# and so on. +# +# method: because we have the growing series directly available to refer +# to no recursion is required. I have made the function return a list +# for any quanity > 0, displayed with a nice little header. + +# In the list-generating function, the definition of the sequence +# lends itself well to a given/when construction, but after making it +# I realized the fall-through logic was so straightforward the outer +# construct could be done away with completely. All cases just fall +# through to the return at the end. + +# The heavy lifting on the Leonardo list is done in one line by adding +# elements made by the reduce sum of the flattened two element tail +# and 1. Nice. +# +# The function doesn't have meaning for quantity values < 1, so a constraint is +# added that the parameter given must be an Int greater than 0. +# +# 2020 colin crain +## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## + + +sub MAIN ( Int:D $quan where {$quan > 0} = 20) { + + ## header + say "the first $quan Leonardo numbers:"; + say ""; + say "index | number"; + say "-------+--------"; + + ## data + my $i; + printf "%-2d %d\n", ++$i, $_ for make_leonardo($quan); +} + + + +## ## ## ## ## SUBS + +sub make_leonardo ( Int:D $quan where {$quan > 0} ){ +## construct a list of the first n Leonardo numbers +## requires no recursion if we have the growing list to refer to + my @list = [1]; ## L1 = 1 + @list.push: 1 if $quan > 1 ; ## L2 = 1 + while ( @list.elems <= $quan-1 ) { + @list.push: [+] flat @list.tail(2), 1; ## reduce sum flattened list of last two elems and 1 + } + return @list; +} |
