Printing Armstrong numbers from 1 to 500. (C Programming)

ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices

Welcome to LinuxQuestions.org, a friendly and active Linux Community.

You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!

Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.

If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.

Having a problem logging in? Please visit this page to clear all LQ-related cookies.

Introduction to Linux - A Hands on Guide

This guide was created as an overview of the Linux Operating System, geared toward new users as an exploration tour and getting started guide, with exercises at the end of each chapter.
For more advanced trainees it can be a desktop reference, and a collection of the base knowledge needed to proceed with system and network administration. This book contains many real life examples derived from the author's experience as a Linux system and network administrator, trainer and consultant. They hope these examples will help you to get a better understanding of the Linux system and that you feel encouraged to try out things on your own.

Click Here to receive this Complete Guide absolutely free.

This is very interesting (really). but according to everything I've read the only way to determine Narcissistic Numbers (of which Armstrong Numbers are just a subset of three-digit numbers) is by brute force, i.e. testing each number to see if it is one. Even if your algorithm works, how can you make sure that you've found all of the Narcissistic numbers within a range?

That's right. There is some probability that you will find each Armstrong number, but you don't know what the probabilities are.

As an example, in 1 hour, my Python implementation was able to find 3 of the 5 Armstrong numbers of 23-digits. After another 5 hours, it had found one more. I have no idea how long it would take to find the last one. If I didn't know that there are only 5, I wouldn't have any way of knowing when the search is completed.

It's just a mathematical curiosity and a small programming challenge.

I'm sorry, but that is incorrect. The leading zeroes cannot be taken into account, they modify the "length", the number of digits. The valid result is:

It's just a mathematical curiosity and a small programming challenge.

Yes. It's totally dependent on the base , and not any sort of real mathematical property. That's why I think there's no real way to calculate them other than brute force.

@Beryllos -- You really don't have to explicitly free() all that memory before you quit, when the process ends, the kernel will clean it up for you. You only have to free() memory that you malloc() when you're running a program that continues to run indefinitely and you want that memory back.

Thanks. I know there is a system garbage collector that takes care of this, but without knowing the details, I thought maybe it's faster to free the memory explicitly at the application level. The benefit, if any, is probably insignificant.

Here is another idea ... if we look at the 1000 numbers with 3 digit combinations, there are only 220 effective combinations that need to be tested as all others are repeats, as per Beryllos' example
of 145, 154, 415, 451, 514, and 541 all yielding the same solution.

The nice thing on working from this direction is the growth of numbers to be tested as the power increases is considerably less than the total number added:

Code:

10 ^ 3 = 220 to test
10 ^ 4 = 715 to test
10 ^ 5 = 2002 to test
10 ^ 6 = 5005 to test
10 ^ 7 = 11440 to test

Of course the problem with the above scenario is trying to come up with what numbers are in the shortlist to be checked against.
As an idea, I tried this in Ruby and just getting the number above took ages, as you can see I never got to 8 or 9

Great idea. I don't have a clear idea how to generate the sequence. It's the sequence of unique n-digit numbers with sorted digits. I'm thinking a recursive approach might work. I'll try to get back to that later.

Thanks. I know there is a system garbage collector that takes care of this, but without knowing the details, I thought maybe it's faster to free the memory explicitly at the application level. The benefit, if any, is probably insignificant.

Sorry I didn't mean to criticize you, it probably looks better to do it that way anyway, I was just commenting. But when your program quits, the kernel has to do a lot to get rid of your process's resources and a few malloc'ed data variables really are insignificant, so I'd bet it's actually slower to do it and then just quit. But again it probably looks nicer.

Sorry I didn't mean to criticize you, it probably looks better to do it that way anyway, I was just commenting. But when your program quits, the kernel has to do a lot to get rid of your process's resources and a few malloc'ed data variables really are insignificant, so I'd bet it's actually slower to do it and then just quit. But again it probably looks nicer.

No worries. Just don't criticize my style of using braces!

Here is another idea ... if we look at the 1000 numbers with 3 digit combinations, there are only 220 effective combinations that need to be tested as all others are repeats, as per Beryllos' example
of 145, 154, 415, 451, 514, and 541 all yielding the same solution.

The nice thing on working from this direction is the growth of numbers to be tested as the power increases is considerably less than the total number added:

Code:

10 ^ 3 = 220 to test
10 ^ 4 = 715 to test
10 ^ 5 = 2002 to test
10 ^ 6 = 5005 to test
10 ^ 7 = 11440 to test

Of course the problem with the above scenario is trying to come up with what numbers are in the shortlist to be checked against.
As an idea, I tried this in Ruby and just getting the number above took ages, as you can see I never got to 8 or 9

Quote:

Originally Posted by Beryllos

Great idea. I don't have a clear idea how to generate the sequence. It's the sequence of unique n-digit numbers with sorted digits. I'm thinking a recursive approach might work. I'll try to get back to that later.

@grail - I had thought about your idea also. Although I've only gotten as far as generating the combinations.

#!/usr/bin/python3
from itertools import combinations_with_replacement
digits=[0,1,2,3,4,5,6,7,8,9]
for i in range(3,16):
nums=combinations_with_replacement(digits, i)
x=0
for tup in nums: # iterate the container
x=x+1
print("10^", i, "\t= ", x, sep='')

Yes, you can look them all up, but that doesn't help you be a better programmer.

that was posted just to be able to check if your code works properly. From the other hand it looks like we may need to prove somehow the statement: we have only 88 numbers, you cannot do that with brute force programs.

I looked up the formula for number of combinations with replacement. Here it is on an online calculator. For 39 digits (the largest Armstrong numbers), there are about 1.7 billion combinations, which is feasible for an exhaustive brute-force search.

#!/usr/bin/python3
from itertools import combinations_with_replacement
digits=[0,1,2,3,4,5,6,7,8,9]
for i in range(3,16):
nums=combinations_with_replacement(digits, i)
x=0
for tup in nums: # iterate the container
x=x+1
print("10^", i, "\t= ", x, sep='')

Not so surprisingly, when you don't use the correct command, cause you thought you had a better idea, you get crap processing.
So when you use the right commands, I also get good times:

grail, please correct me if I'm wrong (back to post #73), but:
1. there are only 900 3-digit numbers exist, not 1000.
2. as you told there are 220 different combinations available, so we need to check only these.
3. but what does this check really mean?
- First we should create the sum of powers and we will have 220 possible results.
- Obviously we can drop all but the 3-digit ones (like 111 -> 3 or 999 -> 2187).
- Now we need to check all of rest if those results can be constructed from the original set of digits - or you can say the result is one of the combinations. It means you need to count the number of digits (both the result and original) and compare them.

grail, please correct me if I'm wrong (back to post #73), but:
1. there are only 900 3-digit numbers exist, not 1000.
2. as you told there are 220 different combinations available, so we need to check only these.
3. but what does this check really mean?
- First we should create the sum of powers and we will have 220 possible results.
- Obviously we can drop all but the 3-digit ones (like 111 -> 3 or 999 -> 2187).
- Now we need to check all of rest if those results can be constructed from the original set of digits - or you can say the result is one of the combinations. It means you need to count the number of digits (both the result and original) and compare them.

That is mostly right. You only have to check 219 combinations, because one of the combinations is 000. Every other combination (e.g., 001) must be checked because it can be rearranged to a 3-digit number (e.g., 100). Check means calculate the sum of powers and see if it has the same combination of digits. It is not necessary to check the number of digits because out-of-range numbers are just combinations having different lengths. Comparison can be accomplished by making a list of digits, sorting the list, and comparing lists. I'll show an example in Python later.

LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.