C :: Aufgabe #70
4 Lösungen
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
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:
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
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; }
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; }
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; }
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); } }