From d94c8c71d75dc10acea0be20f0d6d2c063d3c657 Mon Sep 17 00:00:00 2001 From: Mohammad S Anwar Date: Mon, 5 Apr 2021 01:52:15 +0100 Subject: - Added solutions by Colin Crain. --- challenge-106/colin-crain/perl/ch-1.pl | 61 +++++++++++++ challenge-106/colin-crain/perl/ch-2.pl | 149 +++++++++++++++++++++++++++++++ challenge-106/colin-crain/python/ch-1.py | 49 ++++++++++ challenge-106/colin-crain/raku/ch-1.raku | 47 ++++++++++ challenge-106/colin-crain/raku/ch-2.raku | 33 +++++++ 5 files changed, 339 insertions(+) create mode 100644 challenge-106/colin-crain/perl/ch-1.pl create mode 100644 challenge-106/colin-crain/perl/ch-2.pl create mode 100644 challenge-106/colin-crain/python/ch-1.py create mode 100644 challenge-106/colin-crain/raku/ch-1.raku create mode 100644 challenge-106/colin-crain/raku/ch-2.raku (limited to 'challenge-106') 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; + -- cgit