Camel
Peter
Peter Campbell Smith

A middling deal

Weekly challenge 291 — 14 October 2024

Week 291: 14 Oct 2024

Task 1

Task — Middle index

You are given an array of integers, @ints. Write a script to find the leftmost middle index (MI), ie the smallest amongst all the possible ones. A middle index is an index where:

ints[0] + ints[1] + … + ints[MI-1] == 
   ints[MI+1] + ints[MI+2] + … + ints[ints.length-1]

If MI == 0, the left side sum is considered to be 0. Similarly, if
MI == ints.length - 1, the right side sum is considered to be 0.

Return the leftmost MI that satisfies the condition, or -1 if there is no such index.

Examples


Example 1
Input: @ints = (2, 3, -1, 8, 4)
Output: 3
The sum of the numbers before index 3 is: 2 + 3 + -1 = 4
The sum of the numbers after index 3 is: 4 = 4

Example 2
Input: @ints = (1, -1, 4)
Output: 2
The sum of the numbers before index 2 is: 1 + -1 = 0
The sum of the numbers after index 2 is: 0

Example 3
Input: @ints = (2, 5)
Output: -1
There is no valid MI.

Analysis

My solution consists of maintaining two pots, $before, initially zero, and $after, initially equal to the sum of all the values in @ints.

I then, for $i (0 .. scalar(@ints) - 1):

  • subtract $ints[$i] from $after
  • if $before == $after then this is an MI, so report and stop.
  • Or else add $ints[$i] to $before and continue

... and if no MI has been found then there isn't one.

I don't know what this says about my thought processes or my ability to write correct code, but I think this is the first challenge for which my code compiled and ran correctly for all the normal and edge cases, at the very first attempt!

Try it 

Script


#!/usr/bin/perl

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

use v5.26;    # The Weekly Challenge - 2024-10-14
use utf8;     # Week 291 - task 1 - Middle index
use warnings; # Peter Campbell Smith
binmode STDOUT, ':utf8';

middle_index(2, 3, -1, 8, 4);
middle_index(0, 3, 4, -7);
middle_index(3, 4, -7, 0);
middle_index(1, 2, 3, 4, 5);
middle_index(9, 9, 9, 9, 9);

sub middle_index {
    
    my (@ints, $before, $after, $i);
    
    @ints = @_;
    say qq[\nInput:  \@ints = (] . join(', ', @ints) . ')';
    
    # initialise
    $before = 0;
    $after += $_ for @ints;
    
    # loop over elements of @ints to find first MI
    for $i (0 .. scalar @ints - 1) {
        
        # remove $ints[$i] from $after
        $after -= $ints[$i];
        
        # do we have an MI?
        if ($before == $after) {
            say qq[Output: $i];
            return;
        }
        
        # add $ints[$i] to before, and try the next $i
        $before += $ints[$i];
    }
    
    # no MI found
    say qq[Output: -1];
}

Output


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

Input:  @ints = (0, 3, 4, -7)
Output: 0

Input:  @ints = (3, 4, -7, 0)
Output: 3

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

Input:  @ints = (9, 9, 9, 9, 9)
Output: 2

 

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