Peter’s blog ✴ Week 276 ✴ 1 July 2024

THE WEEKLY CHALLENGE
Round days and frequent numbers

The Perl Camel

Task 1

Complete day

You are given an array of integers, @hours. Write a script to return the number of pairs that forms a complete day. A complete day is defined as a time duration that is an exact multiple of 24 hours.

Examples


Example 1
Input: @hours = (12, 12, 30, 24, 24)
Output: 2
Pair 1: (12, 12)
Pair 2: (24, 24)

Example 2
Input: @hours = (72, 48, 24, 5)
Output: 3
Pair 1: (72, 48)
Pair 2: (72, 24)
Pair 3: (48, 24)

Example 3
Input: @hours = (12, 18, 24)
Output: 0

Analysis

The obvious way to do this is simply two nested loops covering all possible pairs and checking whether they sum to a multiple of 24, so that's what I did.

Even with 1000 random integers - so half a million possible pairs - it takes under a second on my machine to find the 20847 qualifying pairs.

Perl Weekly’s review

from PW issue 676

I noticed the use of v5.26 and few other bits. I am sure it would work with the latest release too (v5.40). Well done.

This review may cover either or both challenges for this week.

Try it 

Try running the script with any input:



example: 9, 10, 11, 12, 13, 14, 15

Script


#!/usr/bin/perl

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

use v5.26;    # The Weekly Challenge - 2024-07-01
use utf8;     # Week 276 - task 1 - Complete day
use warnings; # Peter Campbell Smith
binmode STDOUT, ':utf8';

my (@hours);

complete_day(12, 12, 30, 24, 24);
complete_day(72, 48, 24, 5);
complete_day(12, 18, 24);

push @hours, int(rand(30)) for 0 .. 24;
complete_day(@hours);

sub complete_day {
    
    my (@hours, $pairs, $a, $b, $days, $explain);
    
    @hours = @_;
    
    # loop over all pairs
    $pairs = 0;
    $explain = '';
    for $a (0 .. @hours - 2) {
        for $b ($a + 1 .. @hours - 1) {
            
            # determine if this pair sums to a whole number of days
            $days = ($hours[$a] + $hours[$b]) / 24; 
            next unless (int($days) == $days);
            $pairs ++;
            $explain .= qq[($hours[$a] + $hours[$b]), ];
        }
    }
    printf(qq[\nInput:  \@hours = (%s)\n], join(', ', @hours));
    printf(qq[Output: %s: %s\n], $pairs, substr($explain, 0, -2));
}

13 lines of code

Output from script


Input:  @hours = (12, 12, 30, 24, 24)
Output: 2: (12 + 12), (24 + 24)

Input:  @hours = (72, 48, 24, 5)
Output: 3: (72 + 48), (72 + 24), (48 + 24)

Input:  @hours = (12, 18, 24)
Output: 0:

Input:  @hours = (27, 1, 23, 21, 16, 14, 25, 25, 2, 22, 
  11, 25, 14, 8, 0, 13, 17, 14, 6, 17, 13, 15, 5, 25, 12)
Output: 10: (27 + 21), (1 + 23), (23 + 25), (23 + 25), 
  (23 + 25), (23 + 25), (16 + 8), (2 + 22), (11 + 13), 
  (11 + 13)

 

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