aboutsummaryrefslogtreecommitdiff
path: root/challenge-106
diff options
context:
space:
mode:
authorMohammad S Anwar <mohammad.anwar@yahoo.com>2021-04-05 01:52:15 +0100
committerMohammad S Anwar <mohammad.anwar@yahoo.com>2021-04-05 01:52:15 +0100
commitd94c8c71d75dc10acea0be20f0d6d2c063d3c657 (patch)
tree62b68099c62a3556ffab5e51adc43a06d984bc5f /challenge-106
parent72e42f65a2da702d8f836bd6dca80de3ccdfc33b (diff)
downloadperlweeklychallenge-club-d94c8c71d75dc10acea0be20f0d6d2c063d3c657.tar.gz
perlweeklychallenge-club-d94c8c71d75dc10acea0be20f0d6d2c063d3c657.tar.bz2
perlweeklychallenge-club-d94c8c71d75dc10acea0be20f0d6d2c063d3c657.zip
- Added solutions by Colin Crain.
Diffstat (limited to 'challenge-106')
-rw-r--r--challenge-106/colin-crain/perl/ch-1.pl61
-rw-r--r--challenge-106/colin-crain/perl/ch-2.pl149
-rw-r--r--challenge-106/colin-crain/python/ch-1.py49
-rw-r--r--challenge-106/colin-crain/raku/ch-1.raku47
-rw-r--r--challenge-106/colin-crain/raku/ch-2.raku33
5 files changed, 339 insertions, 0 deletions
diff --git a/challenge-106/colin-crain/perl/ch-1.pl b/challenge-106/colin-crain/perl/ch-1.pl
new file mode 100644
index 0000000000..5d1c9918da
--- /dev/null
+++ b/challenge-106/colin-crain/perl/ch-1.pl
@@ -0,0 +1,61 @@
+#! /opt/local/bin/perl
+#
+# max-gap.pl
+#
+# TASK #1 › Maximum Gap
+# Submitted by: Mohammad S Anwar
+# You are given an array of integers @N.
+#
+# Write a script to display the maximum difference between two successive
+# elements once the array is sorted.
+#
+# If the array contains only 1 element then display 0.
+#
+# Example
+#
+# Input: @N = (2, 9, 3, 5)
+# Output: 4
+#
+# Input: @N = (1, 3, 8, 2, 0)
+# Output: 5
+#
+# Input: @N = (5)
+# Output: 0
+#
+# © 2021 colin crain
+## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ##
+
+
+
+use warnings;
+use strict;
+use feature ":5.26";
+use feature qw(signatures);
+no warnings 'experimental::signatures';
+use List::Util qw(reduce max);
+
+my @input = (2, 19, 13, 15);
+
+my $gap = 0;
+
+## version 1 - reduce
+sub gap_reduce (@list) {
+ my $gap = 0;
+ reduce { $gap = $b - $a if $b - $a > $gap; $b } sort {$a<=>$b} @list;
+ return $gap;
+}
+
+say gap_reduce(@input);
+
+
+## version 2 - map over indices
+sub gap_map (@list) {
+ @list = sort {$a<=>$b} @list;
+
+ my $gap = max (map { $list[$_] - $list[$_-1] } (1..$#list));
+ return $gap;
+}
+
+say gap_map(@input);
+
+
diff --git a/challenge-106/colin-crain/perl/ch-2.pl b/challenge-106/colin-crain/perl/ch-2.pl
new file mode 100644
index 0000000000..955ee0fc23
--- /dev/null
+++ b/challenge-106/colin-crain/perl/ch-2.pl
@@ -0,0 +1,149 @@
+#! /opt/local/bin/perl
+#
+# reptend.pl
+#
+# TASK #2 › Decimal String
+# Submitted by: Mohammad S Anwar
+# You are given numerator and denominator i.e. $N and $D.
+#
+# Write a script to convert the fraction into decimal string. If the fractional part is recurring then put it in parenthesis.
+#
+# Example
+# Input: $N = 1, $D = 3
+# Output: "0.(3)"
+#
+# Input: $N = 1, $D = 2
+# Output: "0.5"
+#
+# Input: $N = 5, $D = 66
+# Output: "0.0(75)"
+#
+# method:
+# break down standard long-division algorithm into successive steps
+# of Euclidean Division
+# (https://en.wikipedia.org/wiki/Euclidean_division) until adding
+# additional 0s causes the new incremental digits of the quotient to
+# repeat.
+#
+# When evaluating each index position for the quotient in the
+# division, check the remainder being evaluated against a lookup hash
+# of previously seen remainders. If it is found we are repeating and
+# the current position and the position saved in the lookup
+# determine the start and end indices of the repeating segment. If a
+# lookup fails, add the remainder at that moment and the current
+# position to the lookup.
+#
+# © 2021 colin crain
+## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ##
+
+
+
+use warnings;
+use strict;
+use feature ":5.26";
+use feature qw(signatures);
+no warnings 'experimental::signatures';
+
+sub get_decimal_string ($num, $den) {
+ ## fraction is numerator over denominator
+ ## division is dividend over divisor yielding integer quotient and remainder
+ ## we'll keep to num and den as they make better variable names
+
+ ## extract the whole-number portion of the quotient in one step
+ ## and start the decimal portion with the remainder
+ my ($whole, $r) = ediv( $num, $den );
+
+ my $pos = 0;
+ my %seen;
+ my @q;
+
+ while ($r != 0) {
+
+ ## add one 0 to remainder
+ ## add remainder at every index position to %seen hash
+ $r .= 0;
+ exists $seen{$r} ? last : ($seen{$r} = $pos);
+
+ ## add additional 0s to remainder and quotient until num > den
+ ## with each 0 increment index position and add to seen hash
+ until ($r - $den >= 0) {
+ $pos++;
+ $r .= 0;
+ exists $seen{$r} ? last : ($seen{$r} = $pos);
+ push @q, 0;
+ }
+
+ ## the long division step
+ my $q;
+ ($q, $r) = ediv($r, $den);
+ push @q => $q;
+
+ $pos++;
+ }
+
+ my $out;
+
+ ## OUTPUT
+ ## three cases:
+ ## * whole number, no decimal
+ ## * isolate and present repeating fraction in parens
+ ## * finishes neatly, join with decimal point
+ if (@q == 0) {
+ $out = $whole;
+ }
+ elsif ($r) {
+ my $start = $seen{$r};
+ my $end = $pos-1;
+ my @pre = @q[0..$start-1];
+ my @rep = @q[$start..$end];
+ $out = join '', $whole, '.', @pre, '(', @rep, ')';
+ }
+ else {
+ $out = join '', ($whole, '.', @q);
+ }
+}
+
+sub ediv ( $num, $den ) {
+## Euclidean division of $num by $den returns quotient and remainder
+ (int( $num / $den ), $num % $den);
+}
+
+
+
+use Test::More;
+is get_decimal_string(2,1), "2", '2/1';
+is get_decimal_string(2,2), "1", '2/2';
+
+is get_decimal_string(1,2), "0.5", '1/2';
+is get_decimal_string(1,3), "0.(3)", '1/3';
+is get_decimal_string(1,4), "0.25", '1/4';
+is get_decimal_string(1,5), "0.2", '1/5';
+is get_decimal_string(1,6), "0.1(6)", '1/6';
+is get_decimal_string(1,7), "0.(142857)", '1/7';
+is get_decimal_string(1,8), "0.125", '1/8';
+is get_decimal_string(1,9), "0.(1)", '1/9';
+
+is get_decimal_string(1,10), "0.1", '1/10';
+is get_decimal_string(1,11), "0.(09)", '1/11';
+is get_decimal_string(1,12), "0.08(3)", '1/12';
+is get_decimal_string(1,13), "0.(076923)", '1/13';
+is get_decimal_string(1,14), "0.0(714285)", '1/14';
+is get_decimal_string(1,15), "0.0(6)", '1/15';
+is get_decimal_string(1,16), "0.0625", '1/16';
+is get_decimal_string(1,17), "0.(0588235294117647)", '1/17';
+is get_decimal_string(1,18), "0.0(5)", '1/18';
+is get_decimal_string(1,19), "0.(052631578947368421)", '1/19';
+is get_decimal_string(1,20), "0.05", '1/20';
+is get_decimal_string(1,21), "0.(047619)", '1/21';
+is get_decimal_string(1,22), "0.0(45)", '1/22';
+is get_decimal_string(1,23), "0.(0434782608695652173913)", '1/23';
+is get_decimal_string(1,24), "0.041(6)", '1/24';
+is get_decimal_string(1,25), "0.04", '1/25';
+
+is get_decimal_string(1,100), "0.01", '1/100';
+is get_decimal_string(1,101), "0.(0099)", '1/101';
+is get_decimal_string(1,102), "0.0(0980392156862745)", '1/102';
+is get_decimal_string(1,103), "0.(0097087378640776699029126213592233)", '1/103';
+
+
+done_testing();
diff --git a/challenge-106/colin-crain/python/ch-1.py b/challenge-106/colin-crain/python/ch-1.py
new file mode 100644
index 0000000000..2018d64960
--- /dev/null
+++ b/challenge-106/colin-crain/python/ch-1.py
@@ -0,0 +1,49 @@
+#!/usr/bin/env python3
+#
+#
+# max-gap.py
+#
+# TASK #1 › Maximum Gap
+# Submitted by: Mohammad S Anwar
+# You are given an array of integers @N.
+#
+# Write a script to display the maximum difference between two successive
+# elements once the array is sorted.
+#
+# If the array contains only 1 element then display 0.
+#
+# Example
+#
+# Input: @N = (2, 9, 3, 5)
+# Output: 4
+#
+# Input: @N = (1, 3, 8, 2, 0)
+# Output: 5
+#
+# Input: @N = (5)
+# Output: 0
+#
+#
+# © 2021 colin crain
+## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ##
+
+
+
+import sys
+
+def gapIndexed( list ):
+ list = sorted(list)
+ i = 1
+ gap = 0
+ while i < len(list):
+ gap = max( gap, int(list[i]) - int(list[i-1]) )
+ i += 1
+ return gap
+
+input = sys.argv[1:]
+print( "input array: ", input )
+gap = gapIndexed( input );
+print( "maximum gap: ", gap )
+
+
+
diff --git a/challenge-106/colin-crain/raku/ch-1.raku b/challenge-106/colin-crain/raku/ch-1.raku
new file mode 100644
index 0000000000..8672064456
--- /dev/null
+++ b/challenge-106/colin-crain/raku/ch-1.raku
@@ -0,0 +1,47 @@
+#!/usr/bin/env perl6
+#
+#
+# max-gap.raku
+#
+# TASK #1 › Maximum Gap
+# Submitted by: Mohammad S Anwar
+# You are given an array of integers @N.
+#
+# Write a script to display the maximum difference between two successive
+# elements once the array is sorted.
+#
+# If the array contains only 1 element then display 0.
+#
+# Example
+#
+# Input: @N = (2, 9, 3, 5)
+# Output: 4
+#
+# Input: @N = (1, 3, 8, 2, 0)
+# Output: 5
+#
+# Input: @N = (5)
+# Output: 0
+#
+#
+# © 2021 colin crain
+## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ##
+
+use Test;
+
+is max-gap(2,9,14,5) , 5, 'last';
+is max-gap(2,19,13,15), 11, '1st';
+is max-gap(22,19,13,15), 4, 'mid';
+
+
+sub max-gap ( *@input ) {
+ my $gap;
+ @input.sort
+ .reduce: {$gap = max( $^b-$^a, $gap); $b} ;
+ return $gap;
+}
+
+
+
+
+
diff --git a/challenge-106/colin-crain/raku/ch-2.raku b/challenge-106/colin-crain/raku/ch-2.raku
new file mode 100644
index 0000000000..1981876745
--- /dev/null
+++ b/challenge-106/colin-crain/raku/ch-2.raku
@@ -0,0 +1,33 @@
+#!/usr/bin/env perl6
+#
+#
+# reptend.raku
+#
+# TASK #2 › Decimal String
+# Submitted by: Mohammad S Anwar
+# You are given numerator and denominator i.e. $N and $D.
+#
+# Write a script to convert the fraction into decimal string. If the fractional part is recurring then put it in parenthesis.
+#
+# Example
+# Input: $N = 1, $D = 3
+# Output: "0.(3)"
+#
+# Input: $N = 1, $D = 2
+# Output: "0.5"
+#
+# Input: $N = 5, $D = 66
+# Output: "0.0(75)"
+#
+#
+#
+# © 2021 colin crain
+## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ##
+
+
+
+unit sub MAIN (Int $num = 1, Int $den = 24) ;
+
+my ($real, $reptend) = ($num/$den).base-repeating(10);
+printf '%s(%s)', $real, $reptend;
+