/* ==============================================================
* Από: migf1
*
* Άθροισμα Παραγοντικών
* ---------------------
* Δίνεται ένας ακέραιος τυχαίος αριθμός. Βρείτε το άθροισμα των παραγοντικών που
* προκύπτουν από καθένα από τα ψηφία του. Επαναλάβατε τη διαδικασία με τα ψηφία
* του αριθμού που προέκυψε σαν άθροισμα. Η επαναληπτική διαδικασία ολοκληρώνεται
* όταν ένας από τους αριθμούς που προκύπτουν από αυτή τη διαδικασία σαν άθροισμα
* έχει ήδη παραχθεί σε προηγούμενο βήμα.
*
* Περισσότερα: http://w...content-available-to-author-only...s.gr/index.php/exercises/86-2011-07-29-05-46-33
* ==============================================================
*/
#include <stdio.h>
#include <stdlib.h>
#define MAX_OUTNUM 9999999+1 // μέγιστο μήκος χάρτη
#define OUTBOUND(x) ( (x) < 0 || (x) > 9999999 ) // συνθήκη άκυρης εισόδου
typedef struct { // δομή χάρτη
int found; // boolean
unsigned int istep; // τιμή μετρητή
}MapElem;
// ---------------------------------------------------------------------------------
// Συνάρτηση fact:
// επιστρέφει το παραγοντικό του n (λειτουργεί με αναδρομή)
//
long int fact(long int n)
{
return n < 2 ? 1 : n * fact(n-1);
}
// ---------------------------------------------------------------------------------
// Συνάρτηση factsum:
// επιστρέφει το άθροισμα των παραγοντικών των ψηφίων του n
//
long int factsum( long int n )
{
long int fsum = 0;
do {
fsum += fact(n % 10);
n /= 10;
} while( n );
return fsum;
}
// ---------------------------------------------------------------------------------
int main ( void )
{
long int fsum; unsigned int i=0; // αποτέλεσμα και μετρητής
MapElem
*map
=calloc(MAX_OUTNUM
,sizeof(MapElem
));// δέσμευση μνήμης για χάρτη // (στη heap, για πιο σίγουρα)
if ( !map ) { // αποτυχία δέσμευσης μνήμης
puts("*** error: out of memory, aborting program..."); exit( EXIT_FAILURE
); // πρόωρος τερματισμός }
do { // απαίτηση έγκυρης εισόδου
printf("Δώστε έναν αριθμό μεταξύ 0 και 9999999: "); } while( OUTBOUND(fsum) );
do { // το κεντρικό μας loop
printf("%ld, ", fsum
); // τύπωμα αποτελέσματος (map+fsum)->found = 1; // χαρτογράφηση αποτελέσματος
(map+fsum)->istep = i++; // αποθήκευση βήματος του loop
} while( !(map + (fsum = factsum(fsum)))->found );
printf("%ld\n\n", fsum
); // τελευταίο αποτέλεσμα printf("Μήκος λίστας παραγοντικών: %u\n", i
+1); printf("Η λίστα παρουσίασε τον ίδιο αριθμό στην θέση: %d\n", (map
+fsum
)->istep
+1);
free( map
); // αποδέσμευση μνήμης χάρτη
exit( EXIT_SUCCESS
); // επιτυχής τερματισμός }