Peter
Peter Campbell Smith

Special and frequent numbers

Weekly challenge 195 — 12 December 2022

Week 195 - 12 Dec 2022

Task 2

Task — Most frequent even

You are given a list of numbers, @list. Write a script to find most frequent even number in the list. In case you get more than one, then return the smallest. For all other cases, return -1.

Examples


Input: @list = (1,1,2,6,2)
Output: 2 as there are only 2 even numbers 2 and 6 and 
  of those 2 appears the most.

Example 2
Input: @list = (1,3,5,7)
Output: -1 since no even numbers found in the list

Example 3
Input: @list = (6,4,4,6,1)
Output: 4 since there are only two even numbers 4 and 6. 
  They both appears the equal number of times, so pick 
  the smallest.

Analysis

Let's sort the list and then pass down it, ignoring odd numbers and incrementing $freq[$j] when we see an even $j.

As we do that, we keep a $max_freq to keep track of the maximum frequency seen, and $max_freq_no being the first (ie least) number that occurs with that frequency.

Try it 

Try running the script with any input:



example: 1, 2, 2, 3, 4, 4, 4, 5, 6, 6, 6, 6

Script


#!/usr/bin/perl

# Peter Campbell Smith - 2022-12-12
# PWC 195 task 2

use v5.28;
use utf8;
use warnings;

my (@tests, $test, @freq, $max_freq, $max_freq_no, $j, @list);

@tests = ([1,1,2,6,2], [1,3,5,7], [6,4,4,6,1], 
    [8, 8, 6, 6, 4, 4, 2, 2], [1, 2, 2, 4, 4, 4], [8, 6, 8, 6, 8, 6, 8]);

# loop over tests
for $test (@tests) {
    
    # initialise
    $max_freq = 0;
    $max_freq_no = -1;
    @freq = ();
    
    # look at each member of input list, sorted numerically so that we see the smallest first
    for $j (sort {$a <=> $b} @$test) {
        
        # ignore it if it is odd
        next if $j & 1;
        
        # increment its frequency
        $freq[$j] ++;
        
        # if more that the highest seen so far, remember it
        if ($freq[$j] > $max_freq) {
            $max_freq = $freq[$j];
            $max_freq_no = $j;
        }
    }
    
    # and show the result
    say qq[\nInput:  \@list = (] . join(', ', @$test) . qq[)];
    say qq[Output: $max_freq_no ] . ($max_freq > 0 ? qq[($max_freq times)] : '');

}

Output


Input:  @list = (1, 1, 2, 6, 2)
Output: 2 (2 times)

Input:  @list = (1, 3, 5, 7)
Output: -1

Input:  @list = (6, 4, 4, 6, 1)
Output: 4 (2 times)

Input:  @list = (8, 8, 6, 6, 4, 4, 2, 2)
Output: 2 (2 times)

Input:  @list = (1, 2, 2, 4, 4, 4)
Output: 4 (3 times)

Input:  @list = (8, 6, 8, 6, 8, 6, 8)
Output: 8 (4 times)