diff options
| author | Mohammad S Anwar <Mohammad.Anwar@yahoo.com> | 2020-11-08 13:16:19 +0000 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-11-08 13:16:19 +0000 |
| commit | 10f545e3c94e9f8d7948303fedeb79d367cc4e9d (patch) | |
| tree | c4b04f0e94a9fe025ea7d5f2dd92041a0844862c /challenge-085 | |
| parent | faf0df91b140867dc8135139327a21ef55441600 (diff) | |
| parent | a1a288b32bbc57f471597353c3b3aeb37a1f0045 (diff) | |
| download | perlweeklychallenge-club-10f545e3c94e9f8d7948303fedeb79d367cc4e9d.tar.gz perlweeklychallenge-club-10f545e3c94e9f8d7948303fedeb79d367cc4e9d.tar.bz2 perlweeklychallenge-club-10f545e3c94e9f8d7948303fedeb79d367cc4e9d.zip | |
Merge pull request #2720 from PerlMonk-Athanasius/branch-for-challenge-085
Perl & Raku solutions to Tasks 1 & 2 of the Perl Weekly Challenge #085
Diffstat (limited to 'challenge-085')
| -rw-r--r-- | challenge-085/athanasius/perl/ch-1.pl | 148 | ||||
| -rw-r--r-- | challenge-085/athanasius/perl/ch-2.pl | 149 | ||||
| -rw-r--r-- | challenge-085/athanasius/raku/ch-1.raku | 128 | ||||
| -rw-r--r-- | challenge-085/athanasius/raku/ch-2.raku | 124 |
4 files changed, 549 insertions, 0 deletions
diff --git a/challenge-085/athanasius/perl/ch-1.pl b/challenge-085/athanasius/perl/ch-1.pl new file mode 100644 index 0000000000..d111d73169 --- /dev/null +++ b/challenge-085/athanasius/perl/ch-1.pl @@ -0,0 +1,148 @@ +#!perl + +############################################################################### +=comment + +Perl Weekly Challenge 085 +========================= + +Task #1 +------- +*Triplet Sum* + +Submitted by: Mohammad S Anwar + +You are given an array of real numbers greater than zero. + +Write a script to find if there exists a triplet (a,b,c) such that 1 < a+b+c < +2. Print 1 if you succeed otherwise 0. + +Example 1: + + Input: @R = (1.2, 0.4, 0.1, 2.5) + Output: 1 as 1 < 1.2 + 0.4 + 0.1 < 2 + +Example 2: + + Input: @R = (0.2, 1.5, 0.9, 1.1) + Output: 0 + +Example 3: + + Input: @R = (0.5, 1.1, 0.3, 0.7) + Output: 1 as 1 < 0.5 + 1.1 + 0.3 < 2 + +=cut +############################################################################### + +#============================================================================== +=comment + +Assumption: +A "triplet" is a *contiguous* sequence of 3 elements in the array. + +Note: +If more than one triplet satisfies the requirement (and assuming $EXPLAIN is +set to a true value), then only the first such triplet will be shown in the +explanation. + +=cut +#============================================================================== + +#--------------------------------------# +# Copyright © 2020 PerlMonk Athanasius # +#--------------------------------------# + + # Exports: +use strict; +use warnings; +use Const::Fast; # const() +use Regexp::Common qw( number ); # %RE{num} + +const my $EXPLAIN => 1; +const my $USAGE => +"Usage: + perl $0 [<R> ...] + + [<R> ...] An array of real numbers greater than zero\n"; + +#------------------------------------------------------------------------------ +BEGIN +#------------------------------------------------------------------------------ +{ + $| = 1; + print "\nChallenge 085, Task #1: Triplet Sum (Perl)\n\n"; +} + +#============================================================================== +MAIN: +#============================================================================== +{ + my @R = parse_command_line(); + + # Add zero to each real number to convert it to its decimal representation + # (where possible); e.g., 1e-4 --> 0.0001 but 1e-5 --> 1e-05 + + printf "Input: \@R = (%s)\n", join ', ', map { $_ + 0 } @R; + + if (my $index = search_for_triplet(\@R) < 0) # -ve index means no triplet + { + print "Output: 0\n"; + } + elsif ($EXPLAIN) + { + my @triplet = @R[$index .. $index + 2]; + my $sum = 0; + $sum += $_ for @triplet; + + printf "Output: 1 as 1 < (%s = %f) < 2\n", join(' + ', @triplet), $sum; + } + else + { + print "Output: 1\n"; + } +} + +#------------------------------------------------------------------------------ +sub search_for_triplet +#------------------------------------------------------------------------------ +{ + my ($R) = @_; + my $idx = -1; # Array index of the first triplet element; -1 = none + + if (scalar @$R >= 3) + { + for my $i (0 .. $#$R - 2) + { + my $sum = $R->[$i] + $R->[$i + 1] + $R->[$i + 2]; + + # Note: From Perl v5.32.0, this can be simplified to: + # if (1 < $sum < 2) + + if (1 < $sum && $sum < 2) + { + $idx = $i; + last; + } + } + } + + return $idx; +} + +#------------------------------------------------------------------------------ +sub parse_command_line +#------------------------------------------------------------------------------ +{ + for (@ARGV) + { + / \A $RE{num}{real} \z /x + or die qq[ERROR: "$_" is not a real number\n$USAGE]; + + $_ > 0 or die qq[ERROR: "$_" is not greater than zero\n$USAGE]; + } + + return @ARGV; +} + +############################################################################### diff --git a/challenge-085/athanasius/perl/ch-2.pl b/challenge-085/athanasius/perl/ch-2.pl new file mode 100644 index 0000000000..d7dbadfd72 --- /dev/null +++ b/challenge-085/athanasius/perl/ch-2.pl @@ -0,0 +1,149 @@ +#!perl + +############################################################################### +=comment + +Perl Weekly Challenge 085 +========================= + +Task #2 +------- +*Power of Two Integers* + +Submitted by: Mohammad S Anwar + +You are given a positive integer $N. + +Write a script to find if it can be expressed as a ^ b where a > 0 and b > 1. +Print 1 if you succeed otherwise 0. + +Example 1: + + Input: 8 + Output: 1 as 8 = 2 ^ 3 + +Example 2: + + Input: 15 + Output: 0 + +Example 3: + + Input: 125 + Output: 1 as 125 = 5 ^ 3 + +=cut +############################################################################### + +#--------------------------------------# +# Copyright © 2020 PerlMonk Athanasius # +#--------------------------------------# + + # Exports: +use strict; +use warnings; +use Const::Fast; # const() +use Regexp::Common qw( number ); # %RE{num} + +const my $EXPLAIN => 1; +const my $USAGE => +"Usage: + perl $0 <N> + + <N> A positive integer\n"; + +#------------------------------------------------------------------------------ +BEGIN +#------------------------------------------------------------------------------ +{ + $| = 1; + print "\nChallenge 085, Task #2: Power of Two Integers (Perl)\n\n"; +} + +#============================================================================== +MAIN: +#============================================================================== +{ + my $N = parse_command_line(); + + print "Input: $N\n"; + + my ($base, $exp) = find_power($N); + + if ($base < 1) + { + print "Output: 0\n"; + } + elsif ($EXPLAIN) + { + print "Output: 1 as $N = $base ^ $exp\n"; + } + else + { + print "Output: 1\n"; + } +} + +#------------------------------------------------------------------------------ +sub find_power +#------------------------------------------------------------------------------ +{ + my ($N) = @_; + my $base = 0; + my $exponent = 1; + my $root = round(sqrt $N); + + if ($root * $root == $N) + { + $base = $root; + $exponent = 2; + } + else + { + my $max_exp = round(log($N) / log(2)); + + for (my $exp = 3; $exp <= $max_exp; $exp += 2) + { + $root = round($N ** (1 / $exp)); + my $n = 1; + $n *= $root for 1 .. $exp; + + if ($n == $N) + { + $base = $root; + $exponent = $exp; + last; + } + } + } + + return ($base, $exponent); +} + +#------------------------------------------------------------------------------ +sub round +#------------------------------------------------------------------------------ +{ + my ($n) = @_; + + return int($n + 0.5); +} + +#------------------------------------------------------------------------------ +sub parse_command_line +#------------------------------------------------------------------------------ +{ + my $args = scalar @ARGV; + $args == 1 or die qq[ERROR: Expected a single command-line ] . + qq[argument, found $args\n] . $USAGE; + + my $N = $ARGV[0]; + $N =~ / \A $RE{num}{int} \z /x + or die qq[ERROR: "$N" is not an integer\n] . $USAGE; + + $N > 0 or die qq[ERROR: "$N" is not a positive integer\n] . $USAGE; + + return int $N; +} + +############################################################################### diff --git a/challenge-085/athanasius/raku/ch-1.raku b/challenge-085/athanasius/raku/ch-1.raku new file mode 100644 index 0000000000..68807ab604 --- /dev/null +++ b/challenge-085/athanasius/raku/ch-1.raku @@ -0,0 +1,128 @@ +use v6d; + +############################################################################### +=begin comment + +Perl Weekly Challenge 085 +========================= + +Task #1 +------- +*Triplet Sum* + +Submitted by: Mohammad S Anwar + +You are given an array of real numbers greater than zero. + +Write a script to find if there exists a triplet (a,b,c) such that 1 < a+b+c < +2. Print 1 if you succeed otherwise 0. + +Example 1: + + Input: @R = (1.2, 0.4, 0.1, 2.5) + Output: 1 as 1 < 1.2 + 0.4 + 0.1 < 2 + +Example 2: + + Input: @R = (0.2, 1.5, 0.9, 1.1) + Output: 0 + +Example 3: + + Input: @R = (0.5, 1.1, 0.3, 0.7) + Output: 1 as 1 < 0.5 + 1.1 + 0.3 < 2 + +=end comment +############################################################################### + +#--------------------------------------# +# Copyright © 2020 PerlMonk Athanasius # +#--------------------------------------# + +#============================================================================== +=begin comment + +Assumption: +A "triplet" is a *contiguous* sequence of 3 elements in the array. + +Note: +If more than one triplet satisfies the requirement (and assuming $EXPLAIN is +set to a true value), then only the first such triplet will be shown in the +explanation. + +=end comment +#============================================================================== + +my Bool constant $EXPLAIN = True; + +subset Positive of Real where * > 0; + +#------------------------------------------------------------------------------ +BEGIN +#------------------------------------------------------------------------------ +{ + "\nChallenge 085, Task #1: Triplet Sum (Raku)\n".put; +} + +##============================================================================= +sub MAIN +( + *@R where .all ~~ Positive:D #= An array of real numbers greater than zero +) +##============================================================================= +{ + # Add zero to each real number to convert it to its decimal representation + # (where possible); e.g., 0x10FE --> 4350 and 1e-4 --> 0.0001 but 1e-5 --> + # 1e-05 + + "Input: @R = (%s)\n".printf: @R.map( { $_ + 0 } ).join: ', '; + + if my Int $idx = search-for-triplet(@R) < 0 # -ve index means no triplet + { + "Output: 0".put; + } + elsif $EXPLAIN + { + my Positive @triplet = @R[$idx .. $idx + 2]; + + "Output: 1 as 1 < (%s = %f) < 2\n".printf: + @triplet.join(' + '), @triplet.sum; + } + else + { + "Output: 1".put; + } +} + +#------------------------------------------------------------------------------ +sub search-for-triplet( Array:D[Positive:D] $R --> Int:D ) +#------------------------------------------------------------------------------ +{ + my Int $idx = -1; # Array index of the first triplet element; -1 = none + + if $R.elems >= 3 + { + for 0 .. $R.end - 2 -> UInt $i + { + if 1 < $R[$i .. $i + 2].sum < 2 + { + $idx = $i; + last; + } + } + } + + return $idx; +} + +#------------------------------------------------------------------------------ +sub USAGE() +#------------------------------------------------------------------------------ +{ + my Str $usage = $*USAGE; + + $usage ~~ s/ ($*PROGRAM-NAME) /raku $0/; + $usage.put; +} + +############################################################################## diff --git a/challenge-085/athanasius/raku/ch-2.raku b/challenge-085/athanasius/raku/ch-2.raku new file mode 100644 index 0000000000..db68ff4174 --- /dev/null +++ b/challenge-085/athanasius/raku/ch-2.raku @@ -0,0 +1,124 @@ +use v6d; + +############################################################################### +=begin comment + +Perl Weekly Challenge 085 +========================= + +Task #2 +------- +*Power of Two Integers* + +Submitted by: Mohammad S Anwar + +You are given a positive integer $N. + +Write a script to find if it can be expressed as a ^ b where a > 0 and b > 1. +Print 1 if you succeed otherwise 0. + +Example 1: + + Input: 8 + Output: 1 as 8 = 2 ^ 3 + +Example 2: + + Input: 15 + Output: 0 + +Example 3: + + Input: 125 + Output: 1 as 125 = 5 ^ 3 + +=end comment +############################################################################### + +#--------------------------------------# +# Copyright © 2020 PerlMonk Athanasius # +#--------------------------------------# + +my Bool constant $EXPLAIN = True; + +subset Positive of Int where * > 0; + +#------------------------------------------------------------------------------ +BEGIN +#------------------------------------------------------------------------------ +{ + "\nChallenge 085, Task #2: Power of Two Integers (Raku)\n".put; +} + +##============================================================================= +sub MAIN +( + Positive:D $N #= A positive integer +) +##============================================================================= +{ + "Input: $N".put; + + my (UInt $base, Positive $exp) = find-power($N); + + if $base == 0 + { + "Output: 0".put; + } + elsif $EXPLAIN + { + "Output: 1 as $N = $base ^ $exp".put; + } + else + { + "Output: 1".put; + } +} + +#------------------------------------------------------------------------------ +sub find-power( Positive:D $N --> List:D[UInt:D] ) +#------------------------------------------------------------------------------ +{ + my UInt $base = 0; + my Positive $exponent = 1; + my Positive $root = $N.sqrt.round; + + if $root * $root == $N + { + $base = $root; + $exponent = 2; + } + else + { + my UInt $max-exp = $N.log2.round; + + loop (my UInt $exp = 3; $exp <= $max-exp; $exp += 2) + { + $root = ($N ** (1 / $exp)).round; + + my UInt $n = 1; + $n *= $root for 1 .. $exp; + + if $n == $N + { + $base = $root; + $exponent = $exp; + last; + } + } + } + + return [$base, $exponent]; +} + +#------------------------------------------------------------------------------ +sub USAGE() +#------------------------------------------------------------------------------ +{ + my Str $usage = $*USAGE; + + $usage ~~ s/ ($*PROGRAM-NAME) /raku $0/; + $usage.put; +} + +############################################################################### |
