# lotto 6 aus 45, doppelte zahlen vermeiden



## MasterOfTheDark (22. Oktober 2008)

hallo!

hab mal aus fun versucht Lotto zu programmieren, leider tritt oft das Problem auf, dass eine zahl 2 mal vorkommt und wollte euch jetzt nach Hilfe fragen.


```
#include <cstdlib>
#include <iostream>
#include <windows.h>

using namespace std;

int main(int argc, char *argv[])
{
    int wuerfel,i;
    char janein,Janein;
    do
    {
    printf("willkommen beim Lotto 6 aus 45\n");
    srand(time(NULL));
    wuerfel=rand()%45+1;
    for(i=20;i>0;i--)//verzögerung der ausgabe
         {
             Sleep(50);
             printf("-");
         }
    printf("%d\n",wuerfel);    
    wuerfel=0;
    wuerfel=rand()%45+1;
    for(i=20;i>0;i--)//verzögerung der ausgabe
         {
             Sleep(50);
             printf("-");
         }
    printf("%d\n",wuerfel);    
    wuerfel=0;
    wuerfel=rand()%45+1;
    for(i=20;i>0;i--)//verzögerung der ausgabe
         {
             Sleep(50);
             printf("-");
         }
    printf("%d\n",wuerfel);    
    wuerfel=0;
    wuerfel=rand()%45+1;
    for(i=20;i>0;i--)//verzögerung der ausgabe
         {
             Sleep(50);
             printf("-");
         }
    printf("%d\n",wuerfel);    
    wuerfel=0;
    wuerfel=rand()%45+1;
    for(i=20;i>0;i--)//verzögerung der ausgabe
         {
             Sleep(50);
             printf("-");
         }
    printf("%d\n",wuerfel);    
    wuerfel=0;
    wuerfel=rand()%45+1;
    for(i=20;i>0;i--)//verzögerung der ausgabe
         {
             Sleep(50);
             printf("-");
         }
    printf("%d\n",wuerfel);    
    wuerfel=0;
    printf("willst du weiterspielen?[J/N]\n");     
    fflush(stdin);
    scanf("%c", &janein);
    system("cls");
    }
    while(janein=='J' || janein=='j');
    system("PAUSE");
    return EXIT_SUCCESS;
}
```

funktioniert das nur mit langwierigen if-Anweisungen, oder geht das auch schneller?

lg MasterOfDarkness


----------



## deepthroat (22. Oktober 2008)

Hi.

Natürlich geht das viel schneller. Du solltest du entsprechende Funktionalität in eigene Funktionen auslagern.

In C++ wäre es am Einfachsten einen vector mit 45 "Kugeln" zu füllen, dessen Elemente dann in eine zufällige Reihenfolge zu bringen und nur die ersten 6 Elemente auszugeben.

Gruß


----------



## chmee (22. Oktober 2008)

Die Idee mit dem Vector ist gut, ich dachte an die simplere Methode, ein Array in einer Schleife zu füllen. Natürlich wird eine Zahl nur zum Array hinzugefügt, wenn sie nicht schon drin ist.

Da ich kein C programmiere, hier eine Codeform, die aber noch ins Reine gebracht werden muss, das ist Kauderwelsch, man möge mir vergeben 


```
int Zahlen() // keine Ahnung wie Arrays in C aussehen
for(Zug=1;Zug>6;Zug++) //6 Züge
{
  gibtsschon=0;            
  repeat
    wurf=rand()%45+1;
    for(Prüfung=0;Prüfung>Zug;Prüfung++)
      { 
       if(wurf=Zahlen(Prüfung)) {gibtsschon=1;}
      }
   until(gibtsschon=0)
   Zahlen(Zug)=wurf;
}
for(Zahlenzeigen=0;Zahlenzeigen>6;i++)
{
  printf Zahlen(i)
  // Pause für die Spannung :)
}
```

mfg chmee


----------



## MasterOfTheDark (22. Oktober 2008)

mit array hab ichs auch versucht, nur nicht hinbekommen


----------



## deepthroat (22. Oktober 2008)

Hi.

Mein Vorschlag in C++:

```
#include <string>
#include <iostream>
#include <algorithm>
#include <iterator>

#include <cstdlib>


using namespace std;

class seq {
  char current;

public:
  seq(char init) : current(init) { }

  char operator() () {
	return current++;
  }
};

int main(int argc, char *argv[])
{
  string pool;

  srand(time(NULL));

  generate_n(back_inserter(pool), 45, seq(1));

  random_shuffle(pool.begin(), pool.end());

  copy(pool.begin(), pool.begin() + 6,
	   ostream_iterator<int>(cout, " "));

  cout << endl;

  return 0;
}
```
Gruß


----------



## MasterOfTheDark (22. Oktober 2008)

```
#include <cstdlib>
#include <iostream>
#include <windows.h>

using namespace std;
int main(int argc, char *argv[])
{
int Zahlen[7]; // für 6 speicherplätze
int Zug;
int i;
int gibtsschon;
int Zahlenzeigen;
int Pruefung;
int wurf;
{   

for(Zug=1;Zug>6;Zug++) //6 Züge
{
  gibtsschon=0;            
  do
  {
    wurf=rand()%45+1;
    for(Pruefung=0;Pruefung>Zug;Pruefung++);
      { 
       if(wurf=Zahlen[Pruefung])
       {
          gibtsschon=1;
       }
      }
   }
   while(gibtsschon=0);
   Zahlen[Zug]=wurf;
}
for(Zahlenzeigen=0;Zahlenzeigen>6;Zahlenzeigen++)
{
  printf("%d",Zahlen[i]);
  for(i=10;i>0;i--)
  {
      Sleep(50);
      printf("-");
  }
}
}
system("PAUSE");
return EXIT_SUCCESS;
}
```
naja, fehlermeldungen weg, aber im ausgabefenster erscheint nur"drücken sie eine beliebige taste...."?


----------



## engelmarkus (22. Oktober 2008)

Ich glaube, du hast da ein paar Strichpunkte vergessen? Oder ist die geschweifte Klammer an der falschen Stelle?


```
int main(int argc, char *argv[])
{
int Zahlen[7]; // für 6 speicherplätze
int Zug;
int gibtsschon;
int Prüfung;
int wurf;
```


----------



## deepthroat (22. Oktober 2008)

MasterOfTheDark hat gesagt.:


> ```
> int Zahlen[7] // für 6 speicherplätze
> ```


Das Array bietet 7 Speicherplätze, von 0 bis 6.


MasterOfTheDark hat gesagt.:


> ```
> gibtsschon=0;
> repeat
> wurf=rand()%45+1;
> ...


Wie von chmee bereits gesagt, ist das nur Pseudocode. Du mußt erstmal den Code verstehen und die Sachen die es in C/C++ nicht gibt, durch entsprechende Befehle ersetzen. repeat und until gibt's doch gar nicht, da mußt du eine Schleife bauen.

Mach es dir einfach und nutze Funktionen. Sonst siehst du doch schon jetzt nicht mehr durch. Schreibe dir erstmal 

1) eine Funktion die eine Zahl von 1 bis 45 zurückgibt

2) eine Funktion die prüft ob eine gegebene Zahl bereits in einem Array enthalten ist und entweder true oder false zurückgibt.

Wenn du das hast und es getestet ist und funktioniert, dann kannst du anfangen das zusammenzubauen.

Gruß


----------



## MasterOfTheDark (22. Oktober 2008)

1) funktion zum zurückgeben:
srand(time(NULL));
array[7]=rand()%45+1;

2) aber hier das problem, hab keinen schimmer wie das funktioniern sollte, odcer ich steh einfach auf der leitung..

mfg Master


----------



## deepthroat (22. Oktober 2008)

MasterOfTheDark hat gesagt.:


> 1) funktion zum zurückgeben:
> srand(time(NULL));
> array[7]=rand()%45+1;


Das ist Unsinn. Das ist weder eine Funktion, noch ist es sinnvoll srand mehrfach im Programm aufzurufen. Weiter gibt es den Index 7 bei array gar nicht und das Ermitteln der Zufallszahl sollte man eigentlich nicht auf diese Weise machen. Das Array hat außerdem in der Funktion überhaupt nichts zu suchen.


MasterOfTheDark hat gesagt.:


> 2) aber hier das problem, hab keinen schimmer wie das funktioniern sollte, odcer ich steh einfach auf der leitung..


Du bist zu voreilig. Du bist ja noch nicht mal mit der ersten Funktion fertig. Und mit testen meine ich auch testen. D.h. z.B. ein Testprogramm zu schreiben welches automatisch die Richtigkeit der Funktionswerte überprüft.

Wenn du dann mal die Funktion für die Zufallszahlen hast, dann brauchst du eine Datenstruktur um die 6 Werte zu sammeln. Dafür kannst du natürlich ein Array mit einer festen Größe nehmen. Dann mußt du dir aber erstmal merken wieviel Elemente überhaupt in dem Array drin sind. Die Suchfunktion müßte dann so aussehen:

```
bool istschondrin(int array[], int anzahl_der_eintraege_im_array, int such_mich) {
  // Array nach such_mich durchsuchen, wenn gefunden return true
  for (...)  {
    if (...) return true;
  }
  return false;
}
```
\edit: Wenn diese Funktion implementiert ist, erstmal testen! D.h. ein paar Arrays nehmen und die Funktion damit aufrufen und überprüfen ob das richtige rauskommt:

```
int a1[] = { 1, 2, 3, 4, 5 };
cout << boolalpha << "a1: " << istschondrin(a1, sizeof(a1)/sizeof(*a1), 6) << " == false" << endl;
...
```
Gruß

PS: Bitte halte dich an die Netiquette, Punkt 15 - Groß/Kleinschreibung. Danke.


----------



## RenderWilli (22. Oktober 2008)

```
int zahlen[45];
for (int i=0; i<45; i++){zahlen[i]=i+1;}
srand(time(NULL));
for (int i=0; i<45; i++)
{
	int tausch = rand()%45;
	int buffer = zahlen[i];
	zahlen[i] = zahlen[tausch];
	zahlen[tausch] = buffer;
}
```

Wenn du jetzt die ersten 6 Werte aus zahlen[] ausliest, hast du deine Lottozahlen.


----------



## MasterOfTheDark (22. Oktober 2008)

danke,es funktioniert
aber ich kann es nicht nachvoll ziehen, da ich mit dem in der letzten for schleife nichts anfangen kann. 

lg Master


----------



## Jochen_Schneider (22. Oktober 2008)

Ich darf mal gerade:

Die For-Schleife ist nichts anderes als eine Shuffle-Routine, d.h. das zuvor mit den 46 Zahlen gefüllte Array wird durcheinandergewürfelt.

Zeile 1 der Schleife ermittelt eine Zufallszahl zwischen 1 und 46. Der Inhalt des Arrays _zahlen_ an der Stelle _i_ wird in eine temporäre Variable _buffer_ geschrieben, um ihn zu sichern (Zeile 2). Das Element des Arrays _zahlen_ wird dann an der jeweiligen Stelle _i_ durch das Element desselben Arrays an der Stelle der Zufallszahl ersetzt (Zeile 3). Schließlich wird das nun doppelt vorhandene Element an der Stelle der Zufallszahl durch die gesicherte Zahl ersetzt (Zeile 4).

Beispiel:

Schleife läuft zum ersten Mal -> i=0. Also:

Annahme: tausch = 20.
buffer = zahlen[0]
zahlen[0] = zahlen[20]
zahlen[20] = buffer
Ich hoffe das war jetzt mehr verständlich. Ist nichts anderes als ein Dreieckstausch.


----------



## chmee (22. Oktober 2008)

Was ich aber nicht gutheißen kann, werter MasterOfTheDark, ist, dass Du an diesem kleinen Versuch, ein Lottospiel zu schreiben, nichts gelernt hast. Ganz ehrlich, Dein erster Versuch brachte nicht das erhoffte Ergebnis ( es war abzusehen, dass gleiche Zahlen auftreten können ) und mit den Tipps konntest Du nichts anfangen, weil Du scheinbar gar keine Lust hast, etwas dabei zu lernen. Sogar in Deinem ersten Versuch hast Du die 6 Zahlzüge nicht in Schleife realisiert, sondern "stümperhaft" hintereinanderkopiert. Nun hast Du eine Lösung, die Du nicht verstehst, geschweige denn selbst geschrieben hast. Schade.. mfg chmee

p.s.: Vielleicht seh ich es zu eng, und Du solltest nur für den gehassten Informatik-Unterricht eine Hausaufgabe präsentieren, naja, ist dann wohl geschafft.


----------



## RenderWilli (23. Oktober 2008)

In erster Linie sollte gezeigt werden, dass es eine einfache Lösung gibt und das es funktioniert. Das Verständnis stellt sich nach Erfolgen ein und aus positiven Erlebnissen lernt man. Ich denke, es bringt nichts, wenn man tagelang an einem kleinen Problem sitzt, denn das baut eher Frust auf. Ausserdem wurden mehrere (komplexe) Lösungsansätze vorgeschlagen (Arrays&Vektoren) und das kann einen Anfänger doch sehr überfordern!
Also alles einfach halten und wenn man dann noch Lust zum Experimentieren hat, kommt das Verständnis von alleine.

Schöne Grüße,
Willi


----------



## deepthroat (23. Oktober 2008)

RenderWilli hat gesagt.:


> In erster Linie sollte gezeigt werden, dass es eine einfache Lösung gibt und das es funktioniert. Das Verständnis stellt sich nach Erfolgen ein und aus positiven Erlebnissen lernt man.


Ich würde es für mich allerdings eher nicht als Erfolg verbuchen, wenn mir jemand einfach die Lösung vorgibt. Mich würde es eher frustrieren auf die Lösung nicht selber gekommen zu sein, besonders wenn ich die vorgegebene Lösung noch nicht mal verstehe.


RenderWilli hat gesagt.:


> Ausserdem wurden mehrere (komplexe) Lösungsansätze vorgeschlagen (Arrays&Vektoren) und das kann einen Anfänger doch sehr überfordern!


Diese Konzepte (Arrays und Vektoren) sind beide gleichwertig und ich halte Arrays gerade für Anfänger für schwieriger als einen std::vector oder string, da diese dynamisch zu erweitern sind und sie ihre Größe selbst verwalten.


RenderWilli hat gesagt.:


> Also alles einfach halten und wenn man dann noch Lust zum Experimentieren hat, kommt das Verständnis von alleine.


Ja, dem stimme zu. Das erste Problem dürfte aber sein: Wie gehe ich vor wenn ich ein Programm schreiben will? Das lernt man nicht durch einfache Beispiele. Da ist es wichtig von Anfang an Programme zu strukturieren um die Komplexität möglichst gering zu halten. Allzu oft verstrickt man sich durch Schachtelung von Schleifen in der 6ten Ebene und obwohl der Code "relativ einfach ist" sieht man nicht mehr durch.

@MasterOfTheDark: Du hast jetzt eine Lösung. Allerdings schien dir ja mein Vorschlag 45 Elemente eines Vektors/Arrays/Strings/... in eine zufällige Reihenfolge zu bringen und dann die ersten 6 auszuwählen nicht zuzusagen und du wolltest anscheinend lieber 6 Elemente ohne Duplikate in ein Array speichern. Vielleicht verfolgst du ja dieses Ziel einfach weiter und versuchst diese Idee doch noch zu implementieren.

Gruß

PS: @RenderWilli: Es sollte nur 6 aus 45 sein, nicht 46.


----------



## RenderWilli (23. Oktober 2008)

> Es sollte nur 6 aus 45 sein, nicht 46.


Ok, danke!


----------



## Zvoni (23. Oktober 2008)

Oder man macht als erstes das, was man normalerweise in einem Forum macht, nämlich suchen, weil dann hättest du auch diesen Thread hier gefunden:

http://www.tutorials.de/forum/coder...ansatz-fuer-den-lotto-problem-algoritmus.html


----------



## chmee (23. Oktober 2008)

OFFTOPIC

Die Erstanfrage wurde gestern gegen 16:48 gestellt. Heisst also, innerhalb von knapp 5 Stunden gab es 3 Lösungsansätze mit 2 funktionierenden Copy&Paste-Codes. Wenn es Interesse für das Coden gäbe, sollte man einem "Beginner" doch auch klar machen, dass Coding etwas mit Geduld und Tee zu tun hat und nicht mit (mein Eindruck Scriptkiddie&Copy&Paste.

Ich werde das Gefühl nicht los, dass Du, werter MasterOfTheDark eher nach einer schnellen Lösung und nicht nach einem Lernerfolg aus warst.

mfg chmee


----------



## MasterOfTheDark (23. Oktober 2008)

chmee hat gesagt.:


> Was ich aber nicht gutheißen kann, werter MasterOfTheDark, ist, dass Du an diesem kleinen Versuch, ein Lottospiel zu schreiben, nichts gelernt hast. Ganz ehrlich, Dein erster Versuch brachte nicht das erhoffte Ergebnis ( es war abzusehen, dass gleiche Zahlen auftreten können ) und mit den Tipps konntest Du nichts anfangen, weil Du scheinbar gar keine Lust hast, etwas dabei zu lernen. Sogar in Deinem ersten Versuch hast Du die 6 Zahlzüge nicht in Schleife realisiert, sondern "stümperhaft" hintereinanderkopiert. Nun hast Du eine Lösung, die Du nicht verstehst, geschweige denn selbst geschrieben hast. Schade.. mfg chmee
> 
> p.s.: Vielleicht seh ich es zu eng, und Du solltest nur für den gehassten Informatik-Unterricht eine Hausaufgabe präsentieren, naja, ist dann wohl geschafft.




mit dem Informatikunterricht liegst du richtig, allerdings ist er alles andere als gehasst, ich wusste hier einfach nicht weiter.

Lg Master

PS: danke an alle, die geholfen haben


----------

