Peter’s blog ✴ Week 143 ✴ 13 December 2021

THE WEEKLY CHALLENGE
Stealthy calculations

The Perl Camel

Task 2

Stealthy number

You are given a positive number, $n. Write a script to find out if the given number is a Stealthy Number. A positive integer $n is stealthy if there exist positive integers $a, $b, $c, $d such that

$a * $b = $c * $d = $n and $a + $b = $c + $d + 1

Examples


Example 1
Input: $n = 36
Output: 1
Since 36 = 4 (a) * 9 (b) = 6 (c) * 6 (d) and 
   4 (a) + 9 (b) = 6 (c) + 6 (d) + 1.

Example 2
Input: $n = 12
Output: 1
Since 2 * 6 = 3 * 4 and 2 + 6 = 3 + 4 + 1

Example 3
Input: $n = 6
Output: 0
Since 2 * 3 = 1 * 6 but 2 + 3 != 1 + 6 + 1

Analysis

From the given equations we can deduce:

$a * $b = $c * $d = $n
∴ $b = $n / $a and $d = $c / $n

$a + $b = $c + $d + 1
∴ $a + $n / $a = $c + $n / $c + 1 --- (1)

So for any $n let's first find all its pairs of divisors as potential values for $a and $c. Happily we can use Math::Prime::Util qw(divisors) and use Algorithm::Combinatorics qw(variations) to do that.

Since we are looking for unique pairs of $a and $c we can restrict both to values no more than sqrt($n), ie where $a <= $b and
$c <= $d.

Now all we need to do is see if equality (1) above is true, and if it is, $n is stealthy.

The stealthy numbers less than 100 are: 4, 12, 24, 36, 40, 60, 72 and 84. Looking further ahead it appears likely that there is an infinite number of such numbers.

Some stealthy numbers have more than one solution for $a + $b = $c + $d + 1, for example:

$n = 7200
72 + 100 = 75 + 96 + 1
75 +  96 = 80 + 90 + 1

$n = 2520
35 + 72 = 36 + 70 + 1
40 + 63 = 42 + 60 + 1
42 + 60 = 45 + 56 + 1

All stealthy numbers are multiples of 4. The reason is this:

Consider $a + $b = $c + $d + 1.

Clearly either $a + $b or $c + $d must be an odd number, since they differ by 1. If $a is odd, $b must be even (so that $a + $b is odd), and $c and $d must either be both odd or both even (so that $c + $d is even).

But we can rule out $c and $d being both odd, because $c * $d would then be odd and $a * $b would be even, so they cannot both equal $n as is required.

So, of $a, $b, $c and $d, one must be odd and the other 3 must be even. We know that $n = $a * $b = $c * $d, and either $a * $b or $c * $d is the product of two even numbers - two multiples of 2 - so $n must be a multiple of 4.

I am sorry that the 'Try it' feature is currently working very slowly or not at all owing to some issue with my web hosting provider.

Try it 

Try running the script with any input:



example: 7200

Script


#!/usr/bin/perl

# Peter Campbell Smith - 2021-12-13
# PWC 143 task 2

use v5.20;
use warnings;
use strict;

use Math::Prime::Util qw(divisors);
use Algorithm::Combinatorics qw(variations);

my ($n, @tests, @divisors, $variations, $v, $a, $c, $good, $half);

# inputs
@tests = (36, 12, 6, 22, 23, 24, 8424, 7200, 4);

for $n (@tests) {
    $good = 0;
    
    # get all the divisors of $n and all the variations of 2 of them
    @divisors = divisors($n);
    $variations = variations(\@divisors, 2);
    
    # check to see if any of these
    $half = sqrt($n);
    while ($v = $variations->next) {        
        ($a, $c) = @$v;
        
        # they need both to be less than sqrt(n)
        next unless ($a <= $half and $c <= $half);
        
        # and test them for stealth
        if ($a + $n / $a == $c + $n / $c + 1) {
            say qq[\nInput:  $n\nOutput: 1] if $good == 0;
            say qq[$a + ] . ($n / $a) . qq[ == $c + ] . ($n / $c) . qq[ + 1];
            $good ++;
        }
    }
    say qq[\nInput:  $test\nOutput: 0] unless $good;
}

20 lines of code

Output from script


Input:  36
Output: 1
4 + 9 == 6 + 6 + 1

Input:  12
Output: 1
2 + 6 == 3 + 4 + 1

Input:  6
Output: 0

Input:  22
Output: 0

Input:  23
Output: 0

Input:  24
Output: 1
3 + 8 == 4 + 6 + 1

Input:  8424
Output: 1
78 + 108 == 81 + 104 + 1

Input:  7200
Output: 1
72 + 100 == 75 + 96 + 1
75 + 96 == 80 + 90 + 1

Input:  4
Output: 1
1 + 4 == 2 + 2 + 1

 

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