Fröhliche Zahl mittels do-while Schleife



  • Das ist eine ganz normale Funktion. main() benutzt du ja auch.

    int main()
    {
      unsigned int i = f(19); // Aufruf der eigenen Funktion
      if(i==1)
        puts("19 ist eine froehliche Primzahl"); // auch ein Funktionsaufruf
      printf("100: %d",f(100));  // hier auch
      return 0;
    }
    

    Was ich meinte war, dass 42 noch weiter aufgeteilt wird.

    4->16->37->58->89->145->42->20->4
    7->49->97->130->10->1
    91->82->68->100->1
    9986->262->44->32->13->10->1
    

    Btw. Von fröhlichen Zahlen habe ich vorher noch nie gehört, was es alles gibt 😃



  • JaykopX schrieb:

    Das while(i>9), kann man auch schreiben als while(i!=1 && i!=4).

    Ja, denn die 7 ist auch fröhlich. Das könnte sonst verwirrend sein.
    Oder while(i!=1 && i!=42).
    Man könnte while(i>4) machen.



  • Gehört nicht mehr zur Aufgabe, aber interssiert mich:

    Konstruiere einen Algorithmus der eine fröhliche Zahl liefert.
    Dabei soll die Folge n Mitglieder haben und die fröhliche Zahl möglichst klein sein. 😃



  • Man könnte doch noch einen Zeiger an f übergeben, in jedem Schleifendurchgang wird er dereferenziert und erhöht.

    int r, n = 5;
    
    while(1)
    {
    	nf = 0; // an f übergeben
    	if((r=f(i,&nf))==1)
    	{
    		if(nf==n)
    		{
                // gefunden
    			break;
    		}
    	}
    	++i;
    }
    
    für n = [1,7[
    1      13
    2      23
    3      44
    4      70
    5      356
    6      78999
    oh, n ist verrutscht
    


  • Das sieht sehr nach Brute Force aus.
    Einfach alle Zahlen durchprobieren...

    Ich hatte da eher sowas im Kopf:
    Fange mit 1 an, berechne daraus 10, berechne daraus 13, berechne daraus 32, usw...

    bis man n Schritte hinter sich hat.

    Ich denke dein Vorschlag wird schon für "kleine" n eine Ewigkeit dauern, weil die Folgenmitglieder mit wachsender Folgenlänge schnell sehr groß werden, dementsprechend wird dann auch die fröhliche Zahl schnell sehr groß.
    Kann aber auch sein, dass ich grad einen Denkfehler hab.

    Hast du es mal getestet?



  • JaykopX schrieb:

    Ich denke dein Vorschlag wird schon für "kleine" n eine Ewigkeit dauern, weil die Folgenmitglieder mit wachsender Folgenlänge schnell sehr groß werden, dementsprechend wird dann auch die fröhliche Zahl schnell sehr groß.

    n länge
    10 1
    13 2
    23 3
    19 4
    7 5
    356 6
    Ab hier gehts los mit Gemeinheit.
    Wir suchen eine Zahl, deren Sumem der Quadrate der Ziffern >356 ist. Die kleinstmögliche hätte lauter Neunen oder wenigsten große Ziffern. Pro Ziffer maximal 81 als Summenbeitrag. 356/81=4,39. Minstestens 5 Stellen sind nötig für die nächste Zahl.
    Sie wurde gefunden bei
    78999 7
    Wir suchen jetzt eine Zahl, deren Sumem der Quadrate der Ziffern >78999 ist. Die kleinstmögliche hätte lauter Neunen oder wenigsten große Ziffern. Pro Ziffer maximal 81 als Summenbeitrag. 78999/81=975,27 Stellen. Minstestens 976 Stellen sind nötig für die nächste Zahl.



  • Die Zahl hat in Wirklichkeit 977 Ziffern und lautet $$3788\overbrace{999\ldots 9}^{973}$$



  • Sorry dass ich euch schon wieder nerve, aber ich checks immernoch nicht...
    es funktioniert auch nicht.

    Hab jetzt das benutzt was Vicious Falcon gepostet hat. Hab hin und her geschoben, hier was veränder da was dazu geschrieben .. es so gelassen...alle probiert...aber das Programm gibt nie aus ob es ne fröhliche Zahl ist, ob nicht..oder überhaupt ...

    Ich versteh den Code auch net wirklich, was da mit der Einerstelle gemacht versteh ich. Aber warum da noch +s ist keine Ahnung.

    do { 
            s=0; 
            do { 
                s= s+(x%10)*(x%10); /*Einerstelle*/
            } while (x/=10);     /* Zehnerstelle*/
            x = s; 
        }while(x!=1 && x!= 4);
    
        printf("x ist eine Fröhliche Zahl: %d \n",x);
    

    So sieht meiner jetzt aus..
    Ich krieg immer entweder ne Endlosschleife..falsche Zahlen..oder gar nichts. und wenns dann ma für die 1 was richtiges ausgibt, gibt er für die 2 was falsches aus.. usw...
    Ich bin echt am verzweifeln... 😞



  • happy coder schrieb:

    Die Zahl hat in Wirklichkeit 977 Ziffern und lautet $$3788\overbrace{999\ldots 9}^{973}$$

    Das erscheint mir nicht sehr wahrscheinlich. Quelle?



  • 1. http://www.fq.math.ca/Scanned/41-4/grundman.pdf (exakte Zahl auf S. 3)
    2. http://www.frejbow.net/tl_files/math/hn.pdf (gibt nur Anzahl Ziffern an)



  • Ich hatte vergessen, das i zurückzusetzen, daher die aufsteigenden Zahlen.
    IchMein Computer berechnet gerade n=8, dauert aber noch...



  • Kisu schrieb:

    ...

    Der Code ist Richtig, als Ausgabe erhälst du entweder 1 oder 4.

    x ist bei dir nicht richtig initialisiert. Das ist das Einzige was da noch falsch sein kann.

    Dein Kommentar "Zehnerstelle", sieht verdächtig aus nach "Hab ich nicht verstanden".

    Ich schrieb:

    Erklärungen zur inneren Schleife:
    x%10 liefert dir immer die Einerstelle einer Zahl. (9876%10=6)
    x/10 entfernt immer die Einerstelle einer Zahl, da bei einer integer-division auf die nächst kleinere, ganze Zahl abgerundet wird. (9876/10=987)



  • happy coder schrieb:

    1. http://www.fq.math.ca/Scanned/41-4/grundman.pdf (exakte Zahl auf S. 3)

    Thx.



  • ne hab ich schon verstanden, ich mein das schon damit, schlecht gewählter begriff, ist halt ohne die einerstelle, bei 19, die 1..die beiden Begrifflichkeiten waren nie das problem.

    mein problem ist das ich den gesamten code im zusammenhang nicht verstehe...
    einzelheiten sind kein problem....

    ich habs eh aufgegeben..muss es morgen präsentieren und hat kein sinn mehr

    ..aber danke dass ihr es versucht habt.



  • unsigned int s; // wir brauchen s als temporäre Variable
    do { // fußgesteuerte Schleife, wird mindestens 1x durchlaufen
      s=0; // s muss hier auf 0 gesetzt werden, da wir später nur hinzuaddieren
      // wir nehmen an, i sei 19
      do { // s.o. 
        s+=(i%10)*(i%10); // -> s = s + 9*9 im ersten Durchlauf, im zweiten Durchlauf s.u. 1*1 und somit 81+1=82
      } while (i/=10); // nach dem ersten Durchgang i=i/10->19/10=1, nach dem zweiten 1/10 = 0-> Abbruch
      i = s; // i ist wird 82
    }while(i!=1 && i!=4); // Bedingung nicht erfüllt, das gleiche Spiel noch einmal,
                          // diesmal nicht mit 19, sondern 82
    

    Daher kommen bei 19 also die Schleifendurchgänge (in der äußeren Schleife) zustande:

    19->82->68->100->1
    

    Bei 1 ist die Abbruchbedingung schließlich erfüllt.



  • okay, auch von mir danke soweit!

    eine kleine frage hätte ich noch:

    wie kriegt man das nun hin, dass zu einer zahl zb: der 10 alle zahlen => 10 geprüft werden ob sie fröhliche zahlen sind? d.h. die 10,9,8,7,6,5,4,3,2,1,0.

    eine mammutsaufgabe, der ich nicht herr werde.



  • Togglino schrieb:

    wie kriegt man das nun hin, dass zu einer zahl zb: der 10 alle zahlen => 10 geprüft werden ob sie fröhliche zahlen sind? d.h. die 10,9,8,7,6,5,4,3,2,1,0.

    Schleife drum?

    for(zahl=0;zahl<=10;zahl++) {
      fröhliche_zahlen(zahl);
    }
    


  • Kisu schrieb:

    ich habs eh aufgegeben..muss es morgen präsentieren und hat kein sinn mehr

    Das ist gut. Du hast auch die Untergrenze unterschritten, wo man noch helfen sollte.



  • Kisu schrieb:

    ne hab ich schon verstanden, ich mein das schon damit, schlecht gewählter begriff, ist halt ohne die einerstelle, bei 19, die 1..die beiden Begrifflichkeiten waren nie das problem.

    mein problem ist das ich den gesamten code im zusammenhang nicht verstehe...
    einzelheiten sind kein problem....

    ich habs eh aufgegeben..muss es morgen präsentieren und hat kein sinn mehr

    ..aber danke dass ihr es versucht habt.

    Viel Spass beim Tutorium morgen. Ich hab meins auch morgen 🙂


Anmelden zum Antworten