# Lotto Zahlen Ziehung



## xam90 (14. Jan 2013)

Hallo muss eine Methode für Lotto Zahlen Ziehung schreiben!! jedoch kommt immer Müll raus 

```
public class Lotto{
  
  static int[] lottoZahlenZiehen(){
    java.util.Random rndGen = new java.util.Random();
    
    int [] ziehung = new int[6];
    for (int i = 1; i < ziehung.length; i++) {
      int zufallszahl = rndGen.nextInt(49) + 1;
      ziehung [i] = zufallszahl;
      
    } // end of for
    return ziehung;
    
  }
  
  public static void main(String[] args){
    
    Out.println(lottoZahlenZiehen());
    
  }
  
}
```


und als Ausgabe kommt z.B. : [I@5b3d9c02

Kann mir jemand helfen ?


----------



## Gast2 (14. Jan 2013)

Arrays haben leider keine schöne toString() Implementierung.
Du solltest mal folgendes ausgeben:

```
int[] ziehung = lottoZahlenZiehen();
Out.println(Arrays.toString(ziehung));
```

Außerdem ist deine for Schleife nicht korrekt initialisiert.


----------



## ARadauer (14. Jan 2013)

Out.println(Arrays.toString(lottoZahlenZiehen()));

Müll.. im Grunde der HexWert des HashCodes des Array...


----------



## Spin (14. Jan 2013)

Hey ho fang bitte bei i = 0 an und dann bis 6 (ohne die 6)

Und die Ausgabe: 

Sorry kein java zu hand : aber ist fast das gleiche 

```
val r = new java.util.Random();
val z = new Array[Int](6)
    
for(i <- 0 until 6) {
   z(i) = r.nextInt(49) + 1;
}
    
z.foreach(println _)
```

in java:

```
int[] ziehung = lottoZahlenZiehen();
for(int j = 0; j < ziehung.length; j++) {
 System.out.println(ziehung[j])
}
```

grüße spin


----------



## xam90 (14. Jan 2013)

aber ich brauch doch einen return-Wert ??!!!
und die Methode muss so heißen laut Aufgabe


----------



## njans (14. Jan 2013)

So sollte das auch gehen 

```
int[] zahlen = new int[49];
Collections.shuffle(Arrays.asList(zahlen ));
return zahlen;
```


----------



## Bleiglanz (15. Jan 2013)

Da oben vergessen alle, dass eine einmal gezogene Kugel nicht ein zweites mal gezogen werden kann, 6 mal Random.next() aufzurufen kann nicht funktionieren. Man muss wirklich shuffeln

```
public static int[] lotto(){
    int[] result = new int[6];
    List<Integer> trommel = new ArrayList<Integer>(49);
    for(int i=1;i<=49;i++) trommel.add(i);
    Collections.shuffle(trommel);
    for(int i=0;i<6;i++) result[i]=trommel.get(i);
    return result;
}
```


----------



## timbeau (15. Jan 2013)

Landei hatte auch etwas ohne zu schuffeln vorgestellt. 

Aus dem Gedächtnis und mit einer kurzen "statistik"-Klasse und kurz runtergetippt, sprich nicht, aber auch garnicht auf Performanz geachtet 

```
package tests;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import java.util.TreeMap;

public class Lotto {
	
	private static List<Integer> numbers = new ArrayList<Integer>();
	private static Random r = new Random();
	private static Stats stats = new Stats();
	
	
	public static void main(String[] args) {
		for (int i = 0; i < 10000; i++) {
			fillNumbers();
			runLotto();
		}
		
		stats.printStats();
		
		
	}

	private static void runLotto() {
		List<Integer> numbers = new ArrayList<Integer>();
		for (int i = 0; i < 6; i++) {
			numbers.add(getNumber());
		}
		System.out.println(numbers);
	}
	
	private static void fillNumbers(){
		numbers = new ArrayList<Integer>();
		for (int i = 1; i <= 49; i++) {
			numbers.add(i);
			
		}
	}
	
	private static int getNumber(){
		int idx = r.nextInt(numbers.size());
		int number = numbers.remove(idx);
		stats.count(number);
		return number;
	}

}

class Stats {
	private Map<Integer, Integer> counter = new TreeMap<Integer, Integer>();
	
	public Stats(){
		initMap();
	}
	
	private void initMap() {
		for (int i = 1; i <= 49; i++) {
			counter.put(i, 0);
		}
	}

	public void count(int number){
		int actualCounter = counter.get(number);
		actualCounter++;
		counter.put(number, actualCounter);
	}
	
	public void printStats(){
		Set<Integer> keys = counter.keySet();
		for (Integer integer : keys) {
			System.out.println(integer + " - " + counter.get(integer));
		}
		
	}
}
```


----------



## bone2 (15. Jan 2013)

Das ganze, große Array zu mischen kann niemals eine Empfehlung sein, wenn man nur ein paar wenige, zufällige Elemente aus diesem braucht. Den Gedankengang sollte man zügig wieder vergessen und sich überlegen, wie man so ein Problem vernünftig löst.


----------



## Bleiglanz (15. Jan 2013)

bone2 hat gesagt.:


> Das ganze, große Array zu mischen kann niemals eine Empfehlung sein, wenn man nur ein paar wenige, zufällige Elemente aus diesem braucht. Den Gedankengang sollte man zügig wieder vergessen und sich überlegen, wie man so ein Problem vernünftig löst.


Es geht um Lotto, um 49 Zahlen. Es ist vernünftig, das zu shuffeln, weil es eine schnelle einfache Lösung liefert die man ohne großen Trara implementieren kann.

Bei 49 Milliarden Kugeln ist das nicht optimal.

Die Lösung von timbeau ist natürlich auch sehr schön, weil da tatsächlich "gezogen" wird.


----------



## bone2 (15. Jan 2013)

Ich denke mir nur, wenn man bei kleinen Sachen anfängt, sich die faulen Lösungen zu nehmen, macht man das bei größeren Sachen nachher auch so. Getreu: was Hänschen nicht lernt, lernt Hans nimmermehr.
Eine vernünftige zieh-Lösung hat auch nur unwesentlich mehr zeilen.


----------



## Crian (15. Jan 2013)

Da hast du nicht ganz Unrecht, auf der anderen Seite sind Faulheit und code reuse gute Eigenschaften von Programmierern. *grinst*


----------



## hüteüberhüte (16. Jan 2013)

Dieses Thema gab es doch schon ausreichend oft:


```
int[] ia = new int[6];
a: for (int i = 0; i < 6;) {
  int r = random.nextInt(49) + 1;
  for (int j = 0; j < i; j++) {
    if (ia[j] == r) {
      continue a;
    }
  }
  ia[i++] = r;
}
```

Ist Imho für 6 aus 1 bis 49 am performantesten.

Grüßle


----------



## Marcinek (16. Jan 2013)

hüteüberhüte hat gesagt.:


> Ist Imho für 6 aus 1 bis 49 am performantesten.



Das würde wohl in die Liste schlechtesten Implementierung von Zufallszahlen fallen.

Bei Random, ohne wiederholung zieht man aus einer Liste und baut keine Liste zufällig auf.

Gruß,

Martin


----------



## hüteüberhüte (16. Jan 2013)

Marcinek hat gesagt.:


> Das würde wohl in die Liste schlechtesten Implementierung von Zufallszahlen fallen.



Nein, erzähl nicht so was.

1+2+3+4+5=15 Vergleichsoperationen + vielleicht 6 für die Generierung der Zahlen. Bei einer HashSet hätte man die Kosten fürs Erstellen und Einfügen (nicht = 1). Bei einem Array mit 49 Zahlen, 49 + die des Mischens.

Also versuche hier niemanden einen Bären aufzubinden, bitte.  Und klicke btw. auf danke.


----------



## hüteüberhüte (16. Jan 2013)

Was sogar ich nicht gut fände:


```
int[] ia = new int[6];
a: for (int i = 0;;) {
  int r = random.nextInt(49) + 1;
  for (int j = 0; j < i; j++) {
    if (ia[j] == r) {
      continue a;
    }
  }
  ia[i++] = r;
  if (i == 6) {
    break;
  }
}
```

was aber möglicherweise noch ein paar Vergleiche sparen könnte.


----------



## Marcinek (16. Jan 2013)

hüteüberhüte hat gesagt.:


> Also versuche hier niemanden einen Bären aufzubinden, bitte. Und klicke btw. auf danke.




Sarkasmus?


----------



## hüteüberhüte (16. Jan 2013)

Ich scherze nie.  [/IRONIE][/OT]


----------



## Spin (16. Jan 2013)

Scala:

```
lazy val r = new java.util.Random();
Array.fill(6)(r.nextInt(49) + 1)

// res1: Array[Int] = Array(24, 37, 38, 28, 24, 48)
// res2: Array[Int] = Array(44, 1, 30, 16, 43, 26)
```

Two Liner 

Sorry, aber wir sind ja eh dabei das Thema auszureizen


----------



## N3verM1nd (17. Jan 2013)

Er ist doch noch ein Anfänger 

So haben wir das letztes Jahr in der Schule machen müssen:

```
package Lotto; 
Lottopublic class Lotto{
  
  static int[] lottoZahlenZiehen(){
    java.util.Random rndGen = new java.util.Random();
    
    int [] ziehung = new int[6];
    for (int i = 1; i < ziehung.length; i++) //Wo beginnt der Index eines Arrays? Nicht bei 1!
    {
      int zufallszahl = rndGen.nextInt(49) + 1;
      ziehung [i] = zufallszahl;
      
    } // end of for
    return ziehung;
    
  }
  
  public static void main(String[] args){
    
    int[] ziehung = lottoZahlenZiehen();
    //und jetzt gibst du das Feld ganz brav aus :)
  }
  
}
```


----------



## hüteüberhüte (17. Jan 2013)

0 ist der Beginnindex. Ihr habt beide keine Überprüfung auf Mehrfachvorkommen.


----------



## Bleiglanz (17. Jan 2013)

Spin hat gesagt.:


> Scala:
> 
> ```
> lazy val r = new java.util.Random();
> ...



Aber nicht mit falschen Zweizeilern.


----------



## bone2 (17. Jan 2013)

hüteüberhüte hat gesagt.:


> Nein, erzähl nicht so was.
> 
> 1+2+3+4+5=15 Vergleichsoperationen + vielleicht 6 für die Generierung der Zahlen. Bei einer HashSet hätte man die Kosten fürs Erstellen und Einfügen (nicht = 1). Bei einem Array mit 49 Zahlen, 49 + die des Mischens.


hm sind es nicht eher:
3+5+7+9+11+13 und das auch nur wenn du keine random Zahl doppelt hast
edit: +7 der äußeren for schleife


----------



## timbeau (17. Jan 2013)

Fragt man sich echt, wie hier Lotto gespielt wird. 

Am performantesten ist doch wohl Zahlen innerhalb eines Arrays zu ziehen. Jetzt noch die Frage wie man die Zufallszahl bestimmt. 

Schneller als Random.nextInt dürfte das hier sein:


```
public static int randomInt() {
		long x = seed;
		x ^= (x << 21);
		x ^= (x >>> 35);
		x ^= (x << 4);
		seed = x;
		// x &= ((1L << nbits) -1);
		return ((int) x > 0) ? ((int) x) % MAX : ((int) x) * (-1) % MAX; 
	}
```

Frei nach XorShifting RNG.


----------



## hüteüberhüte (17. Jan 2013)

@bone2: Es ging ja um Performance, wie man es nun rechnet, sei mal dahingestellt. Du wirst in einem Test nichts schnelleres finden aber.

@timbeau: ... und der Seed kommt aus dem Nichts?


----------



## timbeau (17. Jan 2013)

Der seed kann z.B. die nanoTime sein. Muss aber nicht. 
Mit dir zu diskutieren hab ich aber eh keine Lust :bae:


----------



## hüteüberhüte (17. Jan 2013)

Dann keine Diskussion, hätte ich auch kein Lust jetzt, in Ordnung


----------

