Peter
Peter Campbell Smith

Members’ week

Weekly challenge 222 — 19 June 2023

Week 222 - 19 Jun 2023

Task 1

Task — Matching members

You are given a list of positive integers, @ints. Write a script to find the number of members that match between the original list and the list sorted in numerical order.

Analysis

I toyed with an ingenious one-liner, but as I wanted both to count the matches and list them I stuck with a boring loop:

for $j (0 .. scalar @list - 1) {
  next unless $list[$j] == $sorted[$j];
  $count ++;
}

Not very inspired, but it works.

Try it 

Example: 1, 1, 4, 2, 1, 3

Script


#!/usr/bin/perl

use v5.16;    # The Weekly Challenge - 2023-06-19
use utf8;     # Week 222 task 1 - Matching members
use strict;   # Peter Campbell Smith
use warnings; # Blog: http://ccgi.campbellsmiths.force9.co.uk/challenge

my ($j, @list);

matching_members(1, 1, 4, 2, 1, 3);
matching_members(5, 1, 2, 3, 4);
matching_members(1, 2, 3, 4, 5);

# longer example
for $j (0 .. 29) {
    $list[$j] = int(rand(25));
}
matching_members(@list);

sub matching_members {
    
    my (@list, @sorted, $j, $result, $count);
    
    # initialise
    @list = @_;
    @sorted = sort { $a <=> $b } @list;
    $result = '';
    $count = 0;
    
    # loop over list
    for $j (0 .. scalar @list - 1) {
        next unless $list[$j] == $sorted[$j];
        $result .=  qq[$list[$j], ];
        $count ++;
    }
    
    # display results
    say qq[\nInput:  \@ints   = (] . join(', ', @list) . q[)] .
        qq[\n        \@sorted = (] . join(', ', @sorted) . q[)];
    say qq[Output: ] . $count . ($count > 0 ? ' : ' . substr($result, 0, -2) : '');
}

Output


Input:  @ints   = (1, 1, 4, 2, 1, 3)
        @sorted = (1, 1, 1, 2, 3, 4)
Output: 3 : 1, 1, 2

Input:  @ints   = (5, 1, 2, 3, 4)
        @sorted = (1, 2, 3, 4, 5)
Output: 0

Input:  @ints   = (1, 2, 3, 4, 5)
        @sorted = (1, 2, 3, 4, 5)
Output: 5 : 1, 2, 3, 4, 5

Input:  @ints   = (20, 24, 21, 10, 3, 12, 9, 18, 21, 13, 0, 1, 12, 11, 4, 6, 16, 7, 24, 16, 16, 15, 21, 10, 19, 16, 13, 20, 24, 18)
        @sorted = (0, 1, 3, 4, 6, 7, 9, 10, 10, 11, 12, 12, 13, 13, 15, 16, 16, 16, 16, 18, 18, 19, 20, 20, 21, 21, 21, 24, 24, 24)
Output: 3 : 9, 16, 24