Peter
Peter Campbell Smith

Special and unique numbers

Weekly challenge 252 — 15 January 2024

Week 252 - 15 Jan 2024

Task 1

Task — Special numbers

You are given an array of integers, @ints. Write a script to find the sum of the squares of all special elements of the given array.

An element $int[i] of @ints is called special if i divides n, i.e. n % i == 0 where n is the length of the given array. Also the array is 1-indexed for the task.

Examples


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

There are exactly 3 special elements in the given array:
$ints[1] since 1 divides 4,
$ints[2] since 2 divides 4, and
$ints[4] since 4 divides 4.

Hence, the sum of the squares of all special elements of 
given array:
1 * 1 + 2 * 2 + 4 * 4 = 21.

Example 2
Input: @ints = (2, 7, 1, 19, 18, 3)
Output: 63

There are exactly 4 special elements in the given array:
$ints[1] since 1 divides 6,
$ints[2] since 2 divides 6,
$ints[3] since 3 divides 6, and
$ints[6] since 6 divides 6.

Hence, the sum of the squares of all special elements of 
given array:
2 * 2 + 7 * 7 + 1 * 1 + 3 * 3 = 63

Analysis

This is just a case of passing once along the array, accumulating the square of the values on the elements whose indices (1-based) are factors of the array length.

Note that the first and last elements are always special so we never have the case of there being no special numbers.

Try it 

Try running the script with any input:



example: 1, 4, 7, 10, 13

Script


#!/usr/bin/perl

use v5.26;    # The Weekly Challenge - 2024-01-15
use utf8;     # Week 252 task 1 - Special numbers
use strict;   # Peter Campbell Smith
use warnings; # Blog: http://ccgi.campbellsmiths.force9.co.uk/challenge
binmode STDOUT, ':utf8';

my ($j, @ints);

special_numbers(1, 2, 3, 4);
special_numbers(2, 7, 1, 19, 18, 3);
special_numbers(7, 7, 7, 7, 11);

for $j (0 .. 31) {
    push @ints, int(rand(20) + 1);
}
special_numbers(@ints);

sub special_numbers {
    
    my (@ints, $j, $squares, @specials, $last);
    
    # initialise
    @ints = @_;
    $last = @ints - 1;
    
    # check each member
    for $j (0 .. $last) {
        if (($last + 1) / ($j + 1) == int(($last + 1) / ($j + 1))) {
            $squares += $ints[$j] ** 2;
            push @specials, $j + 1;
        }
    }
    
    # show results
    say qq[\nInput:  \@ints = (] . join(', ', @ints) . ')';
    say qq[Output: $squares ∵ \@specials: ] . join(', ', @specials);
}

Output


Input:  @ints = (1, 2, 3, 4)
Output: 21 ∵ @specials: 1, 2, 4

Input:  @ints = (2, 7, 1, 19, 18, 3)
Output: 63 ∵ @specials: 1, 2, 3, 6

Input:  @ints = (7, 7, 7, 7, 11)
Output: 170 ∵ @specials: 1, 5

Input:  @ints = (12, 18, 4, 5, 4, 20, 16, 3, 16, 20, 1, 9, 4, 15, 19, 16, 10, 18, 17, 2, 12, 16, 15, 19, 8, 19, 12, 9, 11, 18, 11, 13)
Output: 927 ∵ @specials: 1, 2, 4, 8, 16, 32