aboutsummaryrefslogtreecommitdiff
path: root/challenge-085
diff options
context:
space:
mode:
authorMohammad S Anwar <Mohammad.Anwar@yahoo.com>2020-11-08 13:16:19 +0000
committerGitHub <noreply@github.com>2020-11-08 13:16:19 +0000
commit10f545e3c94e9f8d7948303fedeb79d367cc4e9d (patch)
treec4b04f0e94a9fe025ea7d5f2dd92041a0844862c /challenge-085
parentfaf0df91b140867dc8135139327a21ef55441600 (diff)
parenta1a288b32bbc57f471597353c3b3aeb37a1f0045 (diff)
downloadperlweeklychallenge-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.pl148
-rw-r--r--challenge-085/athanasius/perl/ch-2.pl149
-rw-r--r--challenge-085/athanasius/raku/ch-1.raku128
-rw-r--r--challenge-085/athanasius/raku/ch-2.raku124
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;
+}
+
+###############################################################################