diff options
| author | PerlMonk Athanasius <PerlMonk.Athanasius@gmail.com> | 2020-06-27 06:14:44 -0700 |
|---|---|---|
| committer | PerlMonk Athanasius <PerlMonk.Athanasius@gmail.com> | 2020-06-27 06:14:44 -0700 |
| commit | 055085ec16b0d03f1e7b8a14b3a88786d564c14b (patch) | |
| tree | 62af3440fc7429f0086498dbd086c58774dded65 /challenge-066/athanasius | |
| parent | b537fb4269e2226e77e7b2faab34f58a16cba9a7 (diff) | |
| download | perlweeklychallenge-club-055085ec16b0d03f1e7b8a14b3a88786d564c14b.tar.gz perlweeklychallenge-club-055085ec16b0d03f1e7b8a14b3a88786d564c14b.tar.bz2 perlweeklychallenge-club-055085ec16b0d03f1e7b8a14b3a88786d564c14b.zip | |
Perl & Raku solutions to Tasks 1 & 2 of the Perl Weekly Challenge #066
On branch branch-for-challenge-066
Changes to be committed:
new file: challenge-066/athanasius/perl/ch-1.pl
new file: challenge-066/athanasius/perl/ch-2.pl
new file: challenge-066/athanasius/raku/ch-1.raku
new file: challenge-066/athanasius/raku/ch-2.raku
Diffstat (limited to 'challenge-066/athanasius')
| -rw-r--r-- | challenge-066/athanasius/perl/ch-1.pl | 87 | ||||
| -rw-r--r-- | challenge-066/athanasius/perl/ch-2.pl | 110 | ||||
| -rw-r--r-- | challenge-066/athanasius/raku/ch-1.raku | 80 | ||||
| -rw-r--r-- | challenge-066/athanasius/raku/ch-2.raku | 107 |
4 files changed, 384 insertions, 0 deletions
diff --git a/challenge-066/athanasius/perl/ch-1.pl b/challenge-066/athanasius/perl/ch-1.pl new file mode 100644 index 0000000000..89cb96dc97 --- /dev/null +++ b/challenge-066/athanasius/perl/ch-1.pl @@ -0,0 +1,87 @@ +#!perl + +################################################################################ +=comment + +Perl Weekly Challenge 066 +========================= + +Task #1 +------- +*Divide Integers* + +*Submitted by:* Mohammad S Anwar + +You are given two integers $M and $N. + +Write a script to divide the given two integers i.e. $M / $N without using +multiplication, division and mod operator and return the floor of the result of +the division. + +*Example 1:* + + Input: $M = 5, $N = 2 + Output: 2 + +*Example 2:* + + Input: $M = -5, $N = 2 + Output: -3 + +*Example 3:* + + Input: $M = -5, $N = -2 + Output: 2 + +=cut +################################################################################ + +#--------------------------------------# +# Copyright © 2020 PerlMonk Athanasius # +#--------------------------------------# + +use Modern::Perl qw( 2018 ); +use Const::Fast; +use POSIX qw( ceil floor ); +use Regexp::Common qw( number ); + +const my $USAGE => <<~EOS; + Usage: + perl $0 <M> <N> + + <M> Dividend (integer) + <N> Divisor (non-zero integer) + EOS + +#------------------------------------------------------------------------------- +BEGIN +#------------------------------------------------------------------------------- +{ + $| = 1; + print "\n"; +} + +#=============================================================================== +MAIN: +#=============================================================================== +{ + say "Challenge 066, Task #1: Divide Integers (Perl)\n"; + + die $USAGE unless @ARGV == 2 && $ARGV[0] =~ / ^ $RE{num}{int} $ /x && + $ARGV[1] =~ / ^ $RE{num}{int} $ /x && + $ARGV[1] != 0; + my ($M, $N) = @ARGV; + my $quotient = 0; + + if ($M != 0) + { + my $ratio = exp( log(abs $M) - log(abs $N) ); + + $quotient = (($M > 0) && ($N > 0) || + ($M < 0) && ($N < 0)) ? floor($ratio) : -ceil($ratio); + } + + say "$M \\ $N = $quotient"; +} + +################################################################################ diff --git a/challenge-066/athanasius/perl/ch-2.pl b/challenge-066/athanasius/perl/ch-2.pl new file mode 100644 index 0000000000..006cdefecf --- /dev/null +++ b/challenge-066/athanasius/perl/ch-2.pl @@ -0,0 +1,110 @@ +#!perl + +################################################################################ +=comment + +Perl Weekly Challenge 066 +========================= + +Task #2 +------- +*Power Integers* + +*Submitted by:* Mohammad S Anwar + +You are given an integer $N. + +Write a script to check if the given number can be expressed as *m^n* where m +and n are positive integers. Otherwise print 0. + +Please make sure m > 1 and n > 1. + +*BONUS: If there are more than one ways to express the given number then print +all possible solutions.* + +*Example 1:* + +For given $N = 9, it should print 3² or 3^2. + +*Example 2:* + +For given $N = 45, it should print 0. + +*Example 3:* + +For given $N = 64, it should print all or one of 8^2 or 2^6 or 4^3. + +=cut +################################################################################ + +#--------------------------------------# +# Copyright © 2020 PerlMonk Athanasius # +#--------------------------------------# + +use Modern::Perl qw( 2018 ); +use Const::Fast; +use Regexp::Common qw( number ); + +const my $USAGE => <<~EOS; + Usage: + perl $0 <N> -- an integer + EOS + +#------------------------------------------------------------------------------- +BEGIN +#------------------------------------------------------------------------------- +{ + $| = 1; + print "\n"; +} + +#=============================================================================== +MAIN: +#=============================================================================== +{ + print "Challenge 066, Task #2: Power Integers (Perl)\n\n"; + + die $USAGE unless @ARGV == 1 && $ARGV[0] =~ / ^ $RE{num}{int} $ /x; + + my $N = $ARGV[0]; + my $done = 0; + + if ($N > 1) + { + my $powers = find_powers($N); + + if (scalar @$powers) + { + print join(' ', @$powers), "\n"; + $done = 1; + } + } + + print "0\n" unless $done; +} + +#------------------------------------------------------------------------------- +sub find_powers +#------------------------------------------------------------------------------- +{ + my ($N) = @_; + my @powers; + + # The minimum exponent n is 2, since n > 1 (given) + # The maximum exponent n is that for which the base m is minimum (also 2), + # so 2^n = N => n = log⸤2⸥(N) + + my $max_n = int( log($N) / log(2) ); + + for my $n (2 .. $max_n) # exponent + { + my $m = int( ($N ** (1 / $n)) + 0.5 ); # base + my $p = int( ($m ** $n) + 0.5 ); # power + + push @powers, "$m^$n" if $p == $N; + } + + return \@powers; +} + +################################################################################ diff --git a/challenge-066/athanasius/raku/ch-1.raku b/challenge-066/athanasius/raku/ch-1.raku new file mode 100644 index 0000000000..5b64264470 --- /dev/null +++ b/challenge-066/athanasius/raku/ch-1.raku @@ -0,0 +1,80 @@ +use v6d; + +################################################################################ +=begin comment + +Perl Weekly Challenge 066 +========================= + +Task #1 +------- +*Divide Integers* + +*Submitted by:* Mohammad S Anwar + +You are given two integers $M and $N. + +Write a script to divide the given two integers i.e. $M / $N without using +multiplication, division and mod operator and return the floor of the result of +the division. + +*Example 1:* + + Input: $M = 5, $N = 2 + Output: 2 + +*Example 2:* + + Input: $M = -5, $N = 2 + Output: -3 + +*Example 3:* + + Input: $M = -5, $N = -2 + Output: 2 + +=end comment +################################################################################ + +#--------------------------------------# +# Copyright © 2020 PerlMonk Athanasius # +#--------------------------------------# + +#------------------------------------------------------------------------------- +BEGIN ''.put; +#------------------------------------------------------------------------------- + +#=============================================================================== +sub MAIN +( + Int:D $M, #= Dividend (integer) + Int:D $N where { $N }, #= Divisor (non-zero integer) +) +#=============================================================================== +{ + "Challenge 066, Task #1: Divide Integers (Raku)\n".put; + + my Int $quotient = 0; + + if $M + { + my Num $ratio = ($M.abs.log - $N.abs.log).exp; + + $quotient = (($M > 0) && ($N > 0) || + ($M < 0) && ($N < 0)) ?? $ratio.floor !! -$ratio.ceiling; + } + + "$M \\ $N = $quotient".put; +} + +#------------------------------------------------------------------------------- +sub USAGE() +#------------------------------------------------------------------------------- +{ + my Str $usage = $*USAGE; + + $usage ~~ s/ ($*PROGRAM-NAME) /raku $0/; + $usage.put; +} + +################################################################################ diff --git a/challenge-066/athanasius/raku/ch-2.raku b/challenge-066/athanasius/raku/ch-2.raku new file mode 100644 index 0000000000..d69adcba13 --- /dev/null +++ b/challenge-066/athanasius/raku/ch-2.raku @@ -0,0 +1,107 @@ +use v6d; + +################################################################################ +=begin comment + +Perl Weekly Challenge 066 +========================= + +Task #2 +------- +*Power Integers* + +*Submitted by:* Mohammad S Anwar + +You are given an integer $N. + +Write a script to check if the given number can be expressed as *m^n* where m +and n are positive integers. Otherwise print 0. + +Please make sure m > 1 and n > 1. + +*BONUS: If there are more than one ways to express the given number then print +all possible solutions.* + +*Example 1:* + +For given $N = 9, it should print 3² or 3^2. + +*Example 2:* + +For given $N = 45, it should print 0. + +*Example 3:* + +For given $N = 64, it should print all or one of 8^2 or 2^6 or 4^3. + +=end comment +################################################################################ + +#--------------------------------------# +# Copyright © 2020 PerlMonk Athanasius # +#--------------------------------------# + +#------------------------------------------------------------------------------- +BEGIN ''.put; +#------------------------------------------------------------------------------- + +#=============================================================================== +sub MAIN( Int:D $N ) #= an integer +#=============================================================================== +{ + "Challenge 066, Task #2: Power Integers (Raku)\n".put; + + my Bool $done = False; + + if $N > 1 + { + my Str @powers = find-powers($N); + + if @powers.elems + { + @powers.join(' ').put; + $done = True; + } + } + + 0.put unless $done; +} + +#------------------------------------------------------------------------------- +sub find-powers( Int:D $N --> Array[Str] ) +#------------------------------------------------------------------------------- +{ + my Str @powers; + + # The minimum exponent n is 2, since n > 1 (given) + # The maximum exponent n is that for which the base m is minimum (also 2), + # so 2^n = N => n = log⸤2⸥(N) + + my UInt $max-n = (log($N) / log(2)).floor; + + for 2 .. $max-n -> UInt $n # exponent + { + my UInt $m = (($N ** (1 / $n)) + 0.5).floor; # base + + # From the Raku documentation for infix **: + # "If the right-hand side is a non-negative integer and the left-hand + # side is an arbitrary precision type (Int, FatRat), then the calcula- + # tion is carried out without loss of precision." + + @powers.push: "$m^$n" if $m ** $n == $N; # power + } + + return @powers; +} + +#------------------------------------------------------------------------------- +sub USAGE() +#------------------------------------------------------------------------------- +{ + my Str $usage = $*USAGE; + + $usage ~~ s/ ($*PROGRAM-NAME) /raku $0/; + $usage.put; +} + +################################################################################ |
