LinuxQuestions.org
Help answer threads with 0 replies.
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 07-23-2006, 10:05 AM   #1
duffmckagan
Senior Member
 
Registered: Feb 2005
Distribution: Cent OS 6.4
Posts: 1,163

Rep: Reputation: 49
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++;
	}
}

Whats wrong with the program?

It does not give a single number in the output!
 
Old 07-23-2006, 10:25 AM   #2
michaelk
Moderator
 
Registered: Aug 2002
Posts: 25,592

Rep: Reputation: 5880Reputation: 5880Reputation: 5880Reputation: 5880Reputation: 5880Reputation: 5880Reputation: 5880Reputation: 5880Reputation: 5880Reputation: 5880Reputation: 5880
Per the rules:
Do not expect LQ members to do your homework - you will learn much more by doing it yourself.

However, providing hints is acceptable.
Have you verified that digit1, digit2 and digit3 equations actually produce the correct values of your number?
 
Old 07-23-2006, 10:27 AM   #3
duffmckagan
Senior Member
 
Registered: Feb 2005
Distribution: Cent OS 6.4
Posts: 1,163

Original Poster
Rep: Reputation: 49
Hey..i was not expecting you to do my homework!!

I worked all the way upto this step..and still the program is not working..so I asked for help!

well.I changed the Digit Extraction scheme and it worked

Changed it to this:

Code:
digit1 = number - ((number / 10) * 10);
digit2 = (number / 10) - ((number / 100) * 10);
digit3 = (number / 100) - ((number / 1000) * 10);
 
1 members found this post helpful.
Old 07-23-2006, 10:38 AM   #4
michaelk
Moderator
 
Registered: Aug 2002
Posts: 25,592

Rep: Reputation: 5880Reputation: 5880Reputation: 5880Reputation: 5880Reputation: 5880Reputation: 5880Reputation: 5880Reputation: 5880Reputation: 5880Reputation: 5880Reputation: 5880
Well done.
 
Old 07-23-2006, 12:32 PM   #5
graemef
Senior Member
 
Registered: Nov 2005
Location: Hanoi
Distribution: Fedora 13, Ubuntu 10.04
Posts: 2,379

Rep: Reputation: 148Reputation: 148
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...
 
Old 06-11-2017, 12:22 AM   #6
Lalit Yogi
LQ Newbie
 
Registered: Jun 2017
Posts: 1

Rep: Reputation: Disabled
Smile slightly alternate solution-

#include<stdio.h>
void main()
{
int number,temp,digit1,digit2,digit3;

for(number=001;number<=500;number++)
{
digit1 = number - ((number/10)*10);
digit2 = (number - ((number/100)*100))/10;
digit3 = number/100;
temp = (digit1*digit1*digit1) + (digit2*digit2*digit2) + (digit3*digit3*digit3);
if(temp==number)
printf("\nArmstrong number: %d",temp);
}
}

Here in my code, digit2 and digit3 values are a little different-

digit1 = number - {(number/10)*10}
digit2 = {number - ((number/100)*100)}/10
digit3 = number / 100
 
Old 06-11-2017, 01:42 AM   #7
astrogeek
Moderator
 
Registered: Oct 2008
Distribution: Slackware [64]-X.{0|1|2|37|-current} ::12<=X<=15, FreeBSD_12{.0|.1}
Posts: 6,258
Blog Entries: 24

Rep: Reputation: 4193Reputation: 4193Reputation: 4193Reputation: 4193Reputation: 4193Reputation: 4193Reputation: 4193Reputation: 4193Reputation: 4193Reputation: 4193Reputation: 4193
Welcome to LQ!

You have posted to an 11 year dead thread, best to leave them at rest! Please start your own threads for your own questions.

See the LQ posting guidelines foru guidance in posting your questions as well.

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.
 
1 members found this post helpful.
Old 06-11-2017, 10:10 AM   #8
GazL
LQ Veteran
 
Registered: May 2008
Posts: 6,882

Rep: Reputation: 4988Reputation: 4988Reputation: 4988Reputation: 4988Reputation: 4988Reputation: 4988Reputation: 4988Reputation: 4988Reputation: 4988Reputation: 4988Reputation: 4988
I'm glad he did, I enjoyed having a go at that one.

BTW, watch out for those leading zeros!
Code:
for(number=001;number<=500;number++)
It doesn't matter in this case, but leading zeros signify octal!

Last edited by GazL; 06-11-2017 at 10:31 AM.
 
2 members found this post helpful.
Old 06-11-2017, 03:56 PM   #9
danielbmartin
Senior Member
 
Registered: Apr 2010
Location: Apex, NC, USA
Distribution: Mint 17.3
Posts: 1,879

Rep: Reputation: 660Reputation: 660Reputation: 660Reputation: 660Reputation: 660Reputation: 660
Quote:
Originally Posted by GazL View Post
I'm glad he did, I enjoyed having a go at that one.
Me too. Just for fun I wrote a non-C solution.
This code ...
Code:
seq -w 500  \
|awk -F "" '{if ($1^3+$2^3+$3^3==$0) print}'
... produced this result ...
Code:
001
153
370
371
407
Daniel B. Martin
 
3 members found this post helpful.
Old 06-12-2017, 10:13 AM   #10
danielbmartin
Senior Member
 
Registered: Apr 2010
Location: Apex, NC, USA
Distribution: Mint 17.3
Posts: 1,879

Rep: Reputation: 660Reputation: 660Reputation: 660Reputation: 660Reputation: 660Reputation: 660
Execution time is always of interest.

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.
Code:
echo "Method #2 of LQ Member danielbmartin."
seq -w 500       \
|egrep -v '[89]' \
|awk -F "" '{if ($1^3+$2^3+$3^3==$0) print}' >$OutFile
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
 
Old 06-12-2017, 11:05 AM   #11
KenJackson
Member
 
Registered: Jul 2006
Location: Maryland, USA
Distribution: Fedora and others
Posts: 757

Rep: Reputation: 145Reputation: 145
Yeah, this is fun. Didn't time it.
Code:
awk 'BEGIN{for (h=0;h<8;h++)
            for (t=0;t<8;t++)
             for (u=0;u<8;u++)
              if ((h||t||u) && (h^3+t^3+u^3==h*100+t*10+u)) print h t u}'
 
1 members found this post helpful.
Old 06-12-2017, 11:24 AM   #12
ntubski
Senior Member
 
Registered: Nov 2005
Distribution: Debian, Arch
Posts: 3,774

Rep: Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081
Quote:
Originally Posted by danielbmartin View Post
Perhaps the awk-savvy reader will know a better way to produce the three-digit lines 001,002, ... etc.
"Better" might be subjective, but some shorter ways are:

Code:
BEGIN{for (j=1;j<=500;j++) {
        h=int(j/100);     # h = hundreds
        t=int(j/10) % 10; # t = tens
        u=j % 10;         # u = units
        if (h^3+t^3+u^3==j) print j}}
Code:
BEGIN{for (j=1;j<=500;j++) {
        split(sprintf("%03d", j), digits, "");
        if (digits[1]^3+digits[2]^3+digits[3]^3==j) print j}}
 
1 members found this post helpful.
Old 06-12-2017, 02:48 PM   #13
danielbmartin
Senior Member
 
Registered: Apr 2010
Location: Apex, NC, USA
Distribution: Mint 17.3
Posts: 1,879

Rep: Reputation: 660Reputation: 660Reputation: 660Reputation: 660Reputation: 660Reputation: 660
Timings ...

Code:
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
Nice ideas from everyone. Thank you!

Daniel B. Martin
 
Old 06-12-2017, 02:59 PM   #14
Laserbeak
Member
 
Registered: Jan 2017
Location: Manhattan, NYC NY
Distribution: Mac OS X, iOS, Solaris
Posts: 508

Rep: Reputation: 143Reputation: 143
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.
 
Old 06-12-2017, 03:36 PM   #15
danielbmartin
Senior Member
 
Registered: Apr 2010
Location: Apex, NC, USA
Distribution: Mint 17.3
Posts: 1,879

Rep: Reputation: 660Reputation: 660Reputation: 660Reputation: 660Reputation: 660Reputation: 660
Quote:
Originally Posted by Laserbeak View Post
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.

Daniel B. Martin
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
printing line numbers for code bauer172uw Programming 3 04-13-2006 11:10 PM
C programming - sorting random numbers Gigantor Programming 8 12-05-2005 10:32 PM
Printing numbers from a text file dynamically mrobertson Programming 1 06-28-2005 08:19 AM
printing numbers without using semicolon vijeesh_ep Programming 18 09-08-2004 11:59 AM
printing line numbers? fisheromen1031 Programming 1 07-27-2004 02:19 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 04:34 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration