Peter
Peter Campbell Smith

Big ones and jelmbud wrods

Weekly challenge 289 — 30 September 2024

Week 289: 30 Sep 2024

Task 1

Task — Third maximum

You are given an array of integers, @ints. Write a script to find the third distinct maximum in the given array. If third maximum doesn’t exist then return the maximum number.

It might be easier to understand this by substituting 'largest' for 'maximum'.

Examples


Example 1
Input: @ints = (5, 6, 4, 1)
Output: 4
The first distinct maximum is 6.
The second distinct maximum is 5.
The third distinct maximum is 4.

Example 2
Input: @ints = (4, 5)
Output: 5
In the given array, the third maximum doesn't exist 
therefore returns the maximum.

Example 3
Input: @ints =  (1, 2, 2, 3)
Output: 1
The first distinct maximum is 3.
The second distinct maximum is 2.
The third distinct maximum is 1.

Analysis

As always, my solution may not be the briefest, but I think it is easy to understand - and it works.

First I reverse sort @ints. Then I walk along @ints and:

  • If I haven't found the first largest yet, then this is it.
  • Else, if haven't found the 2nd largest, and this isn't the same as the first largest, then this is the second largest.
  • Else if I've found the second but not third, and this isn't the same as the second largest, then this is the third largest - and I'm finished.

The only thing left to do is to output the results if 3 largest have been found, or the maximum of 2 or just one.

Try it 

Try running the script with any input:



example: 4, 8, 7, 2, 9, 3, 9, 10

Script


#!/usr/bin/perl

# Blog: http://ccgi.campbellsmiths.force9.co.uk/challenge

use v5.26;    # The Weekly Challenge - 2024-09-30
use utf8;     # Week 289 - task 1 - Third maximum
use warnings; # Peter Campbell Smith
binmode STDOUT, ':utf8';

third_maximum(1, 2, 3, 4, 4, 5);
third_maximum(1, 2);
third_maximum(5);
third_maximum(7, 7, 7, 7, 7);

# make longer example
my @ints;
push @ints, int(rand(100)) 
for 0 .. 49;
third_maximum(@ints);

sub third_maximum {
    
    my (@ints, @max, $j);
    
    say qq[\nInput:  \@ints = (] . join(', ', @_) . ')';

    # reverse sort @ints
    @ints = reverse sort {$a <=> $b} @_;
    
    # use the stated rules to find the first three distinct numbers
    for $j (@ints) {
        if (not $max[1]) {
            $max[1] = $j;
        } elsif (not $max[2] and $j != $max[1]) {
            $max[2] = $j;
        } elsif (not $max[3] and $max[2] and $j != $max[2]) {
            $max[3] = $j;
            last;
        }
    }
    
    # output
    if ($max[3]) {
        say qq[Output: \$max1 = $max[1], \$max2 = $max[2], \$max3 = $max[3]];
    } else {
        say qq[Output: \$max = ] . ($max[2] ? ($max[2] > $max[1] ? $max[2] : $max[1]) : $max[1]);
    }
}

Output


Input:  @ints = (1, 2, 3, 4, 4, 5)
Output: $max1 = 5, $max2 = 4, $max3 = 3

Input:  @ints = (1, 2)
Output: $max = 2

Input:  @ints = (5)
Output: $max = 5

Input:  @ints = (7, 7, 7, 7, 7)
Output: $max = 7

Input:  @ints = (97, 64, 4, 39, 54, 68, 12, 81, 55, 96,
10, 41, 51, 85, 28, 84, 51, 47, 42, 72, 35, 62, 62, 24,
79, 58, 25, 98, 17, 16, 81, 70, 76, 69, 86, 18, 29, 64,
50, 94, 45, 97, 21, 51, 40, 58, 6, 80, 37, 97)
Output: $max1 = 98, $max2 = 97, $max3 = 96

 

Any content of this website which has been created by Peter Campbell Smith is in the public domain