Perl Weekly Challenge 106.

My solutions (task 1 and task 2) to the The Weekly Challenge - 106.

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

I just order the list, substract the shifted ordered list and choose the maximum.

# Perl weekly challenge 106
# Task 1: Maximum gap
#
# See https://wlmb.github.io/2021/03/29/PWC106/#task-1-maximum-gap

use strict;
use warnings;
use v5.12;
use List::Util qw(reduce);

my @sorted=sort {$a<=>$b} @ARGV;
say +(reduce {$b>$a?$b:$a} map {$sorted[$_+1]-$sorted[$_]} 0..$#sorted-1)//0,
    join ' ', '<-(', @ARGV, ')',

Examples:

./ch-1.pl 2 9 3 5
./ch-1.pl 1 3 8 2 0
./ch-1.pl 5

Results:

4<-( 2 9 3 5 )
5<-( 1 3 8 2 0 )
0<-( 5 )

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)”

Each digit of the decimal expansion is the integer part of the remainder times the base (10) divided by the denominator. If I come back to the same remainder, the sequence repeats itself. So I build a hash of all seen remainders, storing their corresponding place in the digital expansion. If I see that remainder again, then the digits from its previous appearance to the current position repeat forever. If I reach a zero remainder, the expansion simply stops.

# Perl weekly challenge 106
# Task 2: Decimal String
#
# See https://wlmb.github.io/2021/03/29/PWC106/#task-2-decimal-string
use strict;
use warnings;
use v5.12;
use integer;
use List::Util qw(all);
use POSIX qw(floor);

my ($numerator, $denominator)= @ARGV;
die "Usage: ./ch-2.pl numerator denominator"
    unless defined $numerator and defined $denominator;
# I assume positive integer numbers.
my $integer=$numerator/$denominator;
my $rest=$numerator%$denominator;
my %seen;
my $start=0;
my @digits;
while($rest && !defined $seen{$rest}){
    $seen{$rest}=$start++;
    push @digits, (10*$rest)/$denominator;
    $rest=(10*$rest)%$denominator;
}
$seen{0}=$start;
my $result=join '', "$integer.", @digits[0..$seen{$rest}-1];
$result.=join '', '(', @digits[$seen{$rest}..$#digits], ')' if $rest!=0;
say "$numerator/$denominator=$result";

Examples:

./ch-2.pl 1 3
./ch-2.pl 1 2
./ch-2.pl 5 66

./ch-2.pl 1 6
./ch-2.pl 1 81

Results:

1/3=0.(3)
1/2=0.5
5/66=0.0(75)

1/6=0.1(6)
1/81=0.(012345679)
Written on March 29, 2021