aboutsummaryrefslogtreecommitdiff
path: root/challenge-070
diff options
context:
space:
mode:
authorPerlMonk Athanasius <PerlMonk.Athanasius@gmail.com>2020-07-21 21:22:51 -0700
committerPerlMonk Athanasius <PerlMonk.Athanasius@gmail.com>2020-07-21 21:22:51 -0700
commitc6f6e7a6a5ba0688bf4c2e410491e912f24fe654 (patch)
tree96aab53090243744e18232f997567f3ea0c494e0 /challenge-070
parent55efbe97c39b53be14431f457892192ad7f2df3d (diff)
downloadperlweeklychallenge-club-c6f6e7a6a5ba0688bf4c2e410491e912f24fe654.tar.gz
perlweeklychallenge-club-c6f6e7a6a5ba0688bf4c2e410491e912f24fe654.tar.bz2
perlweeklychallenge-club-c6f6e7a6a5ba0688bf4c2e410491e912f24fe654.zip
Perl & Raku solutions to Tasks 1 & 2 of the Perl Weekly Challenge #070
On branch branch-for-challenge-070 Changes to be committed: new file: challenge-070/athanasius/perl/ch-1.pl new file: challenge-070/athanasius/perl/ch-2.pl new file: challenge-070/athanasius/raku/ch-1.raku new file: challenge-070/athanasius/raku/ch-2.raku
Diffstat (limited to 'challenge-070')
-rw-r--r--challenge-070/athanasius/perl/ch-1.pl131
-rw-r--r--challenge-070/athanasius/perl/ch-2.pl125
-rw-r--r--challenge-070/athanasius/raku/ch-1.raku114
-rw-r--r--challenge-070/athanasius/raku/ch-2.raku113
4 files changed, 483 insertions, 0 deletions
diff --git a/challenge-070/athanasius/perl/ch-1.pl b/challenge-070/athanasius/perl/ch-1.pl
new file mode 100644
index 0000000000..00cdb826c4
--- /dev/null
+++ b/challenge-070/athanasius/perl/ch-1.pl
@@ -0,0 +1,131 @@
+#!perl
+
+################################################################################
+=comment
+
+Perl Weekly Challenge 070
+=========================
+
+Task #1
+-------
+*Character Swapping*
+
+*Submitted by:* Mohammad S Anwar
+
+You are given a string $S of size $N.
+
+You are also given swap count $C and offset $O such that $C >= 1, $O >= 1,
+$C <= $O and $C + $O <= $N.
+
+*UPDATE: 2020-07-20 16:10:00*
+*Pete Houston suggested to put additional constraint i.e. $C <= $O. He presented
+the use case $S = 'abcd', $C = 2, $O = 1.*
+
+Write a script to perform character swapping like below:
+
+ $S[ 1 % $N ] <=> $S[ (1 + $O) % $N ]
+ $S[ 2 % $N ] <=> $S[ (2 + $O) % $N ]
+ $S[ 3 % $N ] <=> $S[ (3 + $O) % $N ]
+ ...
+ ...
+ $S[ $C % $N ] <=> $S[ ($C + $O) % $N ]
+
+*Example 1*
+
+ Input:
+ $S = 'perlandraku'
+ $C = 3
+ $O = 4
+
+ Character Swapping:
+ swap 1: e <=> n = pnrlaedraku
+ swap 2: r <=> d = pndlaerraku
+ swap 3: l <=> r = pndraerlaku
+
+ Output:
+ pndraerlaku
+
+=cut
+################################################################################
+
+#--------------------------------------#
+# Copyright © 2020 PerlMonk Athanasius #
+#--------------------------------------#
+
+use strict;
+use warnings;
+use Const::Fast;
+use Regexp::Common qw( number );
+use constant DISPLAY_SWAP => 1;
+
+const my $USAGE =>
+"Usage:
+ perl $0 <S> <C> <O>
+
+ <S> Non-empty string
+ <C> Swap count: integer >= 1
+ <O> Offset: integer >= 1 such that C <= O and C + O <= |S|\n";
+
+#-------------------------------------------------------------------------------
+BEGIN
+#-------------------------------------------------------------------------------
+{
+ $| = 1;
+ print "\nChallenge 070, Task #1: Character Swapping (Perl)\n\n";
+}
+
+#===============================================================================
+MAIN:
+#===============================================================================
+{
+ my ($S, $C, $O) = parse_command_line();
+
+ print "Input:\n \$S = '$S'\n \$C = $C\n \$O = $O\n\n";
+
+ print "Character Swapping:\n" if DISPLAY_SWAP;
+
+ $S = swap($S, $_, $O) for 1 .. $C;
+
+ print "\n" if DISPLAY_SWAP;
+ print "Output:\n $S\n";
+}
+
+#-------------------------------------------------------------------------------
+sub swap
+#-------------------------------------------------------------------------------
+{
+ my ($S, $idx, $O) = @_;
+
+ my $N = length $S;
+ my $idx_l = $idx % $N;
+ my $idx_r = ($idx + $O) % $N;
+ my $chr_l = substr($S, $idx_l, 1);
+ my $chr_r = substr($S, $idx_r, 1);
+
+ substr($S, $idx_l, 1, $chr_r);
+ substr($S, $idx_r, 1, $chr_l);
+
+ print " swap: $idx: $chr_l <=> $chr_r = $S\n" if DISPLAY_SWAP;
+
+ return $S;
+}
+
+#-------------------------------------------------------------------------------
+sub parse_command_line
+#-------------------------------------------------------------------------------
+{
+ scalar @ARGV == 3 or die $USAGE;
+
+ my ($S, $C, $O) = @ARGV;
+ my $N = length $S;
+
+ $N > 0 or die $USAGE;
+
+ /\A$RE{num}{int}\z/ && $_ >= 1 or die $USAGE for $C, $O;
+
+ $C <= $O && ($C + $O) <= $N or die $USAGE;
+
+ return ($S, $C, $O);
+}
+
+################################################################################
diff --git a/challenge-070/athanasius/perl/ch-2.pl b/challenge-070/athanasius/perl/ch-2.pl
new file mode 100644
index 0000000000..8319f595ac
--- /dev/null
+++ b/challenge-070/athanasius/perl/ch-2.pl
@@ -0,0 +1,125 @@
+#!perl
+
+################################################################################
+=comment
+
+Perl Weekly Challenge 070
+=========================
+
+Task #2
+-------
+*Gray Code Sequence*
+
+*Submitted by:* Mohammad S Anwar
+
+You are given an integer 2 <= $N <= 5.
+
+Write a script to generate $N-bit
+[https://www.tutorialspoint.com/what-is-gray-code | gray code sequence].
+
+*2-bit Gray Code Sequence*
+
+ [0, 1, 3, 2]
+
+To generate the 3-bit Gray code sequence from the 2-bit Gray code sequence,
+follow the step below:
+
+ 2-bit Gray Code sequence
+ [0, 1, 3, 2]
+
+ Binary form of the sequence
+ a) S1 = [00, 01, 11, 10]
+
+ Reverse of S1
+ b) S2 = [10, 11, 01, 00]
+
+ Prefix all entries of S1 with '0'
+ c) S1 = [000, 001, 011, 010]
+
+ Prefix all entries of S2 with '1'
+ d) S2 = [110, 111, 101, 100]
+
+ Concatenate S1 and S2 gives 3-bit Gray Code sequence
+ e) [000, 001, 011, 010, 110, 111, 101, 100]
+
+ 3-bit Gray Code sequence
+ [0, 1, 3, 2, 6, 7, 5, 4]
+
+*Example*
+
+ Input: $N = 4
+
+ Output: [0, 1, 3, 2, 6, 7, 5, 4, 12, 13, 15, 14, 10, 11, 9, 8]
+
+=cut
+################################################################################
+
+#--------------------------------------#
+# Copyright © 2020 PerlMonk Athanasius #
+#--------------------------------------#
+
+use strict;
+use warnings;
+use Const::Fast;
+use Regexp::Common qw( number );
+
+const my @ONE_BIT_SEQ => (0, 1);
+const my $USAGE =>
+"Usage:
+ perl $0 <N>
+
+ <N> Number of bits: integer >= 2 and <= 5\n";
+
+#-------------------------------------------------------------------------------
+BEGIN
+#-------------------------------------------------------------------------------
+{
+ $| = 1;
+ print "\nChallenge 070, Task #2: Gray Code Sequence (Perl)\n\n";
+}
+
+#===============================================================================
+MAIN:
+#===============================================================================
+{
+ my $N = parse_command_line();
+
+ print "Input: \$N = $N\n\n";
+
+ # For the conversion from binary to decimal, see perlfaq4:
+ # "How do I convert between numeric representations/bases/radixes?"
+
+ my @gray_codes = map { oct "0b$_" } gray_codes_binary($N);
+
+ printf "Output: [%s]\n", join(', ', @gray_codes);
+}
+
+#-------------------------------------------------------------------------------
+sub gray_codes_binary
+#-------------------------------------------------------------------------------
+{
+ my ($N) = @_;
+ $N >= 1 or die "ERROR: Invalid argument $N, stopped";
+
+ return @ONE_BIT_SEQ if $N == 1; # Base case
+
+ my @seq = gray_codes_binary($N - 1); # Recursive call
+ my @s1 = map { "0$_" } @seq;
+ my @s2 = map { "1$_" } reverse @seq;
+
+ return (@s1, @s2); # Concatenate the arrays
+}
+
+#-------------------------------------------------------------------------------
+sub parse_command_line
+#-------------------------------------------------------------------------------
+{
+ scalar @ARGV == 1 or die $USAGE;
+
+ my ($N) = @ARGV;
+ $N =~ m[ \A $RE{num}{int} \z ]x && $N >= 2 && $N <= 5 or die $USAGE;
+
+ return $N;
+}
+
+################################################################################
diff --git a/challenge-070/athanasius/raku/ch-1.raku b/challenge-070/athanasius/raku/ch-1.raku
new file mode 100644
index 0000000000..e322267dbc
--- /dev/null
+++ b/challenge-070/athanasius/raku/ch-1.raku
@@ -0,0 +1,114 @@
+use v6d;
+
+################################################################################
+=begin comment
+
+Perl Weekly Challenge 070
+=========================
+
+Task #1
+-------
+*Character Swapping*
+
+*Submitted by:* Mohammad S Anwar
+
+You are given a string $S of size $N.
+
+You are also given swap count $C and offset $O such that $C >= 1, $O >= 1,
+$C <= $O and $C + $O <= $N.
+
+*UPDATE: 2020-07-20 16:10:00*
+*Pete Houston suggested to put additional constraint i.e. $C <= $O. He presented
+the use case $S = 'abcd', $C = 2, $O = 1.*
+
+Write a script to perform character swapping like below:
+
+ $S[ 1 % $N ] <=> $S[ (1 + $O) % $N ]
+ $S[ 2 % $N ] <=> $S[ (2 + $O) % $N ]
+ $S[ 3 % $N ] <=> $S[ (3 + $O) % $N ]
+ ...
+ ...
+ $S[ $C % $N ] <=> $S[ ($C + $O) % $N ]
+
+*Example 1*
+
+ Input:
+ $S = 'perlandraku'
+ $C = 3
+ $O = 4
+
+ Character Swapping:
+ swap 1: e <=> n = pnrlaedraku
+ swap 2: r <=> d = pndlaerraku
+ swap 3: l <=> r = pndraerlaku
+
+ Output:
+ pndraerlaku
+
+=end comment
+################################################################################
+
+#--------------------------------------#
+# Copyright © 2020 PerlMonk Athanasius #
+#--------------------------------------#
+
+my Bool constant DISPLAY-SWAP = True;
+
+#-------------------------------------------------------------------------------
+BEGIN
+#-------------------------------------------------------------------------------
+{
+ "\nChallenge 070, Task #1: Character Swapping (Raku)\n".put;
+}
+
+#===============================================================================
+sub MAIN
+(
+ Str:D $S where { $S.chars > 0 }, #= Non-empty string
+ UInt:D $C where { $C ≥ 1 }, #= Swap count: integer >= 1
+ UInt:D $O where { $O ≥ 1 && $C ≤ $O && #= Offset: integer >= 1 such that
+ $C + $O ≤ $S.chars } #= C <= O and C + O <= |S|
+)
+#===============================================================================
+{
+ "Input:\n \$S = '$S'\n \$C = $C\n \$O = $O\n".put;
+
+ 'Character Swapping:'.put if DISPLAY-SWAP;
+
+ my Str $s = $S;
+ $s = swap($s, $_, $O) for 1 .. $C;
+
+ ''.put if DISPLAY-SWAP;
+ "Output:\n $s".put;
+}
+
+#-------------------------------------------------------------------------------
+sub swap(Str:D $S, UInt:D $idx, UInt:D $O --> Str:D)
+#-------------------------------------------------------------------------------
+{
+ my UInt $N = $S.chars;
+ my UInt $idx-l = $idx % $N;
+ my UInt $idx-r = ($idx + $O) % $N;
+ my Str $chr-l = $S.substr: $idx-l, 1;
+ my Str $chr-r = $S.substr: $idx-r, 1;
+ my Str $new-s = $S;
+
+ $new-s.substr-rw($idx-l, 1) = $chr-r;
+ $new-s.substr-rw($idx-r, 1) = $chr-l;
+
+ " swap: $idx: $chr-l <=> $chr-r = $new-s".put if DISPLAY-SWAP;
+
+ return $new-s;
+}
+
+#-------------------------------------------------------------------------------
+sub USAGE()
+#-------------------------------------------------------------------------------
+{
+ my Str $usage = $*USAGE;
+
+ $usage ~~ s/ ($*PROGRAM-NAME) /raku $0/;
+ $usage.put;
+}
+
+################################################################################
diff --git a/challenge-070/athanasius/raku/ch-2.raku b/challenge-070/athanasius/raku/ch-2.raku
new file mode 100644
index 0000000000..42ede69d6e
--- /dev/null
+++ b/challenge-070/athanasius/raku/ch-2.raku
@@ -0,0 +1,113 @@
+use v6d;
+
+################################################################################
+=begin comment
+
+Perl Weekly Challenge 070
+=========================
+
+Task #2
+-------
+*Gray Code Sequence*
+
+*Submitted by:* Mohammad S Anwar
+
+You are given an integer 2 <= $N <= 5.
+
+Write a script to generate $N-bit
+[https://www.tutorialspoint.com/what-is-gray-code | gray code sequence].
+
+*2-bit Gray Code Sequence*
+
+ [0, 1, 3, 2]
+
+To generate the 3-bit Gray code sequence from the 2-bit Gray code sequence,
+follow the step below:
+
+ 2-bit Gray Code sequence
+ [0, 1, 3, 2]
+
+ Binary form of the sequence
+ a) S1 = [00, 01, 11, 10]
+
+ Reverse of S1
+ b) S2 = [10, 11, 01, 00]
+
+ Prefix all entries of S1 with '0'
+ c) S1 = [000, 001, 011, 010]
+
+ Prefix all entries of S2 with '1'
+ d) S2 = [110, 111, 101, 100]
+
+ Concatenate S1 and S2 gives 3-bit Gray Code sequence
+ e) [000, 001, 011, 010, 110, 111, 101, 100]
+
+ 3-bit Gray Code sequence
+ [0, 1, 3, 2, 6, 7, 5, 4]
+
+*Example*
+
+ Input: $N = 4
+
+ Output: [0, 1, 3, 2, 6, 7, 5, 4, 12, 13, 15, 14, 10, 11, 9, 8]
+
+=end comment
+################################################################################
+
+#--------------------------------------#
+# Copyright © 2020 PerlMonk Athanasius #
+#--------------------------------------#
+
+my Array[Str:D] constant ONE-BIT-SEQ = Array[Str:D].new: < 0 1 >;
+
+#-------------------------------------------------------------------------------
+BEGIN
+#-------------------------------------------------------------------------------
+{
+ "\nChallenge 070, Task #2: Gray Code Sequence (Raku)\n".put;
+}
+
+#===============================================================================
+sub MAIN
+(
+ UInt:D $N where { 2 ≤ $N ≤ 5 } #= Number of bits: integer >= 2 and <= 5
+)
+#===============================================================================
+{
+ "Input: \$N = $N\n".put;
+
+ my UInt @gray-codes = gray-codes-binary($N).map: { "0b$_".UInt };
+
+ "Output: [%s]\n".printf: @gray-codes.join: ', ';
+}
+
+#-------------------------------------------------------------------------------
+sub gray-codes-binary
+(
+ UInt:D $N where { $N >= 1 } #= Number of bits: integer >= 1
+--> Array:D[Str:D]
+)
+#-------------------------------------------------------------------------------
+{
+ return ONE-BIT-SEQ if $N == 1; # Base case
+
+ my Str @seq = gray-codes-binary($N - 1); # Recursive call
+ my Str @s1 = @seq .map: { "0$_" };
+ my Str @s2 = @seq.reverse.map: { "1$_" };
+
+ @s1.append: @s2; # Concatenate the arrays
+
+ return @s1;
+}
+
+#-------------------------------------------------------------------------------
+sub USAGE()
+#-------------------------------------------------------------------------------
+{
+ my Str $usage = $*USAGE;
+
+ $usage ~~ s/ ($*PROGRAM-NAME) /raku $0/;
+ $usage.put;
+}
+
+################################################################################