diff options
| author | PerlMonk Athanasius <PerlMonk.Athanasius@gmail.com> | 2019-09-01 06:05:39 -0700 |
|---|---|---|
| committer | PerlMonk Athanasius <PerlMonk.Athanasius@gmail.com> | 2019-09-01 06:05:39 -0700 |
| commit | d9d64e3c722af57eee60f5cc8279eeff0b0be4bb (patch) | |
| tree | dcf96f4a9e24519090c6a717a522bb57d9c114f2 /challenge-023/athanasius/perl6 | |
| parent | 887c6713ef9e5c4abe75edae665fa674b3948860 (diff) | |
| download | perlweeklychallenge-club-d9d64e3c722af57eee60f5cc8279eeff0b0be4bb.tar.gz perlweeklychallenge-club-d9d64e3c722af57eee60f5cc8279eeff0b0be4bb.tar.bz2 perlweeklychallenge-club-d9d64e3c722af57eee60f5cc8279eeff0b0be4bb.zip | |
Perl 5 & 6 solutions to Tasks #1 & #2, and Perl 5 solution to Task #3.
On branch branch-for-challenge-023
Changes to be committed:
new file: challenge-023/athanasius/perl5/ch-1.pl
new file: challenge-023/athanasius/perl5/ch-2.pl
new file: challenge-023/athanasius/perl5/ch-3.pl
new file: challenge-023/athanasius/perl6/ch-1.p6
new file: challenge-023/athanasius/perl6/ch-2.p6
Diffstat (limited to 'challenge-023/athanasius/perl6')
| -rw-r--r-- | challenge-023/athanasius/perl6/ch-1.p6 | 98 | ||||
| -rw-r--r-- | challenge-023/athanasius/perl6/ch-2.p6 | 92 |
2 files changed, 190 insertions, 0 deletions
diff --git a/challenge-023/athanasius/perl6/ch-1.p6 b/challenge-023/athanasius/perl6/ch-1.p6 new file mode 100644 index 0000000000..bec5457e96 --- /dev/null +++ b/challenge-023/athanasius/perl6/ch-1.p6 @@ -0,0 +1,98 @@ +use v6; + +################################################################################ +=begin comment + +Perl Weekly Challenge 023 +========================= + +Task #1 +------- +Create a script that prints nth order forward difference series. You should be a +able to pass the list of numbers and order number as command line parameters. +Let me show you with an example. + + Suppose we have list (X) of numbers: 5, 9, 2, 8, 1, 6 and we would like to + create 1st order forward difference series (Y). So using the formula Y(i) = + X(i+1) - X(i), we get the following numbers: (9-5), (2-9), (8-2), (1-8), + (6-1). In short, the final series would be: 4, -7, 6, -7, 5. If you noticed, + it has one less number than the original series. Similary you can carry on 2nd + order forward difference series like: (-7-4), (6+7), (-7-6), (5+7) => -11, 13, + -13, 12. + +=end comment +################################################################################ + +#--------------------------------------# +# Copyright © 2019 PerlMonk Athanasius # +#--------------------------------------# + +my UInt:D constant $ORDER = 1; + +BEGIN say ''; + +#=============================================================================== +sub MAIN(*@series, UInt:D :$order = $ORDER) +#=============================================================================== +{ + check-arguments(@series, $order); + + for 1 .. $order + { + my UInt $max-index = @series.elems - 1; + + my @new-series; + @new-series.push(@series[$_] - @series[$_ - 1]) for 1 .. $max-index; + + @series = @new-series; + } + + "%s order forward difference series:\n(%s)\n".printf: + ordinal($order), join(', ', @series); + + CATCH + { + default + { + $*ERR.say: .message ~ "\n" ~ $*USAGE; + } + } +} + +#------------------------------------------------------------------------------- +sub check-arguments(@series, UInt:D $order) +#------------------------------------------------------------------------------- +{ + my UInt $elements = @series.elems; + + $elements > 1 + or die "Invalid number of elements ($elements) in the series: must " ~ + "be at least 2"; + + $order > 0 + or die "Invalid order ($order): must be an integer > 0"; + + $order < $elements + or die "Invalid order ($order): a series of $elements elements " ~ + "cannot have an order > { $elements - 1 }"; +} + +#------------------------------------------------------------------------------- +sub ordinal(UInt:D $cardinal) +#------------------------------------------------------------------------------- +{ + my $suffix = 'th'; + my $digit_0 = $cardinal % 10; + my $digit_1 = ($cardinal / 10).floor % 10; + + if ($digit_1 != 1) + { + $suffix = $digit_0 == 1 ?? 'st' !! + $digit_0 == 2 ?? 'nd' !! + $digit_0 == 3 ?? 'rd' !! 'th'; + } + + return $cardinal ~ $suffix; +} + +################################################################################ diff --git a/challenge-023/athanasius/perl6/ch-2.p6 b/challenge-023/athanasius/perl6/ch-2.p6 new file mode 100644 index 0000000000..24048e5626 --- /dev/null +++ b/challenge-023/athanasius/perl6/ch-2.p6 @@ -0,0 +1,92 @@ +use v6; + +################################################################################ +=begin comment + +Perl Weekly Challenge 023 +========================= + +Task #2 +------- +Create a script that prints *Prime Decomposition* of a given number. The prime +decomposition of a number is defined as a list of prime numbers which when all +multiplied together, are equal to that number. For example, the Prime decomposi- +tion of 228 is 2,2,3,19 as 228 = 2 * 2 * 3 * 19. + +=end comment +################################################################################ + +#--------------------------------------# +# Copyright © 2019 PerlMonk Athanasius # +#--------------------------------------# + +BEGIN say ''; + +#=============================================================================== +sub MAIN(UInt:D $number ) #= Unsigned integer > 1 +#=============================================================================== +{ + die $*USAGE if $number <= 1; + + say "The prime decomposition of $number is: ", factor($number).join(', '); + + CATCH + { + default + { + $*ERR.say: .message; + } + } +} + +#------------------------------------------------------------------------------- +sub factor(UInt:D $number) +#------------------------------------------------------------------------------- +{ + my UInt $remainder = $number; + my @factors; + + MY-OUTER: + for 2 .. $number -> UInt $f + { + if $f.is-prime + { + while $remainder % $f == 0 + { + @factors.push: $f; + $remainder div= $f; + + last MY-OUTER if $remainder == 1; + } + } + } + + die "ERROR: for number $number, remainder is $remainder" + unless $remainder == 1; + + return @factors; +} + +################################################################################ + +=begin note + +The label used in sub factor() was originally "OUTER:". Here is the explanation +of the (cryptic!) error message that resulted: + +From https://perl6.eu/colonoscopy.html + +"Upper Case letters are normally used for labels, but this will cause an error +if you happen to choose a name that is already in use internally by Perl 6. The +label itself isn't a problem, as the trailing colon tells the compiler that it +is a label. The usage, where it is used as a bareword causes the problem, and +there is no way to fix it. + +Some examples: + +OUTER, which seems perfectly logical as a label name, will give the run time +error («Cannot resolve caller next(OUTER:U); ...»), as OUTER is a built-in +package name and Perl 6 isn't clever enough to spot that it is used as a label +in this case." + +=end note |
