# HappyNumbers und so weiter.



## AnfängerinIm1Semester (3. Nov 2007)

_[Edit by Beni: zu den "Aufgaben" verschoben]_

Hallo beieinander,
Ich traue mich nach den Ermahnungen im Anfängerbereich gar nicht mehr so richtig was reinzuschreiben   
Aber vielleicht seid ihr ja so lieb und könnt mir einen Tip geben. Es geht um Folgendes:
Ich soll ein Programm schreiben, das eine EIngabezahl (Hier n) einliest und dann alle darunter liegenden "fröhlichen Zahlen" ausgeben soll. n soll , falls fröhlich, auch ausgegeben werden.

Mein Programm gibt aber alle Zahlen aus und ich hab mitlerweile den Überblick verloren.
Sieht jemand von euch meinen Fehler?

Eine fröhliche Zahl erkennt man daran, dass die quadrierung der Einzelziffern einer zahl....wenn man immer so weitermacht....mit einer 1 endet:
19 -> 1² + 9² = 82
    -> 8² + 2² = 68
    -> 6² + 8² = 100
    -> 1²        =1
Übrigens eine "traurige zahl" endet immer mit der Folge 4 16 37 58 89 145 42 20 4.

_________________________________________________________________

```
class HappyNumbers
{
	public static void main(String[] args)
	{
	
		int n = Integer.parseInt(args[0])
		int zehner = 0;
		int einer = 0;
		int getEiner;
		int i;
		int s=0;
		int zs;
		
		
		for (i=1; i<=n; i++)
		{	
			zs= i;			
			while (s !=1 && s!=4)
			{	
					while (zs>=10)
					{	
						getEiner =zs%10;
						einer = einer + (getEiner*getEiner);
						zs = zs/10;
					}
					zehner = zs*zs;
					s= zehner + einer;
					zs=s;	
			}	
			if (s==1)
				System.out.print(i + " ");
			else
				System.out.print("");

		}
	}
}
_________________________________________________________________
```
 :bahnhof:


----------



## Guest (3. Nov 2007)

FYI

Die Ausgabe für n=20 müsste sein:
1 7 10 13 19


----------



## AnfängerinIm1Semester (7. Nov 2007)

....zumindest sind mein Prof und ich uns einig, dass es funktionieren müsste, wenn die Variable s wieder auf null gesetzt wird, nachdem der counter eins hochgesetzt wurde......oder davor, aber auf alle Fälle außerhalb der ersten while Schleife....


----------



## SlaterB (7. Nov 2007)

ist die Frage noch aktuell?
dein Programm macht relativ wenig bisher,

wozu die Abfrage
> while (s !=1 && s!=4) 
was ist der Sinn dahinter, welches Verfahren wird verwendet (in deutscher Sprache)?

dem Programm scheinen grundlegende Features zu fehlen:
- die einzelnen Ziffern quadrieren
- die bereits bekannten Zwischenergebnisse merken, um Endlosbrechnungen zu verhindern,
sei froh, dass du s nicht auf 0 gesetzt hast, dann läuft dein Programm nämlich ewig


ein ganz grobes Beispielprogamm:


```
public class Test
{

    public static void main(String[] args)
        throws Exception
    {
        test(3);
        test(4);
    }

    public static void test(int n)
    {

        Set set = new HashSet();

        while (true)
        {
            set.add(n);
            if (n > 9999)
            {
                throw new RuntimeException("not yet implemented");
            }
            String st = "" + n;
            n = 0;
            for (int i = 0; i < st.length(); i++)
            {
                int k = st.charAt(i) - 48;
                n += k * k;
                System.out.println("k: " + k + ", " + n);
            }
            if (n == 1)
            {
                System.out.println("Treffer");
                return;
            }
            if (set.contains(n))
            {
                System.out.println("kein Treffer: " + n);
                return;
            }
        }

    }
}

->

k: 3, 9
k: 9, 81
k: 8, 64
k: 1, 65
k: 6, 36
k: 5, 61
k: 6, 36
k: 1, 37
k: 3, 9
k: 7, 58
k: 5, 25
k: 8, 89
k: 8, 64
k: 9, 145
k: 1, 1
k: 4, 17
k: 5, 42
k: 4, 16
k: 2, 20
k: 2, 4
k: 0, 4
k: 4, 16
k: 1, 1
k: 6, 37
kein Treffer: 37
k: 4, 16
k: 1, 1
k: 6, 37
k: 3, 9
k: 7, 58
k: 5, 25
k: 8, 89
k: 8, 64
k: 9, 145
k: 1, 1
k: 4, 17
k: 5, 42
k: 4, 16
k: 2, 20
k: 2, 4
k: 0, 4
kein Treffer: 4
```


----------



## dirk.be (7. Nov 2007)

Hallo AnfängerinIm1Semester,

Dein Programm läuft, wenn Du vor dem 1. while s mit 0 und vor dem 2. while auch "einer" mit 0 initialisiert.

```
s = 0;
while (s !=1 && s!=4)
{   
    einer = 0;
    while (zs>=10)
    { [...] 
    }
[...]
}
```
Allerdings halte ich Deine Lösung auch nicht für sehr glücklich. Einfacher ist es imho über eine rekursive Funktion, der Du die Zahl als String übergibst (vereinfacht das Durchlaufen der Ziffern). Das könnte etwa so aussehen:

```
public class HappyNumbers {

	public static boolean isHappyNumber(String number) {
	
		int digit, squareSum = 0;
		
		for(int i=0; i < number.length(); i++) {
			digit = number.charAt(i) - '0';			
			squareSum += digit * digit;
		}
		
		if (squareSum == 1) {
			return true;
		}
		
		if (squareSum == 4) {
			return false;
		}
		
		return isHappyNumber(String.valueOf(squareSum));
	}
	
	
	public static void main(String[] args) throws NumberFormatException {
		
		int num = Integer.parseInt(args[0]);
		
		for(int i=1; i <= num; i++) {
			if (isHappyNumber(String.valueOf(i))) {
				System.out.print(i + " ");
			}
		}
	}
}
```
Noch ein Tipp am Rande: Deine Variablenbezeichner sind nicht immer sehr aussagekräftig bzw. glücklich gewählt (s suggeriert eine String-Variable, getEiner eine Getter-Methode).

Gruß Dirk


----------



## Guest (7. Nov 2007)

Hallo Dirk,

Danke für deinen "Schlag auf den Hinterkopf" !!

Jetzt hab ich mich gefreut, dass ich bemerkt habe, dass s=0 gesetzt werden muss und dabei die anderen Variablen vergessen....ganz schön doof ....aber das sind dann ja hoffentlich die Sachen die ich in Zukunft nicht mehr falsch mache  :wink: 

Deine Tips zum Schluss entsprechen genau dem was auch mein Prof gesagt hat. Getters und Setters habe ich schonml gehört, aber werden erst im nächsten Kapitel behandelt....

Ich danke dir und den anderen für die Tips!!

Viele Grüße!!


----------

