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.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
Printing Armstrong numbers from 1 to 500. (C Programming)
Code:
/*
Write a program to print out all Armstrong numbers between 1 and 500.
If sum of cubes of each digit of the number is equal to the number itself,
then the number is called an Armstrong number.
For example,
153 = (1*1*1) + (5*5*5) + (3*3*3)
*/
#include<stdio.h>
main()
{
int number, temp, digit1, digit2, digit3;
printf("Printing all Armstrong numbers between 1 and 500:\n\n");
number = 001;
while (number <= 500)
{
digit1 = number%10;
digit2 = (number%100) - ((number/100)*10);
digit3 = number%1000;
temp = (digit1*digit1*digit1) + (digit2*digit2*digit2) + (digit3*digit3*digit3);
if (temp == number)
{
printf("\nAmstrong Number:%d", temp);
}
number++;
}
}
Just to comment on what you have done, Whilst your second approach is correct, it is a little ungainly, the first approach to get the digits actually had some merit. With a little more thought, you can make that code much cleaner.
And for the moment I'll leave it there as a poser...
And when you post code, please place your code snippets inside [CODE]...[/CODE] tags for better readability. You may type those yourself or click the "#" button in the edit controls.
The original problem statement (in post #1) is ...
Code:
Write a program to print out all Armstrong numbers between 1 and 500.
If sum of cubes of each digit of the number is equal to the number itself, then the number is called an Armstrong number.
For example, 153 = (1*1*1) + (5*5*5) + (3*3*3)
Post #9 offered this concise non-C solution ...
Code:
echo "Method #1 of LQ Member danielbmartin."
seq -w 500 \
|awk -F "" '{if ($1^3+$2^3+$3^3==$0) print}' >$OutFile
Consider a means to reduce execution time. Since the largest number must be less than 501, each of the individual terms $1^3, $2^3, and $3^3 must be less than 501.
The command seq -w 500 creates a stream of lines in the form
Code:
001
002
003
...
498
499
500
8^3=512 and 9^3=729, so the stream may be "pruned" to eliminate all lines which contain an 8 or a 9, in this manner.
Pruning reduces the stream from 500 to 320 lines which leaves less work for the awk to do. This might seem like an improvement but it isn't, as shown below.
Now, another surprise. A solution which uses only awk looks verbose and clumsy but turned out to be the fastest of the three.
Code:
echo "Method #3 of LQ Member danielbmartin."
awk 'BEGIN{for (j=1;j<=500;j++)
{k="00"j;
a=substr(k,length(k)-2,3); # a = j with leading zeros
h=substr(a,1,1); # h = hundreds
t=substr(a,2,1); # t = tens
u=substr(a,3,1); # u = units
if (h^3+t^3+u^3==j) print a}}' >$OutFile
A measurement of each solution executed 1000 times produced this result ...
Code:
Method #1 of LQ Member danielbmartin, repeated 1000 times.
real 0m2.356s
user 0m0.060s
sys 0m0.160s
Method #2 of LQ Member danielbmartin, repeated 1000 times.
real 0m2.649s
user 0m0.064s
sys 0m0.260s
Method #3 of LQ Member danielbmartin, repeated 1000 times.
real 0m1.779s
user 0m0.060s
sys 0m0.088s
Perhaps the awk-savvy reader will know a better way to produce the three-digit lines 001,002, ... etc.
Daniel B. Martin
Last edited by danielbmartin; 06-12-2017 at 10:23 AM.
Reason: Cosmetic improvement
Method #1 of LQ Member danielbmartin, repeated 1000 times.
real 0m2.388s
user 0m0.040s
sys 0m0.184s
Method #2 of LQ Member danielbmartin, repeated 1000 times.
real 0m2.709s
user 0m0.084s
sys 0m0.232s
Method #3 of LQ Member danielbmartin, repeated 1000 times.
real 0m1.803s
user 0m0.056s
sys 0m0.096s
Method #1 of LQ Member KenJackson, repeated 1000 times.
real 0m1.418s
user 0m0.048s
sys 0m0.096s
Method #1 of LQ Senior Member ntubski, repeated 1000 times.
real 0m1.388s
user 0m0.056s
sys 0m0.096s
Method #2 of LQ Senior Member ntubski, repeated 1000 times.
real 0m2.437s
user 0m0.052s
sys 0m0.104s
There's two basic approaches -- try to calculate every Armstrong number between 1 and 500 or check every number between 1 and 500 to see if it's an Armstrong number. I assume this has already been made clear.
There's two basic approaches -- try to calculate every Armstrong number between 1 and 500 or check every number between 1 and 500 to see if it's an Armstrong number. I assume this has already been made clear.
Which is faster would need testing.
calculate every Armstrong number between 1 and 500
... this requires an algorithm. Do you know one?
check every number between 1 and 500 to see if it's an Armstrong number
... this is exhaustive enumeration and is the basis of all solutions posted so far. Granted, avoiding 8s and 9s is a small shortcut but all the posted solutions fall into the Brute Force category.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.