Peter
Peter Campbell Smith

Stealthy calculations

Weekly challenge 143 — 13 December 2021

Week 143 - 13 Dec 2021

Task 2

Task — 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.

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;
}

Output


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