# Fröhliche Zahlen



## karllson (10. Dez 2008)

Hey Leute, erstmal vorweg: Cooles Forum.

Danke für die Möglichkeit mein geistigen Unfug mit eurer Hilfe zu Ordnen.
Ich bin Anfänger in Sachen Java und habe jetzt eine Aufgabe in der UNI, an der ich an nem gewissen Punkt scheitere!

Aufgabe ist:


> Pflichtaufgabe 28: Die Dezimalziffern einer natürlichen Zahl n, n ≥ 1, werden einzeln
> quadriert und addiert. Anschließend wird mit der entstandenen Summe genauso verfahren.
> Die Ausgangszahl n heißt fröhlich, wenn man bei diesem Vorgehen schließlich auf die Zahl
> 1 stößt, sonst traurig. Beispielsweise ist 7 eine fröhliche Zahl:
> ...



So nun bin ich soweit:


```
import java.io.*;

public class test {

 	 public static void main( String[] args ) {
  
    		
    		try {
			System.out.println( "Bitte untere Grenze eingeben:" );
      			BufferedReader in = new BufferedReader(new InputStreamReader( System.in ) );
      			String eingabe = in.readLine();
      			int unteregrenze = Integer.parseInt(eingabe);
			
			System.out.println( "Bitte obere Grenze eingeben:" );			
			BufferedReader in2 = new BufferedReader(new InputStreamReader( System.in ) );
      			String eingabe2 = in.readLine();
      			int oberegrenze = Integer.parseInt(eingabe2);
			
			int startwert = unteregrenze;
			while(startwert >= unteregrenze && startwert <= oberegrenze){
				startwert = ++startwert;
				int zwischenzahlen = startwert-1;
					
					if(zwischenzahlen <= 9){
						int ergebniskleinerzehn = zwischenzahlen*zwischenzahlen;
						System.out.println(zwischenzahlen);
					}
					if(zwischenzahlen <=99 && zwischenzahlen >=10){
						int ersteziffer = (zwischenzahlen/10);
						int zweiteziffer = (zwischenzahlen%10);
						int ergebniskleinerhundert = (ersteziffer*ersteziffer)+(zweiteziffer*zweiteziffer);
						System.out.println(ergebniskleinerhundert);
					}
					if(zwischenzahlen <=999 && zwischenzahlen >=100){
						int ersteziffer1 = (zwischenzahlen/100);
						int zweiteziffer1 = ((zwischenzahlen-(ersteziffer1*100)) / 10);	
						int dritteziffer = (zwischenzahlen-(ersteziffer1*100)-(zweiteziffer1*10));
						int ergebniskleinertausend = (ersteziffer1*ersteziffer1)+(zweiteziffer1*zweiteziffer1)+(dritteziffer*dritteziffer);
						System.out.println(ergebniskleinertausend);
					}	
			}	
			
   		} 
		catch( IOException ex ) {
      			System.out.println( ex.getMessage() );
   	 	}	

  	}
}
```

Was macht das Skript bis dato? - In erster Linie laufen ohne Fehler. Darüber hinaus fragt es den User nach der Unteren und der Oberen Grenze und Berechnet für alle dazwischen liegenden Zahlen die Summe ihrer (Dezimalziffern zum Quadrat).

Wie ich finde, schonmal nicht schlecht. Ich sitz jetzt nur aufm Schlauch, weil ich nicht weiß, wie ich es hinbekomme, dass falls die Summe nicht 1 (also fröhlich) oder 4(traurig) ist, das Skript eben diese Summe wieder kontrolliert - solange bis 1 oder 4 in der Summe rauskommt. 

Muss man hier mit arrays arbeiten? War es bis hier in Ordnung, oder vielleicht viel zu kompliziert?
Bin um jede Hilfe dankbar. Danke für das Lesen!
gruß karllson


----------



## Guest (10. Dez 2008)

Und die 69 ist nicht dabei? Die finde ich immer wieder fröhlich.


----------



## 0x7F800000 (10. Dez 2008)

@Gast: :autsch:
@OP:
was soll dieser quatsch mit fallunterscheidungen und "ersten, zweiten, zehnten" ziffer? Die dekadische entwicklung kann man ja wohl ein wenig kürzer und wesentlich allgemeiner hinkriegen, siehe bitte die einzeiler-forschleife in "happyIterationStep", der methode, die einem n die summe der quadrate der ziffer zuordnet.

außerdem: ich würde das ein wenig unterteilen, und an paar stellen die eher geeigneten for-schleifen benutzen:

```
public class HappyNumbers {

	public static long happyIterationStep(long n){
		long result=0;
		for(long digit; n>0; digit=n%10, n/=10, result+=digit*digit );
		return result;
	}
	
	public static boolean isHappy(long n){
		while(true){
			if(n==1) return true;
			if(n==4) return false;
			n=happyIterationStep(n);
		}
	}
	
	public static String happySequenceToString(long n, boolean isHappy, int maxSteps){
		StringBuilder b=new StringBuilder();
		
		if(isHappy){
			do{
				b.append("->"+n);
				n=happyIterationStep(n);
			}while(n!=1);
		}else{
			for(int i=0; i<maxSteps; i++){
				b.append("->"+n);
				n=happyIterationStep(n);	
			}
			b.append("...(unhappy)");
		}
		return b.toString();
	}
	
	public static void main(String[] args) {
		
		//einlesen, blah blah...
		int start=192837465, end=192837564;
		boolean isHappy;
		
		for(int n=start; n<end; n++){
			System.out.printf("%5d: %b %s\n",n,isHappy=isHappy(n), happySequenceToString(n,isHappy,20));
		}
	}
}
```


----------



## karllson (10. Dez 2008)

Hey!

Dieser "Quatsch" ist halt das Beste, was mir dazu einfiel. Wie gesagt ich programmieren noch nicht lange mit Java.

Trotzdem aber erstmal Danke! Ich werde dein Code mal durcharbeiten und bin dann hoffentlich etwas schlauer!


Vielen Dank

Gruß


----------



## 0x7F800000 (10. Dez 2008)

Hmm, naja, den code (insbesondere diese eine zeile) kann man wohl stundenlang anstarren, ohne schlauer zu werden, wenn man das eigentliche prinzip nicht oder nur schwammig versteht. Spiele ein wenig mit p-adischen entwicklungen herum, schreib dir eine methode, die dir eine p-adische entwicklung zu einer vorgegebenen basis liefert, dann versuche den code auch in deinem programm zu verwenden, und anzupasen, und erst dann kannst du damit anfangen, nach und nach alle unnötigen teile rauszuschmeissen, und den ganzen vorgang letztendlich auf eine zeile reduzieren. Wenn es am anfang 20 zeilen sind, ist es dem compiler eigentlich ziemlich wurscht, hauptsache man versteht, ws da passiert.


----------



## c (10. Dez 2008)

hehe, das sieht so nach prog I tu bs aus ;D sitze auch gerade davor


----------



## karllson (10. Dez 2008)

Hey,
Also hab es soweit mal durchgearbeiten und auch verstanden.

in Public Static long wird n erhöht und die dezimalziffern-summe errechnet.
in Public Static boolean werden dann die Fälle 4 und 1 false und true zugeordnet, solange wie n true ist...
dann wird der String erstellt. Das habe ich alles verstanden.

Ich verstehe nur


```
System.out.printf("%5d: %b %s\n",n,isHappy=isHappy(n), happySequenceToString(n,isHappy,20));
```

nicht ganz.
Was soll %5d, %b,%s ???? 
Und wie ist die ganze Zeile zu verstehen?

Mir ist auch erfolgreich gelungen, die obergrenze und untergrenze nach benutzereingabe als start und end zu setzen.

Und Vorallem, wie muss ich das Skript schreiben Damit das Ergebnis in der Form



> 7 -> 49 -> 97 -> 130 -> 10 -> 1
> 10 -> 1
> 13 -> 10 -> 1


 ausgegeben wird. Also quasi der boolean wert nicht angezeigt wird. Ich denke ja mal das dies in der "von mir nicht kapierten Zeile" passiert.

Erstmal danke für die schnelle hilfe. Ich hab bis jetzt schon sehr viel gelernt und bin von der Lösung (für mich im kopf) nur sehr wenig entfernt!

Grüße


----------



## AmunRa (10. Dez 2008)

Das ist eine formatierte Ausgabe
das  %5d ->heist das er eine dezimal Zahl ausgeben muss in diesem Fall    n
%b ist ein boolescher Wert  -> isHappy(n);
%s ist ein String -> happySequenceToString(n,isHappy,20);


----------



## karllson (10. Dez 2008)

Ich muss doch da jetzt nur noch ne if -schleife einbauen,dass nicht mehr die false werte ausgegeben werden,

sondern nur die true werte in der form :

7 -> 49 -> 97 -> 130 -> 10 -> 1 

Aber ich weiss nicht wo....kann mir da wer helfen. Den Rest habe ich wie gesagt hinbekommen.
Und Dank AmunRa habsch die letzte Zeile auch kapiert 

Danke für all die Mühe...


----------



## AmunRa (10. Dez 2008)

```
for(int n=start; n<end; n++){ 
    if (isHappy(n){
     
          System.out.printf("%5d: %b %s\n",n,isHappy=isHappy(n), happySequenceToString(n,isHappy,20)); 
      }
}
```
So in etwa müsste das dann laufen


----------



## karllson (10. Dez 2008)

Jau, danke, aber das habsch denn eben alleine geschafft...

so sollte das alles eigentlich schon durchgehen.

Wenn ich es jetzt noch schaffe irgendwie nur die Dezimalziffern auszulesen

ohne Zahl: true -> davor, dann binsch noch zufriedener...

Aber für heute erstma kopp ausschalten und morgen wieder ran.

Ich danke euch für eure Mithilfe. Ihr habt ein' gut 

Grüße und Danke
Ich geh nen Brot essen!


----------



## AmunRa (10. Dez 2008)

dann musst du bei der Ausgabe einfach nurmehr 
System.out.printf("%s\n", happySequenceToString(n,isHappy(n),20));
schreiben


----------

