Peter’s blog ✴ Week 290 ✴ 7 October 2024

THE WEEKLY CHALLENGE
Double existence and checking the payload

The Perl Camel

Task 1

Double exist

You are given an array of integers, @ints. Write a script to find if there exist two indices $i and $j such that:

  1. $i != $j
  2. 0 <= ($i, $j) < scalar @ints
  3. $ints[$i] == 2 * $ints[$j]

Examples


Example 1
Input: @ints = (6, 2, 3, 3)
Output: true
For $i = 0, $j = 2
$ints[$i] = 6 => 2 * 3 =>  2 * $ints[$j]

Example 2
Input: @ints = (3, 1, 4, 13)
Output: false

Example 3
Input: @ints = (2, 1, 4, 2)
Output: true
For $i = 2, $j = 3
$ints[$i] = 4 => 2 * 2 =>  2 * $ints[$j]

Analysis

This is another one where ther is probably a one-liner, but I chose to write something a little more verbose;

First I create %exists such that $exists[$j] exists if $j occurs in @ints.

Then I simply loop through @ints checking whether
$exists{$j * 2} exists.

Note that since $i != $j is a requirement, I have to explicitly exclude the case where 0 appears in @ints.

Perl Weekly’s review

from PW issue 690

A verbose approach to make it easy to read and follow. DIY tool is the icing on the cake. Well done.

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

Try it 

Try running the script with any input:



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

Script


#!/usr/bin/perl

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

use v5.26;    # The Weekly Challenge - 2024-10-07
use utf8;     # Week 290 - task 1 - Double exist
use warnings; # Peter Campbell Smith
binmode STDOUT, ':utf8';

double_exist(6, 2, 3, 3);
double_exist(3, 1, 4, 13);
double_exist(2, 1, 4, 2);
double_exist(0, 0, 14, 7, -4, -8);

# bigger example
my @ints;
push @ints, int(rand(100)) for (0 .. 19);
double_exist(@ints);

sub double_exist {
    
    my (@ints, %exists, $explain, $j);
    
    # initialise
    @ints = @_;
    $exists{$_} = 1 for @ints;
    
    # find compliant pairs
    for $j (@ints) {
        $explain .= qq[$j and ] . ($j * 2) . ', ' if ($j != 0 and $exists{2 * $j});
    }
    
    # show results
    say qq[\nInput:  \@ints = (] . join(', ', @ints) . ')';
    say qq[Output: ] . ($explain ? (qq[true - ] . substr($explain, 0, -2)) : 'false');
}

8 lines of code

Output from script


Input:  @ints = (6, 2, 3, 3)
Output: true - 3 and 6, 3 and 6

Input:  @ints = (3, 1, 4, 13)
Output: false

Input:  @ints = (2, 1, 4, 2)
Output: true - 2 and 4, 1 and 2, 2 and 4

Input:  @ints = (0, 0, 14, 7, -4, -8)
Output: true - 7 and 14, -4 and -8

Input:  @ints = (91, 65, 35, 7, 61, 20, 40, 4, 73, 89, 84, 30, 13, 31,
   74, 67, 4, 62, 91, 1)
Output: true - 20 and 40, 31 and 62

 

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