C :: Aufgabe #70

4 Lösungen Lösungen öffentlich

Giuga-Zahlen berechnen

Anfänger - C von Gustl - 13.02.2015 um 12:42 Uhr
Eine natürliche Zahl n ist eine Giuga-Zahl, wenn alle ihre Primteiler p den Wert n/p - 1 teilen.

Schreibe ein Programm welches alle Giuga-Zahlen bis zu einer festen Obergrenze ausgibt.

Erläuterung zu einer Giuga-Zahl findest du hier: Wikipedia

Lösungen:

vote_ok
von devnull (8870 Punkte) - 01.03.2015 um 22:24 Uhr
Das Programm verwendet "unsigend int". Die 3- bis 5-faktorigen Giuga-Zahlen werden recht schnell berechnet, für größere Giuga-Zahlen ist der Faktorisier-Algorithmus (Probedivision) zu langsam.

Konsolenausgabe:


$ ./giuga_uint 1000000
Berechne Primzahlen bis 1000000...
78498 Primzahlen gefunden.
Suche Giuga-Zahlen bis 1000000
30 = 2*3*5
858 = 2*3*11*13
1722 = 2*3*7*41
66198 = 2*3*11*17*59

Quellcode ausblenden C-Code
/********************************************
 * giuga.c    Giuga-Zahlen berechnen
 ********************************************/
#include <stdlib.h>
#include <stdio.h>
 
#define MAX_SIEVE 1000000   // Array Limit Sieb
#define MAX_PRIME 100000    // Array Limit Primzahlen

unsigned char *psieve;
unsigned int *pprime, *ppfact;
int nsieve, nprime, npfact;

int alloc_buffers() {
	size_t bufsiz;
	
	// sieve buffer initialized with 0
	bufsiz = MAX_SIEVE / 8;
	if ((psieve = (unsigned char *)calloc(bufsiz,1)) == NULL) {
	  printf("Error sieve buffer allocation (%d byte)\n", (int)bufsiz);
	  return 1;
    }
	bufsiz = MAX_PRIME * sizeof(int);
	if ((pprime = (unsigned int *)malloc(bufsiz)) == NULL) {
	  printf("Error prime buffer allocation (%d byte)\n", (int)bufsiz);
	  return 1;
    }
	if ((ppfact = (unsigned int *)malloc(bufsiz)) == NULL) {
	  printf("Error factor buffer allocation (%d byte)\n", (int)bufsiz);
	  return 1;
    }
    return 0;
}

void free_buffers() {
	if (psieve != NULL) free(psieve);
	if (pprime != NULL)	free(pprime);
	if (ppfact != NULL)	free(ppfact);
}

void set_sieve(unsigned int number) {
	// sets "NOPRIME = 1"
	unsigned char *p = psieve + number/8;
	*p |= 1 << number%8;
}

int get_sieve(unsigned int number) {
	// if "NOPRIME" return code > 0
	unsigned char *p = psieve + number/8;
	return *p & (1 << number%8);
}

int get_primes(unsigned int max_number) { 
    unsigned int np = 2;
    unsigned int m, p;
 
    set_sieve(0);
    set_sieve(1);
    do {
		m = np + np;
		while(m <= max_number) {
			set_sieve(m);
			m += np;
		}
		while(++np <= max_number && get_sieve(np) > 0)
			;
    } while (np <= max_number);
	// fill primes array
    for (m=p=0; p <= max_number; p++) {
        if (get_sieve(p) == 0) {
			*(pprime + m) = p;
			m++;
		}
	}
	return m;		
}

int factorize(unsigned int number) {
	unsigned int pnum; 
	int np=0, nf=0;

	while (number > 1) {
		pnum = *(pprime + np);
		while (number % pnum == 0) {
			*(ppfact + nf++) = pnum;
			number /= pnum;
		} 
		if (++np >= nprime)
			return 0;
	}
	return nf;
}

int main(int argc, char **argv) {
	unsigned int max_number, number;
	unsigned int pfact, gtest, k;

	if (argc <= 1 || (max_number = atoi(argv[1])) == 0)
		return 1;

	printf("Berechne Primzahlen bis %d...\n", MAX_SIEVE);
	alloc_buffers();
    nprime = get_primes(MAX_SIEVE);
	printf("%d Primzahlen gefunden.\n",nprime);

   	printf("Suche Giuga-Zahlen bis %u\n", max_number);
    for (number=2; number <= max_number; number+=2) {
	    gtest = 1;
	    if ((npfact = factorize(number)) > 0) {
		  gtest = pfact = 0;	
		  for (k=0; k < npfact; k++) {
		    if (pfact < *(ppfact + k)) {
			    pfact = *(ppfact + k);
		        if ((gtest += (number>pfact)?(number/pfact-1)%pfact:1) > 0)
		          break;
  		    }
  		  }  
	    }
        if (gtest == 0) {
			// Treffer
			printf("%u = ", number);
		    for (k=0; k < npfact; k++)
				printf("%u%c", *(ppfact + k), (k<npfact-1)?'*':'\n');
		}	
	}	
	free_buffers();
    return 0;
}
vote_ok
von Jordan (210 Punkte) - 10.03.2015 um 09:05 Uhr
Quellcode ausblenden C-Code
// Giuga Zahlen.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "stdlib.h"
#include "math.h"

struct element
{
	int key;
	int zahl;
	struct element *next;
};

void append(struct element **liste, int value)
{
	struct element *neuesElement;									
	struct element *liste_iter = *liste;							
				
	neuesElement = (struct element*)malloc(sizeof(struct element));	
	neuesElement->zahl = value,									
	neuesElement->next = NULL;										
	

	if(liste_iter != NULL)											
	{
		while(liste_iter->next != NULL)								
		{
			liste_iter = liste_iter->next;							
																	
		}
		liste_iter->next = neuesElement;							
		neuesElement->key = liste_iter->key+1;
	}
	else
	{

		*liste = neuesElement;
		neuesElement->key = 0;
	}
}

void printliste(struct element *list)
{
	printf("das %d element hat den wert %d\n",list->key, list->zahl);										
	while (list->next != NULL)										
	{
		list = list->next;											
		printf("das %d element hat den wert %d\n",list->key, list->zahl);	
	}
	printf("\n\n");
}

element *Prim(int grenze)
{
	struct element *primListe;
	primListe = NULL;

	int teiler = 0;
	int j;
	for(int i = 2; i <= grenze; i++) 
    {
        for(j = (i-1); i%j; j--) 
        {
		}

        if(j == 1)
        {
			append(&primListe,i); 
			teiler = i;
        }
    }
	return primListe;
}

int ifPrim(int zahl, struct element *primKey)
{
	while(zahl != primKey->zahl && primKey->next != NULL)
	{
		primKey = primKey->next;
		if(primKey->zahl == zahl)
		{
			//printf("Zahl ist eine Primzahl");
			return 1;
			break;
		}
		if(primKey->zahl > zahl)
		{
			//printf("Zahl ist keine Primzahl");
			return 0;
			break;
		}

	}
	

}

element *primTeiler(int zahl, int primzahlen)
{
	struct element *primKey = Prim(primzahlen);
	struct element *primKey_start = primKey;

	struct element *primTeiler;
	primTeiler = NULL;

	int zahl_start = zahl;
	
	if(!ifPrim(zahl, primKey))
	{
		while( zahl > 1 )
		{
			while(zahl % primKey->zahl == 0)
			{
				//printf("%d * ",primKey->zahl);
				append(&primTeiler, primKey->zahl);
				zahl = zahl / primKey->zahl;				
			}
			primKey = primKey->next;

			if(ifPrim(zahl, primKey_start))
			{
				//printf("%d = %d\n\n",zahl,zahl_start);
				append(&primTeiler, zahl);
				break;
			}

			if(zahl % primKey->zahl != 0)
			{
				primKey = primKey->next;
			}
		}
	}
	else
	{
		primTeiler = NULL;
	}
	return primTeiler;

}

void Giuga(int zahl)
{
	struct element *PT =  primTeiler(zahl, 10000);
	if(PT != NULL)
	{
		while(PT->next != NULL)
		{
			//printf("%d\n",PT->zahl);
			if( ((zahl / PT->zahl) -1) % PT->zahl == 0 )
			{
				//printf("%d ist ein Teiler von %d / %d -1\n", PT->zahl, zahl, PT->zahl);
				PT = PT->next;
			}
			else
			{
				//printf("\nDie Zahl %d ist keine Giuga Zahl\n",zahl);
				break;
			}		

			if(PT->next == NULL)
			{
				if( ((zahl / PT->zahl) -1) % PT->zahl == 0 )
				{
					//printf("%d ist ein Teiler von %d / %d -1\n", PT->zahl, zahl, PT->zahl);
					//printf("\nDie Zahl %d ist eine Giuga Zahl\n",zahl);
					printf("%d\tGiuga\n",zahl);
				}		
			}
		}
	}
	else
	{
		printf("%d\tPrimzahl\n",zahl);
	}
	
}


int main()
{
	for(int i = 0; i<1000; i++)
	{
		int zahl = i;
		Giuga(zahl);
	}
		

	getchar();
	return 0;
}
vote_ok
von eulerscheZhl (5230 Punkte) - 10.03.2015 um 16:41 Uhr
Quellcode ausblenden C-Code
#define LIMIT 1000000
#include <stdio.h>
 
void getSmallestFactor(int array[]) {
	int i, j;
    for (i = 2; i * i <= LIMIT; i++) {
        if (array [i] == 0) {
            for (j = 2 * i; j <= LIMIT; j += i) {
                if (array [j] == 0) {
                    array [j] = i;
                }
            }
        }
    }
}
 
int isGiuga(int n, const int primes[]) {
    int current = n;
    while (primes[current] != 0) {
        if ((n / primes [current] - 1) % primes [current] != 0)
            return 0;
        current /= primes [current];
    }
    return n != current && (n / current - 1) % current == 0;
}
 
int main() {
    int primes[LIMIT + 1] = {0};
    int i;
    getSmallestFactor (primes);
    for (i = 1; i <= LIMIT; i++) {
        if (isGiuga (i, primes)) {
            printf("%i\n", i);
        }
    }
    return 0;
}
vote_ok
von kathleenw (3600 Punkte) - 09.07.2020 um 12:10 Uhr
Quellcode ausblenden C-Code
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

int main(void)
{
    int grenze, zahl, z, i, p, anzahl_faktoren;
    bool gefunden, giuga;
    int faktoren[100]={0};
    
    printf("Bis zu welcher Grenze sollen die Giuga Zahlen berechnet werden? \n");
    if (scanf("%d", &grenze)!=1) {
        printf("Zahl wurde falsch eingegeben. \n");
        return EXIT_FAILURE;
    }
    fflush(stdin);
    
    printf("\n***************************");
    printf("\n*** Giuga Zahlen bis %d ", grenze);
    printf("\n***************************\n\n");
    
    for (zahl=2;zahl<=grenze;zahl++)
    {
        //faktoren[100] = {0};
        anzahl_faktoren=0;
        giuga = true;
        
        //Primfaktorzerlegung
        z=zahl;
        while (z>1) {
            i =2;
            gefunden = false;
            while(i*i<=z && gefunden == false) {
                if (z%i == 0) {
                    gefunden = true;
                    p=i;
                }
                else
                    i++;
            }
            if (gefunden == false)
                p=z;
            faktoren[anzahl_faktoren] = p;
            anzahl_faktoren++;
            z = z / p;
        }
        
        //Prüfe auf Giuga Zahl
        for (i=0;i<anzahl_faktoren;i++) {
            if (((zahl/faktoren[i])-1)%faktoren[i]!=0 || ((zahl/faktoren[i])-1)==0)
                giuga = false;
        }
            
        if (giuga==true)
            printf("%d \t", zahl);
    }
}
1814509

Du scheinst einen AdBlocker zu nutzen. Ich würde mich freuen, wenn du ihn auf dieser Seite deaktivierst und dich davon überzeugst, dass die Werbung hier nicht störend ist.