No friends among the champions
Weekly challenge 343 — 13 October 2025
Week 343: 13 Oct 2025
You are given a list of numbers. Find the number that is closest to zero and return its distance to zero.
Example 1 Input: @nums = (4, 2, -1, 3, -2) Output: 1 Values closest to 0: -1 and 2 (distance = 1 and 2) Example 2 Input: @nums = (-5, 5, -3, 3, -1, 1) Output: 1 Values closest to 0: -1 and 1 (distance = 1) Example 3 Input: @ums = (7, -3, 0, 2, -8) Output: 0 Values closest to 0: 0 (distance = 0) Exact zero wins regardless of other close values. Example 4 Input: @nums = (-2, -5, -1, -8) Output: 1 Values closest to 0: -1 and -2 (distance = 1 and 2) Example 5 Input: @nums = (-2, 2, -4, 4, -1, 1) Output: 1 Values closest to 0: -1 and 1 (distance = 1)
As is often the case, there is a choice between a concise solution and the most efficient one. I've gone for conciseness this time.
My solution is to sort the given array by absolute value, for which Perl conveniently provides:
my @x = sort {abs($a) <=> abs($b)} @_;
The answer is then simply abs($x[0])
.
Perl has an efficient sort operation, so this is pretty fast even for a long array: I tried 1000 numbers and it completed in under a second. However, for a very long array it would probably be quicker to do a single pass along the array, comparing the absolute value of each element against the smallest seen so far.
I noted that the array was stated to be of 'numbers' rather than integers, and you will see from my tests that it also works for floating point numbers.
#!/usr/bin/perl # Blog: http://ccgi.campbellsmiths.force9.co.uk/challenge use v5.26; # The Weekly Challenge - 2025-10-13 use utf8; # Week 343 - task 1 - Zero friend use warnings; # Peter Campbell Smith binmode STDOUT, ':utf8'; use Encode; zero_friend(4, 2, -1, 3, -2); zero_friend(-5, 5, -3, 3, -1, 1); zero_friend(7, -3, 0, 2, -8); zero_friend(71.6, -93.4, 102.102, -1000, 41.2, -70.9, 999, 4e6, -1e-3); # bigger example my @ints; push @ints, (int(rand(1e6) - 5e5)) / 1e3 for 0 .. 49; zero_friend(@ints); sub zero_friend { # sort by absolute values my @x = sort {abs($a) <=> abs($b)} @_; say qq[\nInput: ] . join(', ', @_); say qq[Output: ] . abs($x[0]); }
Input: 4, 2, -1, 3, -2 Output: 1 Input: -5, 5, -3, 3, -1, 1 Output: 1 Input: 7, -3, 0, 2, -8 Output: 0 Input: 71.6, -93.4, 102.102, -1000, 41.2, -70.9, 999, 4000000, -0.001 Output: 0.001 Input: -478.251, 211.44, 382.593, 23.986, 175.974, 120.869, 77.025, 452.896, -138.822, -127.616, -199.365, 169.603, 216.2, -294.691, -479.728, 491.744, -325.153, -214.099, -377.572, 61.443, -492.841, -273.27, -349.304, 115.779, 425.666, 127.48, -363.688, 452.505, 454.606, 301.836, -289.928, 404.138, -107.246, 155.597, 192.101, 412.444, 466.311, 460.197, -377.281, 481.047, -281.096, 165.08, -342.416, -255.452, 451.143, -431.013, -458.835, 136.978, -439.602, 47.112 Output: 23.986
Any content of this website which has been created by Peter Campbell Smith is in the public domain