Peter’s blog ✴ Week 379 ✴ 22 June 2026

THE WEEKLY CHALLENGE
Reversing and curious numbers

The Perl Camel

Task 2

Armstrong number

You are given two integers, $base and $limit. Write a script to find all Armstrong numbers in base $base that are less than $limit.

If raising each of the digits of a non-negative integer to the power of the total number of digits, then taking their sum, equals the original number, it is an Armstrong number.

Examples


Example 1
Input: $base = 10, $limit = 1000
Output: (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 153, 370, 371, 407)

Example 2
Input: $base = 7, $limit = 1000
Output: (0, 1, 2, 3, 4, 5, 6, 10, 25, 32, 45, 133, 134, 152, 250)

Example 3
Input: $base = 16, $limit = 1000
Output: (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 342, 
   371, 520, 584, 645)

Analysis

Michael Armstrong
Michael Armstrong
1941-2020

Armstrong numbers were described by Michael Armstrong, an engineer and computer scientist at the University of Rochester.

So how do we compute them? To start with, although we are asked to handle numbers with a base which might not be 10, I note that the supplied $limit (and obviously $base), and the required answers are all expressed in base 10.

We do however need to convert some numbers into and out of base $base, and while I could have written a pair of subroutines to do that I found Math::Int2Base, which does so very compactly, and have used that.

The key statement in my solution is:

$sum += base2int(substr($jb, $_, 1), $base) ** $power

Here, $jb is the number under test ($j) expressed in base $base. So for example, if $j == 10 and $base == 7 then $jb == 13. The loop variable, $_, runs from zero to one less than the length of $jb, and $power is the number of characters in $jb.

And if the sum of powers as above equals $j we have found an Armstrong number. They are relatively rare, although notably there are often a pair which differ by 1, and 0 to $base - 1 are always included.

Try it 

Your input:



eg: 9 - max 62 please



eg: 1200 - max 10_000 please

Script


#!/usr/bin/perl

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

use v5.26;    # The Weekly Challenge - 2026-06-22
use utf8;     # Week 379 - task 2 - Armstrong number
use warnings; # Peter Campbell Smith
binmode STDOUT, ':utf8';
use Encode;
use Math::Int2Base ('int2base', 'base2int');

armstrong_number(10, 10000);
armstrong_number(7, 1000);
armstrong_number(16, 1000);
armstrong_number(9, 1000);

sub armstrong_number {
    
    my ($base, $limit, $j, $jb, $power, $sum, $output);
    
    # initialise
    ($base, $limit) = @_;
    
    # loop over possibles
    for $j (0 .. $limit) {
        
        # get digits of $j in base $base and count them
        $jb = int2base($j, $base);
        $power = length($jb);
        
        # now sum digits ** $power
        $sum = 0;
        $sum += base2int(substr($jb, $_, 1), $base) ** $power 
            for 0 .. $power - 1;
        
        # found one!
        $output .= qq[$j, ] if $sum == $j;
    }
    
    say qq[\nInput:  \$base = $base, \$limit = $limit];
    say qq[Output: ] . substr($output, 0, -2);
}

12 lines of code

Output from script


Input:  $base = 10, $limit = 10000
Output: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 153, 370, 371, 407, 1634, 8208,
   9474

Input:  $base = 7, $limit = 1000
Output: 0, 1, 2, 3, 4, 5, 6, 10, 25, 32, 45, 133, 134, 152, 250

Input:  $base = 16, $limit = 1000
Output: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 342,
   371, 520, 584, 645

Input:  $base = 9, $limit = 1000
Output: 0, 1, 2, 3, 4, 5, 6, 7, 8, 41, 50, 126, 127, 468, 469

 

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