aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--challenge-072/athanasius/perl/ch-1.pl177
-rw-r--r--challenge-072/athanasius/perl/ch-2.pl116
-rw-r--r--challenge-072/athanasius/raku/ch-1.raku151
-rw-r--r--challenge-072/athanasius/raku/ch-2.raku115
4 files changed, 559 insertions, 0 deletions
diff --git a/challenge-072/athanasius/perl/ch-1.pl b/challenge-072/athanasius/perl/ch-1.pl
new file mode 100644
index 0000000000..a6cc08b4a4
--- /dev/null
+++ b/challenge-072/athanasius/perl/ch-1.pl
@@ -0,0 +1,177 @@
+#!perl
+
+################################################################################
+=comment
+
+Perl Weekly Challenge 072
+=========================
+
+Task #1
+-------
+*Trailing Zeroes*
+
+*Submitted by:* Mohammad S Anwar
+
+You are given a positive integer $N (<= 10).
+
+Write a script to print number of trailing zeroes in $N!.
+
+*Example 1*
+
+Input: $N = 10
+Output: 2 as $N! = 3628800 has 2 trailing zeroes
+
+*Example 2*
+
+Input: $N = 7
+Output: 1 as $N! = 5040 has 1 trailing zero
+
+*Example 3*
+
+Input: $N = 4
+Output: 0 as $N! = 24 has 0 trailing zero
+
+=cut
+################################################################################
+
+#--------------------------------------#
+# Copyright © 2020 PerlMonk Athanasius #
+#--------------------------------------#
+
+#===============================================================================
+=comment
+
+The simplest solution to the problem *as given* (i.e., with only 11 possible
+cases, from 0! to 10!) is a lookup table, in which the answers are pre-computed.
+
+The more interesting problem is to find the number of trailing zeroes for a
+factorial n! of arbitrary size n. Since each trailing zero results from a factor
+pair of 2 and 5 -- and since the number of factors of 2 is always larger than the
+corresponding number of factors of 5 -- this means simply counting the number of
+times 5 occurs as a factor in the numbers 1 .. n. Care must be taken when
+considering powers of 5; e.g., 24! has 4 trailing zeroes, but 25! has 6 (an
+additional 2 zeroes) because 25 = 5 * 5.
+
+In the solution code below, the command-line flag "--e[xtended]" allows values
+of n greater than 10 to be given as input; e.g.:
+
+ 18:21 >perl ch-1.pl -e 25
+
+ Challenge 072, Task #1: Trailing Zeroes (Perl)
+
+ Input: N = 25
+ Output: 6 (because 25! has 6 trailing zeroes)
+
+ 18:22 >
+
+=cut
+#===============================================================================
+
+use strict;
+use warnings;
+use Const::Fast;
+use Getopt::Long;
+use Regexp::Common qw( number );
+
+const my $MAX_N => 10;
+
+const my $USAGE =>
+"Usage:
+ perl $0 [--extended] <N>
+
+ --extended Allow values of N > $MAX_N
+ <N> A positive integer <= $MAX_N\n";
+
+const my @ZEROES =>
+(
+ # N! #0s N
+ [ 1, 0 ], # 0
+ [ 1, 0 ], # 1
+ [ 2, 0 ], # 2
+ [ 6, 0 ], # 3
+ [ 24, 0 ], # 4
+ [ 120, 1 ], # 5
+ [ 720, 1 ], # 6
+ [ 5_040, 1 ], # 7
+ [ 40_320, 1 ], # 8
+ [ 362_880, 1 ], # 9
+ [ 3_628_800, 2 ], # 10
+);
+
+#-------------------------------------------------------------------------------
+BEGIN
+#-------------------------------------------------------------------------------
+{
+ $| = 1;
+ print "\nChallenge 072, Task #1: Trailing Zeroes (Perl)\n\n";
+}
+
+#===============================================================================
+MAIN:
+#===============================================================================
+{
+ my $N = parse_command_line();
+ my ($zeroes, $factorial);
+
+ printf "Input: N = %d\n", $N;
+
+ if ($N > $MAX_N)
+ {
+ $zeroes = find_trailing_zeroes($N);
+ }
+ else
+ {
+ ($factorial, $zeroes) = $ZEROES[ $N ]->@*;
+ }
+
+ printf "Output: %d (because %d!%s has %d trailing zero%s)\n",
+ $zeroes, $N, $factorial ? sprintf(' = %d', $factorial) : '',
+ $zeroes, $zeroes == 1 ? '' : 'es';
+}
+
+#-------------------------------------------------------------------------------
+sub find_trailing_zeroes
+#-------------------------------------------------------------------------------
+{
+ my ($n) = @_;
+
+ # Adapted from Rahul Jain, "Count trailing zeroes in factorial of a number":
+ # https://www.geeksforgeeks.org/count-trailing-zeroes-factorial-number/
+
+ my $count = 0;
+
+ for (my $i = 5; $n / $i >= 1; $i *= 5)
+ {
+ $count += int($n / $i);
+ }
+
+ return $count;
+}
+
+#-------------------------------------------------------------------------------
+sub parse_command_line
+#-------------------------------------------------------------------------------
+{
+ my $extended;
+
+ GetOptions
+ (
+ 'extended!' => \$extended,
+
+ ) or die "Error in command line arguments\n";
+
+ scalar @ARGV == 1 or die $USAGE;
+
+ my $N = $ARGV[0];
+ $N =~ /\A$RE{num}{int}\z/ or die $USAGE;
+ $N >= 0 or die $USAGE;
+
+ unless ($extended)
+ {
+ $N <= $MAX_N or die $USAGE;
+ }
+
+ return $N;
+}
+
+################################################################################
diff --git a/challenge-072/athanasius/perl/ch-2.pl b/challenge-072/athanasius/perl/ch-2.pl
new file mode 100644
index 0000000000..6e88c4c850
--- /dev/null
+++ b/challenge-072/athanasius/perl/ch-2.pl
@@ -0,0 +1,116 @@
+#!perl
+
+################################################################################
+=comment
+
+Perl Weekly Challenge 072
+=========================
+
+Task #2
+-------
+*Lines Range*
+
+*Submitted by:* Mohammad S Anwar
+
+You are given a text file name $file and range $A - $B where $A <= $B.
+
+Write a script to display lines range $A and $B in the given file.
+
+*Example*
+
+Input:
+ $ cat input.txt
+ L1
+ L2
+ L3
+ L4
+ ...
+ ...
+ ...
+ ...
+ L100
+
+$A = 4 and $B = 12
+
+Output:
+ L4
+ L5
+ L6
+ L7
+ L8
+ L9
+ L10
+ L11
+ L12
+
+=cut
+################################################################################
+
+#--------------------------------------#
+# Copyright © 2020 PerlMonk Athanasius #
+#--------------------------------------#
+
+use strict;
+use warnings;
+use Const::Fast;
+use Getopt::Long;
+
+const my $USAGE =>
+"Usage:
+ perl $0 [--file <Str>] [-A <Natural>] [-B <Natural>]
+
+ --file <Str> The name of a readable text file
+ -A <Natural> Lower bound of range of lines
+ -B <Natural> Upper bound of range of lines: A <= B\n";
+
+#-------------------------------------------------------------------------------
+BEGIN
+#-------------------------------------------------------------------------------
+{
+ $| = 1;
+ print "\nChallenge 072, Task #2: Lines Range (Perl)\n\n";
+}
+
+#===============================================================================
+MAIN:
+#===============================================================================
+{
+ my ($file, $A, $B) = parse_command_line();
+
+ open(my $fh, '<', $file)
+ or die "Cannot open file '$file' for reading, stopped";
+
+ my $line_num = 0;
+
+ while (my $line = <$fh>)
+ {
+ last if ++$line_num > $B;
+ print $line if $line_num >= $A;
+ }
+
+ close $fh
+ or die "Cannot close file '$file', stopped";
+}
+
+#-------------------------------------------------------------------------------
+sub parse_command_line
+#-------------------------------------------------------------------------------
+{
+ my ($file, $A, $B);
+
+ GetOptions
+ (
+ 'file=s' => \$file,
+ 'A=i' => \$A,
+ 'B=i' => \$B,
+ ) or die $USAGE;
+
+ scalar @ARGV == 0 or die $USAGE;
+ defined $file && $file ne '' or die $USAGE;
+ defined $A && $A > 0 or die $USAGE;
+ defined $B && $A <= $B or die $USAGE;
+
+ return ($file, $A, $B);
+}
+
+################################################################################
diff --git a/challenge-072/athanasius/raku/ch-1.raku b/challenge-072/athanasius/raku/ch-1.raku
new file mode 100644
index 0000000000..a14906df9c
--- /dev/null
+++ b/challenge-072/athanasius/raku/ch-1.raku
@@ -0,0 +1,151 @@
+use v6d;
+
+################################################################################
+=begin comment
+
+Perl Weekly Challenge 072
+=========================
+
+Task #1
+-------
+*Trailing Zeroes*
+
+*Submitted by:* Mohammad S Anwar
+
+You are given a positive integer $N (<= 10).
+
+Write a script to print number of trailing zeroes in $N!.
+
+*Example 1*
+
+Input: $N = 10
+Output: 2 as $N! = 3628800 has 2 trailing zeroes
+
+*Example 2*
+
+Input: $N = 7
+Output: 1 as $N! = 5040 has 1 trailing zero
+
+*Example 3*
+
+Input: $N = 4
+Output: 0 as $N! = 24 has 0 trailing zero
+
+=end comment
+################################################################################
+
+#--------------------------------------#
+# Copyright © 2020 PerlMonk Athanasius #
+#--------------------------------------#
+
+#===============================================================================
+=begin comment
+
+The simplest solution to the problem *as given* (i.e., with only 11 possible
+cases, from 0! to 10!) is a lookup table, in which the answers are pre-computed.
+
+The more interesting problem is to find the number of trailing zeroes for a
+factorial n! of arbitrary size n. Since each trailing zero results from a factor
+pair of 2 and 5 -- and since the number of factors of 2 is always larger than the
+corresponding number of factors of 5 -- this means simply counting the number of
+times 5 occurs as a factor in the numbers 1 .. n. Care must be taken when
+considering powers of 5; e.g., 24! has 4 trailing zeroes, but 25! has 6 (an
+additional 2 zeroes) because 25 = 5 * 5.
+
+In the solution code below, the command-line flag "--ext[ended]" allows values
+of n greater than 10 to be given as input; e.g.:
+
+ 18:25 >raku ch-1.raku --ext 25
+
+ Challenge 072, Task #1: Trailing Zeroes (Raku)
+
+ Input: N = 25
+ Output: 6 (because 25! has 6 trailing zeroes)
+
+ 18:25 >
+
+=end comment
+#===============================================================================
+
+my UInt constant $MAX-N = 10;
+my constant @ZEROES = # N! #0s N
+ ( 1, 0 ), # 0
+ ( 1, 0 ), # 1
+ ( 2, 0 ), # 2
+ ( 6, 0 ), # 3
+ ( 24, 0 ), # 4
+ ( 120, 1 ), # 5
+ ( 720, 1 ), # 6
+ ( 5_040, 1 ), # 7
+ ( 40_320, 1 ), # 8
+ ( 362_880, 1 ), # 9
+ ( 3_628_800, 2 ); # 10
+
+#-------------------------------------------------------------------------------
+BEGIN
+#-------------------------------------------------------------------------------
+{
+ "\nChallenge 072, Task #1: Trailing Zeroes (Raku)\n".put;
+}
+
+#===============================================================================
+sub MAIN
+(
+ UInt:D $N, #= A positive integer <= $MAX-N
+ Bool:D :ext(:$extended) = False, #= Allow values of N > $MAX-N
+)
+#===============================================================================
+{
+ if $N > $MAX-N && !$extended
+ {
+ USAGE();
+ exit(1);
+ }
+
+ "Input: N = %d\n".printf: $N;
+
+ my UInt ($zeroes, $factorial);
+
+ if $N > $MAX-N
+ {
+ $zeroes = find-trailing-zeroes($N);
+ }
+ else
+ {
+ ($factorial, $zeroes) = @ZEROES[ $N ];
+ }
+
+ "Output: %d (because %d!%s has %d trailing zero%s)\n".printf:
+ $zeroes, $N, $factorial ?? sprintf(' = %d', $factorial) !! '', $zeroes,
+ $zeroes == 1 ?? '' !! 'es';
+}
+
+#-------------------------------------------------------------------------------
+sub find-trailing-zeroes(UInt:D $n --> UInt:D)
+#-------------------------------------------------------------------------------
+{
+ # Adapted from Rahul Jain, "Count trailing zeroes in factorial of a number":
+ # https://www.geeksforgeeks.org/count-trailing-zeroes-factorial-number/
+
+ my UInt $count = 0;
+
+ loop (my UInt $i = 5; $n / $i >= 1; $i *= 5)
+ {
+ $count += floor($n / $i);
+ }
+
+ return $count;
+}
+
+#-------------------------------------------------------------------------------
+sub USAGE()
+#-------------------------------------------------------------------------------
+{
+ my Str $usage = $*USAGE;
+
+ $usage ~~ s / ($*PROGRAM-NAME) /raku $0/;
+ $usage ~~ s:g/ \$MAX\-N /$MAX-N/;
+ $usage.put;
+}
+
+################################################################################
diff --git a/challenge-072/athanasius/raku/ch-2.raku b/challenge-072/athanasius/raku/ch-2.raku
new file mode 100644
index 0000000000..375e776d62
--- /dev/null
+++ b/challenge-072/athanasius/raku/ch-2.raku
@@ -0,0 +1,115 @@
+use v6d;
+
+################################################################################
+=begin comment
+
+Perl Weekly Challenge 072
+=========================
+
+Task #2
+-------
+*Lines Range*
+
+*Submitted by:* Mohammad S Anwar
+
+You are given a text file name $file and range $A - $B where $A <= $B.
+
+Write a script to display lines range $A and $B in the given file.
+
+*Example*
+
+Input:
+ $ cat input.txt
+ L1
+ L2
+ L3
+ L4
+ ...
+ ...
+ ...
+ ...
+ L100
+
+$A = 4 and $B = 12
+
+Output:
+ L4
+ L5
+ L6
+ L7
+ L8
+ L9
+ L10
+ L11
+ L12
+
+=end comment
+################################################################################
+
+#--------------------------------------#
+# Copyright © 2020 PerlMonk Athanasius #
+#--------------------------------------#
+
+subset Natural of UInt where * > 0;
+
+#-------------------------------------------------------------------------------
+BEGIN
+#-------------------------------------------------------------------------------
+{
+ "\nChallenge 072, Task #2: Lines Range (Raku)\n".put;
+}
+
+#===============================================================================
+sub MAIN
+(
+ Str:D :$file, #= The name of a readable text file
+ Natural:D :$A, #= Lower bound of range of lines
+ Natural:D :$B where { $A <= $B }, #= Upper bound of range of lines: A <= B
+)
+#===============================================================================
+{
+ $file.IO ~~ :r or die "ERROR: Cannot open file '$file' for reading";
+
+ my UInt $line-num = 0;
+
+ for $file.IO.lines -> Str $line
+ {
+ last if ++$line-num > $B;
+ $line.put if $line-num >= $A;
+ }
+
+=begin comment
+
+ # Alternative syntax using gather, take, and ff
+
+ gather for $file.IO.lines -> Str $line
+ {
+ $_ = ++$line-num;
+ take $line if $A ff $B;
+
+ } .join("\n").put;
+
+=end comment
+
+ CATCH
+ {
+ default
+ {
+ .payload.put;
+ }
+ }
+}
+
+#-------------------------------------------------------------------------------
+sub USAGE()
+#-------------------------------------------------------------------------------
+{
+ my Str $usage = $*USAGE;
+
+ $usage ~~ s:g/ ($*PROGRAM-NAME) /raku $0/;
+ $usage ~~ s:g/ \s where \s \{ .*? \} //;
+ $usage ~~ s:g/ \> \s+ /> /;
+ $usage.put;
+}
+
+################################################################################