Weekly Challenge 351
Each week Mohammad S. Anwar sends out The Weekly Challenge, a chance for all of us to come up with solutions to two weekly tasks. My solutions are written in Python first, and then converted to Perl. It's a great way for us all to practice some coding.
Task 1: Special Average
Task
You are given an array of integers.
Write a script to return the average excluding the minimum and maximum of the given array.
My solution
This task doesn't require much explanation. I start by calculating the min_value and max_value. I then have a list (array in Perl) called short_list which has the original integers with any min_value or max_value values removed.
If the short_list is empty, I return 0. Otherwise I return the average ( sum ÷ length ) of the short list.
def special_average(ints: list) -> float:
min_value = min(ints)
max_value = max(ints)
short_list = [n for n in ints if n != min_value and n != max_value]
if not short_list:
return 0
return sum(short_list)/len(short_list)
The Perl solution has the same logic, and uses the grep function to remove values.
sub main (@ints) {
my $min_value = min(@ints);
my $max_value = max(@ints);
my @short_array = grep { $_ != $min_value && $_ != $max_value } @ints;
if ($#short_array == -1) {
say 0;
}
say sum(@short_array) / scalar(@short_array);
}
Examples
$ ./ch-1.py 8000 5000 6000 2000 3000 7000
5250.0
$ ./ch-1.py 100000 80000 110000 90000
95000.0
$ ./ch-1.py 2500 2500 2500 2500
0
$ ./ch-1.py 2000
0
$ ./ch-1.py 1000 2000 3000 4000 5000 6000
3500.0
Task 2: Arithmetic Progression
Task
You are given an array of numbers.
Write a script to return true if the given array can be re-arranged to form an arithmetic progression, otherwise return false.
A sequence of numbers is called an arithmetic progression if the difference between any two consecutive elements is the same.
My solution
This task might throw up some gotchas by some less experience developers. Experienced developers should know that 0.1 + 0.2 is not 0.3. The reason for this is explained in this Python web page.
$ python3
Python 3.13.9 (main, Oct 14 2025, 00:00:00) [GCC 15.2.1 20250808 (Red Hat 15.2.1-1)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> 0.1 + 0.2
0.30000000000000004
Therefore the inputs to this function need to be either integers or of the Decimal type. With that out of the way, these are the steps I take
- Create a
sorted_listlist (array in Perl) which has the values sorted numerically (smallest first). - Create a variable
diffthat is the difference between the first two values (i.e.sorted_ints[1] - sorted_ints[0]). - Have a loop called
iwhich stats with 2 to one less than the length of the list. For each iteration, I check the difference between the number at that position and the previous one is the same asdiff. If it isn't, I returnFalse. - Once the loop is exhausted, I return
True.
def arithmetic_progression(ints: list) -> bool:
sorted_ints = sorted(ints)
diff = sorted_ints[1] - sorted_ints[0]
for i in range(2, len(sorted_ints)):
if sorted_ints[i] - sorted_ints[i - 1] != diff:
return False
return True
Perl also uses the same floating point arithmetic, and thus has the same issue. Perl has the Math::BigFloat function to handle this. The Perl solution uses the same logic, and converts the values to BigFloat before doing the computations.
sub main (@ints) {
my @sorted_ints = map { Math::BigFloat->new($_) } sort { $a <=> $b } @ints;
my $diff = $sorted_ints[1] - $sorted_ints[0];
foreach my $i ( 2 .. $#sorted_ints ) {
if ( $sorted_ints[$i] - $sorted_ints[ $i - 1 ] != $diff ) {
say 'false';
return;
}
}
say 'true';
}
Examples
$ ./ch-2.py 1 3 5 7 9
True
$ ./ch-2.py 9 1 7 5 3
True
$ ./ch-2.py 1 2 4 8 16
False
$ ./ch-2.py 5 -1 3 1 -3
True
$ ./ch-2.py 1.5 3 0 4.5 6
True
$ ./ch-2.py 0.1 0.3 0.2 0.4
True
Top comments (0)