I've been a zone leader with DZone since 2008, and I'm crazy about community. Every day I get to work with the best that JavaScript, HTML5, Android and iOS has to offer, creating apps that truly make at difference, as principal front-end architect at Avego. James is a DZone Zone Leader and has posted 639 posts at DZone. You can read more from them at their website. View Full User Profile

Thursday Code Puzzler: Is This An Armstrong Number?

02.14.2013
| 4964 views |
  • submit to reddit

Thursday is code puzzler day here at DZone. The idea is simple: solve the coding problem as efficiently as you can, in any language or framework that you find suitable.

Note: Even though there really is nothing stopping you from finding a solution to this on the internet, try to keep honest, and come up with your own answer.  It's all about the participation!

Do you have code puzzlers that you'd like to share with the DZone community?  If so, please submit here. 

Determine if a given number is an Armstrong number

Write a method that will return true if the number passed through as a parameter is an Armstrong number, as defined in Wikipedia . Numbers satisfy this condition if the number is a sum of it's own digits, each raised to the power of the number of digits.

For example, 153 has 3 digits, so everything is raised to the power of 3.
153 = 1 to the power of 3 + 5 to the power of 3 + 3 to the power of 3

Given a single linked list, write a method that will determine if the "next" pointer of one of the nodes is pointing to a previous node in your list.

Catch up on all our previous puzzlers here.

Comments

Thierry Bodhuin replied on Thu, 2013/02/14 - 6:09am

    // Determine if a given number is an Armstrong number , Java Code
public static boolean isArmstrong(int n) {
        int rmd, s = 0, tmp = n;
        int p, l=n;
        for (p = 0; l > 0; ++p) {
            l /= 10;
        }
        while (tmp != 0) {
            rmd = tmp % 10;
            int pow = 1;
            for (int i = 1; i <= p; i++) {
                pow *= rmd;
            }
            s = s + pow;
            tmp = tmp / 10;
        }
        return (n == s);
    }

Thierry Bodhuin replied on Thu, 2013/02/14 - 6:13am

    public static boolean isArmstrong(int n) {
        int rmd, s = 0, tmp = n;
        int p, l=n;
        for (p = 0; l > 0; ++p) {
            l /= 10;
        }
        while (tmp != 0) {
            rmd = tmp % 10;
            int pow = 1;
            for (int i = 1; i <= p; i++) {
                pow *= rmd;
            }
            s = s + pow;
            tmp = tmp / 10;
        }
        return (n == s);
    }

Mark Howard replied on Thu, 2013/02/14 - 7:41am

I hope I have the right idea of the problem, I did the following in Java

I got the following working from 0 - 500: 0,1,2,3,4,5,6,7,8,9,153,370,371,407. When searching Google for Armstrong numbers between 0 - 500 I get mixed answers!

public static boolean isArmstrong(int nNumber){
		// Convert the number to a char array.
		char[] sNumber = String.valueOf(nNumber).toCharArray();
		
		// Holds the result.
		double result=0;
		double nTotal = (double)sNumber.length;
		
		for(int i=0; i<sNumber.length;i++){
			double nThisNumber = (double)Character.getNumericValue(sNumber[i]);
			System.out.println("Sum should be "+nThisNumber+"^"+nTotal);
			int temp = (int)Math.pow(nThisNumber, nTotal);
			result = result+temp;
		}
		
		System.out.println("Main number: "+String.valueOf(sNumber));
		System.out.println("Total result number: "+String.valueOf((int)result));
		
		/* Compare the result against the number passed in, if they match then the number 
		 * is an Anderson number and we return true.
		 */
		if((int)result==nNumber){
			System.out.println("This is an Anderson number");
			return true;
		}
		System.out.println("Numbers are not equal");
		return false;
	}

Vijay Nathani replied on Thu, 2013/02/14 - 8:44am

Groovy

def isArmstrong(number) {
	def (numberOfDigits, powerSum) = [Math.ceil(Math.log10(number)), 0.0]
	for (long n=number; n!=0; n/=10) 
		powerSum += Math.pow(n%10,numberOfDigits)
	number == powerSum.longValue()
}
assert isArmstrong(153) 
assert !isArmstrong(154) 

sun east replied on Thu, 2013/02/14 - 9:26am

 Here is my codes by scala:

def isArmstrong(n: Int): Boolean = {
  val num = n.toString.map(_.asDigit)
  n == num.map(math.pow(_,num.size)).sum
}


And test:

scala> def test(start: Int, end: Int): (Long, Seq[Int]) = {
  |  val begin = System.currentTimeMillis
  |  val arms = (start to end).filter(isArmstrong)
  |  val used = System.currentTimeMillis - begin
  |  (used, arms)
  | }
test: (start: Int, end: Int)(Long, Seq[Int])

scala> test(0, 1000000)
res0: (Long, Seq[Int]) = (2403,Vector(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 153, 370, 371, 407, 1634, 8208, 9474, 54748, 92727, 93084, 548834))

scala> test(0, 10000000)
res1: (Long, Seq[Int]) = (27519,Vector(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 153, 370, 371, 407, 1634, 8208, 9474, 54748, 92727, 93084, 548834, 1741725, 4210818, 9800817, 9926315))

Thierry Bodhuin replied on Thu, 2013/02/14 - 9:41am in response to: Thierry Bodhuin

The code has been done in order to avoid Java API dependency. The first loop is used for computing the number of digits for "n" (String.valueof(n).length() for this). The inner "for" loop inside the while loop is used for computing the power of rmd to p (rmd^p) (Maybe used Math.pow for this).

Thierry Bodhuin replied on Thu, 2013/02/14 - 9:43am in response to: Thierry Bodhuin

The code has been done in order to avoid Java API dependency. The first loop is used for computing the number of digits for "n" (String.valueof(n).length() for this). The inner "for" loop inside the while loop is used for computing the power of rmd to p (rmd^p) (Maybe used Math.pow for this).

Jorge Riquelme replied on Thu, 2013/02/14 - 10:36am

A c# version:

		static bool IsArmstrongNumber(int number) {
			double[] res = new double[2]; //sum and pow
			Func<int, double[]> f = null;
			f = delegate(int value) {
				res[1]++;
				if(value < 10) {
					res[0] += Math.Pow(value, res[1]);
					return res;
				} else {
					double p = f(value / 10)[1];
					res[0] += Math.Pow(value % 10, p);
					return res; 
				}
			};
			return f(number)[0] == number;
		}

Jorge Riquelme replied on Thu, 2013/02/14 - 10:43am

And a shorter (just a bit) implementation following the same idea of sun east scala version :)

		static bool IsArmstrongNumber(int number) {
			var sz = number.ToString();
			return number == sz.Sum(c => Math.Pow(Convert.ToDouble(c.ToString()), sz.Length));
		}

Laurent Petiet replied on Thu, 2013/02/14 - 10:49am

For php4 / php5 
function isArmstrongNumber($number = null){
	$resultat = false;

	if( ! function_exists('cube')){
		function cube($n)
		{
		    return($n * $n * $n);
		}
	}

	$output = array();

	preg_match_all('#\d#',$number, $output);

	if(isset($output) && is_array($output) &&  1 == count($output)){
		$tab_cube = array_map("cube", $output[0]);
		$cube_sum = array_sum($tab_cube);

		if( $number === $cube_sum){
			$resultat = true;
		}
	}

	return $resultat;
}

Sree Das replied on Thu, 2013/02/14 - 12:53pm

public class ArmstrongFinder {
    
    public boolean isArmstrong(String num){
        
        int length = num.length();
        int actualNum = Integer.valueOf(num);
        int result = 0;
        for(int i =0 ;i<length;i++){
            int digit;
            digit = Character.getNumericValue(num.charAt(i));
            result = (int) (result+Math.pow(digit, length));
        }
        return result == actualNum;
    }
    
    public static void main(String args[]){
        ArmstrongFinder f = new ArmstrongFinder();
            System.out.println("153 is armstrong :"+f.isArmstrong("153"));
            System.out.println("371 is armstrong :"+f.isArmstrong("371"));
            System.out.println("407 is armstrong :"+f.isArmstrong("407"));
            System.out.println("234 is armstrong :"+f.isArmstrong("234"));
    }
}

 

ebenezer raj replied on Thu, 2013/02/14 - 12:53pm

in q:

{x=last sums {("F"$y) xexp x}[count string x; ] each string x}[153]

prints 1

Ajinkya Vaze replied on Fri, 2013/02/15 - 5:47am

private boolean isArmstrong(Integer number) {
String numString = number.toString();
int power = numString.length();
int canBeArmstrong = 0;
for (int i = 0; i < numString.length(); i++) {
int digit = Integer.parseInt(String.valueOf(numString.charAt(i)));
canBeArmstrong += Math.pow(digit, power);
}
return canBeArmstrong == number.intValue();
}

Per Trangbæk replied on Fri, 2013/02/15 - 1:59am

And now for something completely different:

identification division.
program-id.               armstro.
data division.
working-storage section.
01 i              pic 9(4) binary.
01 pow            pic 9(4) binary.
01 digit          pic 9(4) binary.
01 tmp-res        pic 9(15) binary.
01 num-9          pic 9(15)
01 f              pic 9(4) binary.
linkage section.
01 num            pic 9(15) binary.
01 result         pic 9(15)
   88 amstrong    value zero.
procedure division using num result.
    move num to num-9
    move zero to tmp-r
    perform varying f from 1 by 1 
	  until f > length of num-9 or num-9(f:1) not = 0
       continue
    end-perform
    compute
       pow = length of num-9 - f + 1
    end-compute
    perform varying i from f by 1 until i > length of num-9
       move num-9(i:1) to digit
       compute
          tmp-res = tmp-res + digit ** pow
       end-compute
    end-perform
    subtract num from tmp-res giving result
    goback.
end program armstro.

Remigio Di Muzio replied on Fri, 2013/02/15 - 5:25am

    public boolean isArmstrong(int n) {
        int m = 0;
        int r = n;
        int x;
        
        while (r > 0) {
            x = r % 10;
            m += x * x * x;
            r /= 10;
        }
        return m == n;
    }

Thierry Bodhuin replied on Fri, 2013/02/15 - 8:12am in response to: Remigio Di Muzio

This is valid only for 3 digits numbers, not valid for other nubers.

Thierry Bodhuin replied on Fri, 2013/02/15 - 8:12am in response to: Remigio Di Muzio

This is valid only for 3 digits numbers, not valid for other numbers.

Remigio Di Muzio replied on Wed, 2013/02/20 - 10:14am in response to: Thierry Bodhuin

You're right, I've read it hastily and misunderstood.

This is my proposal:

public boolean isArmstrong(int n) {
    int m = 0;
    int r = n;
    int x;
    int e = 0;
    
    while (r > 0) {
        ++e;
        r /= 10;
    }
    r = n;
    while (r > 0) {
        x = r % 10;
        m += Math.pow(x, e);
        r /= 10;
    }
    return m == n;
}

Ada Ahmed replied on Wed, 2013/02/20 - 11:40am

 

Perl command line:

perl -e 'print eval join "+", map{$_**length $ARGV[0]} split //, $ARGV[0]' 153

Prints 153

or sth. like this:

perl -e 'exit ((eval join "+", map{$_**length $ARGV[0]} split //, $ARGV[0]) != $ARGV[0])' 407
exits with 0, non armstrong numbers exit with 1

Chris Hartman replied on Wed, 2013/02/20 - 12:46pm

C++11, optimized for readability/understandability:


#include <iostream>
#include <string>
using std::string;
using std::to_string;
#include <cmath>

unsigned long numericValue(char c);
unsigned long sumOfPowers(string digits, std::size_t power);

bool isArmstrongNumber(unsigned long number)
{
    string numberAsString=to_string(number);
    auto power=numberAsString.length();
    auto armstrongValue=sumOfPowers(numberAsString,power);
    return armstrongValue==number;
}

unsigned long sumOfPowers(string digits, unsigned long power)
{
    unsigned long total = 0;
    for(char digit:digits)
        total += pow(numericValue(digit),power);
    return total;
}

unsigned long numericValue(char c)
{
    return c-'0';
}

Ryan Horch replied on Wed, 2013/02/20 - 3:09pm

C  

#include <stdlib.h>

int IsArmstrong(int number)
{
        int t = 0;
        int r = number;
        int * digits;
        int p = 0;
        digits = malloc(1);
        while (r > 0)
        {
                digits = realloc(digits,p+1);
                digits[p++] = r % 10;
                r /= 10;
        }
        int i, j;
        for(i = 0; i < p; i++)
        {
                int x = digits[i];
                for(j = 1; j < p; j++)
                {
                        x *= digits[i];
                }
                t += x;
        }
        return t == number;
}

Ryan Horch replied on Wed, 2013/02/20 - 3:11pm

C++ 

#include <vector>

int IsArmstrong(unsigned int number)
{
	int t = 0;
    int r = number;
	std::vector<int> digits;
	int p = 0;
	while (r > 0)
	{
		digits.resize(p + 1);
		digits[p++] = r % 10;
		r /= 10;
	}
	for(int i = 0; i < p; i++)
	{
		int x = digits[i];
		for(int j = 1; j < p; j++)
		{
			x *= digits[i];
		}
		t += x;
	}
	return t == number;
}

Daniel Sobral replied on Wed, 2013/02/20 - 5:32pm

Functional programming ftw.

def armstrong(n: Int) = {
  val s = n.toString
  s.map(c => List.fill(s.size)(c.asDigit).product).sum == n
}

Daniel Sobral replied on Wed, 2013/02/20 - 5:33pm in response to: Per Trangbæk

How do I upvote this? :-)

Bob Beechey replied on Wed, 2013/02/20 - 6:39pm

Easy to understand Python function that accepts input of any type

def is_armstrong(num):
    numstr = str(num)
    armstrong = False
    if numstr.isdigit():
        power = len(numstr)
        calcnum = 0
        for eachdigit in numstr:
            calcnum += int(eachdigit) ** power
        armstrong = calcnum == int(numstr)
    return armstrong

Chris Hartman replied on Wed, 2013/02/20 - 8:01pm in response to: Ryan Horch

Why not just digits.push_back(r%10); instead of the clumsy "digits.resize(p+1); digits[p++] = r%10;" ? (And use digits.size() instead of p in the next for loop, too.)

Sennen Ekouaghe replied on Thu, 2013/02/21 - 3:53pm

public class ArmstrongNumberChecker {
    public static boolean isAnArmstrongNumber(int number) {
        int absNumber = Math.abs(number);
        return isAnArmstrongNumber(absNumber, absNumber, 0);
    }
    private static boolean isAnArmstrongNumber(int originalNumber, int number, int sum) {
        int firstDigit = getFirstDigit(number);
        int newSum = sum + (int) Math.pow(firstDigit, 3);
        int numberOfDigits = getNumberOfDigits(number);
        if(numberOfDigits == 1) {
            return newSum == originalNumber;
        }
        if(newSum > originalNumber) {
            return false;
        }
        int newNumber = number - (int)(firstDigit * Math.pow(10, numberOfDigits - 1));
        return isAnArmstrongNumber(originalNumber, newNumber, newSum);
    }
    static int getFirstDigit(int number) {
        int numberOfDigitsMinus1 = getNumberOfDigits(number) - 1;
        return numberOfDigitsMinus1 == 0 ? number :
               (int) (number / Math.pow(10, numberOfDigitsMinus1));
    }
    static int getNumberOfDigits(int number) {
        return number == 0 ? 1 : (int) Math.log10(Math.abs(number)) + 1;
    }
}

Camilo Rivera replied on Thu, 2013/11/07 - 12:26am

A little Ruby. The first solution takes advantage of Ruby features, the second one has some performance improvements:

def armstrong(num)
	nums = num.to_s
	num == nums.split(//).map{|s| s.to_i}.reduce{|sum,n| sum+n**nums.length}
end

def armstrong2(num)
	nums, sum = num.to_s, 0
	nums.split(//).map{|s| s.to_i}.each{|n| if sum>num then return false end; sum=sum+n**nums.length }
	num == sum
end

puts "Armstrong? #{armstrong(153)}, #{armstrong2(153)}"

Haroon Ghafoori replied on Thu, 2013/11/21 - 1:31am

  public boolean isArmstrongNumber(int number) {
  char[] digits = String.valueOf(number).toCharArray();
  int numberOfDigits = digits.length;
  int powerSum = 0;
  for(char digit : digits){
  powerSum += Math.pow(Integer.valueOf(digit), numberOfDigits);
  }
  return (number == powerSum);
  }

 

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.