How To write an Armstrong number checker

Hello there, and for those of you who have read my previous work, welcome back.

Now, what is an Armstrong number:

“In recreational number theory, a narcissistic number (also known as a pluperfect digital invariant (PPDI), an Armstrong number (after Michael F. Armstrong) or a plus perfect number) is a number that is the sum of its own digits each raised to the power of the number of digits.” – wikipedia

So in layman terms, a three digit number abc is narcisistic if a^3 + b^3 + c^3 = abc.

Before we go through the code let’s analyze what we need to do. We need a number to check, we need to find out how many digits it has, we need to raise each individual digit to the power of how many digits there are, add them up and check to see if it’s equal to the original number.

So down below you will see a little script that checks if a number is an armstrong number or not. After we will go through the code line by line to understand what each bit of code does what.

class Armstrong

  def check_user_number
    puts "Enter any number for check: "
    user_input = gets.chomp.to_i
    is_narcissistic?(user_input)
  end

  private

  def is_narcissistic?(user_input)
    all_digits = user_input.to_s.chars.map(&:to_i)
    number_of_digits = all_digits.count
    raised_to_power = all_digits.map {|a| a ** number_of_digits}
    if raised_to_power.inject(0) {|sum, x| sum + x} == user_input
      puts "your number #{user_input} is a narcissistic number"
    else
      puts "it's not a narcissistic number"
    end
  end
end

Armstrong.new.check_user_number

Now we have one class and just 2 methods inside it. The first method is pretty straight forward and doesn’t need to much explaining. It just greets the user, asks for an input, takes that input, turns it into an integer  and passes it to the is_narcissistic? method to be checked.

So in essence the first method – which is public – holds the interface, and the second method – which is private – holds the business logic.

Now onto the second method.

def is_narcissistic?(user_input)
    all_digits = user_input.to_s.chars.map(&:to_i)
    number_of_digits = all_digits.count

The first line of code just take the user input and turns it into an array of integers corresponding to the digits of the number. so for example 153 will be turned into [1, 5, 3] and saves that array into the variable “all_digits” because we will use that later on.

The second line of code counts the number of digits inside the array and saves that in a variable called “number_of_digits” because we will need this number to be able to raise to power the individual digits inside the “all_digits” array.

The third line of code:

raised_to_power = all_digits.map {|a| a ** number_of_digits}

This line of code maps over the array “all_digits” and raises each and every one of them to the power of the “number_of_digits” and saves that inside the “raised_to_power” variable.

The last five lines of code does the check against the original number

if raised_to_power.inject(0) {|sum, x| sum + x} == user_input
  puts "your number #{user_input} is a narcissistic number"
else
  puts "it's not a narcissistic number"
end

It does this with a simple if/else statement in which it checks if the sum of the “raised_to_power” digits is equal to the original “user_input” in which case it prints a statement that tells the user that it truly is a narcissistic number or a statement that it’s not.

And that is all there is too it. Now, do you think you could write up a new program that uses the above code to find out all the narcissistic numbers in a range of, let’s say [1..999] ?

Have a great week!

0 comments… add one

Leave a Comment