Benötige Hilfe! Zufallszahlen eingrenzen (Lotto)



  • Hallo,
    ich habe ein Programm zur Ziehung der Lottozahlen geschrieben.
    Es zieht 6 Zahlen aus 49, ohne Zahlen zu wiederholen.

    Nun möchte ich (auf Grund statistischer Hintergründe) die Auswahl der Zahlen eingrenzen.
    1. Die Summe aller gezogenen Zahlen soll im Bereich 142-156 sein.
    2. Es sollen 2 zahlen < 25 und 4 Zahlen > 25 sein.
    3. 2 Zahlen sollen gerade sein und 4 ungerade.
    4. Es muss ein Zahlenpaarchen dabei sein.

    Da ich leider schon länger nicht mehr mit C++ gearbeitet hat komme ich zur Zeit da nicht weiter und hoffe das mir hier vielleicht jemand etwas unter die Arme greifen kann. Vielleicht sind meine Ziele auch garnicht möglich mit dem Programm so wie ich es habe.
    Also wäre super wenn mir jemand weiter helfen kann.

    Hier das Programm:

    #include <iostream>
    #include <time.h>
    using namespace std;

    int main ()
    {

    cout << "Dieses Programm bestimmt ihre 6 Lottozahlen" << endl;

    int zufallszahl[6];
    int i =0;
    int zahlen[49];
    int r;

    while (i < 6)
    {
    do
    {
    srand(time(NULL) * time(NULL));
    r = rand() % 49;
    }

    while (zahlen[r] == 1);
    zahlen[r] = 1;
    zufallszahl[i] = r+1;

    i++;
    }

    // Ausgabe der Zahlen
    for (int i=0; i<=5; i++)
    {
    cout << "Lottozahl " << i+1 <<": "
    << zufallszahl[i]
    << endl;
    }
    system("pause");
    return 0;
    }

    viellen Dank schon mal

    keyzer



  • Mach dir eine Klasse SupaDupaDistribution

    class SupaDupaDistribution
    {
    public:
     SupaDupaDistribution() : ..., dist(0,49), ... {}
     unsigned int operator()()
     {
      unsigned int n = dist(eng);
      if (good(n)) return n;
      else nochmal //(bzw while nicht good)
     }
    private:
     size_t count, odd, sum usw...
     std::mt19937 eng; // o.a.
     std::uniform_int<unsigned int> dist;
    };
    

    Das wär nen ganz simpler Ansatz.

    std::mt19937 und std::uniform_int<> sind tolle Klassen aus <random> aus dem neuen C++ Standard.



  • Wo liegt konkret dein Problem? Bei den Schleifen? Bei den Eingrenzungen?

    Gerade Zahlen:

    int i = 2;
    if (i%2 == 0)
       // Gerade Zahl
    

    Ungerade Zahl:

    int i = 3;
    if (i%2 != 0)
       // Ungerade Zahl
    

    Den zweiten Punkt (< & > 25) kannst du ganz einfach mit einem ähler lösen, oder halt indem du zwei Schleifen einbaust. Eine mit Zahlen über & einmal unter 25.(Fürs Pärchen ginge es thoretisch auch so.. ist aber glaube ich nicht so ganz sauber)

    Übrigens du erstellst Zufallszahlen zwischen 0-49 (r = rand() % 49;) Für 1-49 wäre das so:

    r = rand() % 49+1;
    


  • hi brotbernd,
    von Klassen/ SupaDupaDistribution hab ich noch nichts gehört da müsste ich erst mal nachlesen, verstehe auch nicht was dein Programm macht...

    Hi =),
    ich weiß nicht an welchem Teil meines Programms ich das einbinden muss.
    Noch oben in der while-do Schleife oder später erst?
    Ah und danke. Stimmt die 0 hab ich ganz vergessen... gibts ja garnet.



  • keyzer777 schrieb:

    [cpp]
    srand(time(NULL) * time(NULL));
    [/cpp[

    Was soll das denn?



  • brotbernd schrieb:

    class SupaDupaDistribution
    {
    public:
     SupaDupaDistribution() : ..., dist(0,49), ... {}
     unsigned int operator()()
     {
      unsigned int n = dist(eng);
      if (good(n)) return n;
      else nochmal //(bzw while nicht good)
     }
    private:
     size_t count, odd, sum usw...
     std::mt19937 eng; // o.a.
     std::uniform_int<unsigned int> dist;
    };
    

    Was soll das denn?



  • @ volkard
    das srand ist die random funktion!!!
    ich will ja nich immer die gleichen zahlen erhlaten!!

    sonst immmer noch keiner da, der mir hier weiter helfen kann?

    greez keyzer



  • Er meint wohl eher: time(NULL) * time(NULL) . Auch sollte srand nur einmal am Programmstart aufgerufen werden und nicht jedesmal in der Schleife.



  • tach, das gehört halt dazu!
    hab das irgendwo gelesen.
    das is ja auch nich mein problem.
    das funzt ja so.



  • Um ehrlich zu sein, ist das totaler Bockmist. Am besten schnappst du dir eine gutes Buch oder Tutorial. Ansonsten: Ziehe 6 Zufallszahlen, pruefe die Bedingungen und wenn sie erfuellt sind, dann speicherst du die 6 Zufallszahlen ab.



  • Was soll ein Zahlenpaar sein?

    #include <iostream>
    #include <time.h>
    
    int _tmain(int argc, _TCHAR* argv[])
    {
    	unsigned int zufallszahlen[6];
    	bool eindeutig = false;
    	bool valid = false;
    
    	unsigned int anzKlein = 0;
    	unsigned int anzGerade = 0;
    	unsigned int summe = 0;
    
    	srand((unsigned)time(NULL));
    
    	while (!valid)
    	{
    		anzKlein = 0;
    		anzGerade = 0;
    		summe = 0;
    
    		for (int i = 0; i<6; i++)
    		{
    			while (!eindeutig)
    			{
    				int zufallszahl = rand()%49+1;
    				zufallszahlen[i] = zufallszahl;
    				eindeutig = true;
    				for (int j = 0; j<i; j++)
    				{
    					if (zufallszahl == zufallszahlen[j])
    						eindeutig = false;
    				}
    			}
    			eindeutig = false;
    		}
    
    		for (int i = 0; i<6; i++)
    		{
    			if (zufallszahlen[i] <25)
    				anzKlein++;
    
    			if (zufallszahlen[i] %2 == 0)
    				anzGerade++;
    
    			summe += zufallszahlen[i];
    		}
    
    		if ((anzKlein == 2) && (anzGerade == 2))
    			valid = true;
    
    	}
    
    	for (int i = 0; i<6; i++)
    		std::cout << zufallszahlen[i] << " ";
    
    	getchar();
    	return 0;
    }
    

    Das kommentieren kannst du ja als Verständnisübung selber machen ^^



  • Für Zufallszahlen aus einer kleinen Menge ginge das hier. Es wird eine Menge aller möglichen Zufallszahlen erzeugt und gemischt. Anschliessend kann per next() die erste Zahl aus der Menge gelesen werden, die dann aus der Menge entfernt wird. Damit ist es unmöglich, Duplikate zu bekommen, da alle gezogenenen Zahlen aus der Menge der verbleibenden Kandiaten entfernt werden.

    #include <cassert>
    #include <vector>
    #include <iostream>
    #include <algorithm>
    
    class RangeRNG
    {
       std::vector<unsigned int> Numbers_;
    
    public:
       RangeRNG( unsigned int Min, unsigned int Max )
       {
          First = std::min( Min, Max );
          Last  = std::max( Min, Max );
    
          Numbers_.reserve( Last - First +1 );
    
          while( First <= Last ) Numbers_.push_back( First++ );
          std::random_shuffle( Numbers_.begin(), Numbers.end() );
       }
    
       bool empty() const
       {
          return Numbers_.empty();
       }
    
       unsigned int next()
       {
          assert( !empty() );
    
          // aus Performancegründen werden Zahlen von hinten aus
          // dem Vektor entfernt... auch wenn´s nur Spielerei ist
          unsigned int n = Numbers_.back();
          Numbers_.erase( Numbers_.end() -1 );
          return n;
       }
    };
    
    int main()
    {
       RangeRNG Lottoziehung( 1,49 );
    
       for( unsigned int i = 0; i < 6; ++i )
       {
          std::cout << "Zahl " << i << ": " << Lottoziehung.next() << std::endl;
       }
    }
    

    Edit: Anfangsposting nur halb gelesen und für das typische Anfänger-Lottozahlen-Problem gehalten und dazu eine Lösung gebastelt...



  • dann erklähr mir doch bitte mal warum das bullshit ist!?
    es funktionier doch so!
    ich habe jetzt auch meine erste anforderung gelöst mit ner do-while schleife.
    aber wenn er keine zahlen mit der summe zwischen 142-156 findet, dauert jede neue berechnung der zahlen immer länger.
    was kann ich machen um den zwichenspeicher zu löschen, das er quasi wieder ganz von forne anfängt?



  • uuuups nicht aktuallisiert!

    ein zahlen paar = zwei auf einander folgende zahlen z.b. 35, 36



  • #include "stdafx.h"
    #include <iostream>
    #include <time.h>
    #include <string>
    
    int _tmain(int argc, _TCHAR* argv[])
    {
    	unsigned int zufallszahlen[6];
    	bool eindeutig = false;
    	bool valid = false;
    
    	unsigned int anzKlein = 0;
    	unsigned int anzGerade = 0;
    	unsigned int summe = 0;
    
    	srand((unsigned)time(NULL));
    
    	while (!valid)
    	{
    
    		for (int i = 0; i<6; i++)
    		{
    			while (!eindeutig)
    			{
    				int zufallszahl = rand()%49+1;
    				zufallszahlen[i] = zufallszahl;
    				eindeutig = true;
    				for (int j = 0; j<i; j++)
    				{
    					if (zufallszahl == zufallszahlen[j])
    						eindeutig = false;
    				}
    			}
    			eindeutig = false;
    		}
    
    		// sortieren
    		for (int i = 0; i<6-1; i++)
    		{
    			for (int j = i+1; j<6; j++)
    			{
    				if (zufallszahlen[i] > zufallszahlen[j])
    				{
    					int temp = zufallszahlen[i];
    					zufallszahlen[i] = zufallszahlen[j];
    					zufallszahlen[j] = temp;
    				}
    			}
    		}
    
    		anzKlein = 0;
    		anzGerade = 0;
    		summe = 0;
    
    		// Kleine zählen
    		for (int i = 0; i<6; i++)
    			if (zufallszahlen[i] <25)
    				anzKlein++;
    
    		// Gerade zählen
    		if (anzKlein == 2)
    		{
    			for (int i = 0; i<6; i++)
    				if (zufallszahlen[i] %2 == 0)
    					anzGerade++;
    
    			// Summe berechnen
    			if (anzGerade == 2)
    			{
    				for (int i = 0; i < 6; i++)
    					summe += zufallszahlen[i];
    
    				// Nach Pärchen prüfen
    				if (summe >=142 && summe <= 156)
    					for (int i = 0; i<6-1; i++)
    						if (zufallszahlen[i]+1 == zufallszahlen[i+1])
    							valid = true;
    			}
    		}
    	}
    
    	for (int i = 0; i<6; i++)
    		std::cout << zufallszahlen[i] << " ";
    
    	getchar();
    	return 0;
    }
    


  • keyzer777 schrieb:

    dann erklähr mir doch bitte mal warum das bullshit ist!?
    es funktionier doch so!

    Nö, tuts nicht, du erkennst es bloß nicht. Wenn du zu faul bist zu googlen und ein wenig selbst nachzudenken, probier doch mal sowas:

    while(true)
    {
        srand(time(NULL));
        int i = rand();
        cout << i << "\n";
    }
    


  • @matze-o:

    Mit welcher IDE arbeitest du? Unter Code-Blocks wurden mehrere Fehler ausgegeben.
    Unter Einbindung dieser Bibliotheken geht es:

    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <time.h>
    


  • hi matze-o
    bei deinem programm blicke ich so einigermasen durch leider funzt es nicht.

    `_TCHAR has not been declared

    auch mit #include "stdafx.h"

    kann ich nichts anfangen

    grüße

    ach noch ne frage kanns auch daran liegen das ich nur den dev-C++ nutze?



  • keyzer777 schrieb:

    hi matze-o
    bei deinem programm blicke ich so einigermasen durch leider funzt es nicht.

    Doch es funktioniert, musst nur die includes ändern:

    #include <iostream> 
    #include <cstdio> 
    #include <cstdlib> 
    #include <time.h>
    

    Und lad dir anstatt devc++ lieber Code::Blocks, das wir noch weiterentwickelt!



  • volkard schrieb:

    brotbernd schrieb:

    class SupaDupaDistribution
    {
    public:
     SupaDupaDistribution() : ..., dist(0,49), ... {}
     unsigned int operator()()
     {
      unsigned int n = dist(eng);
      if (good(n)) return n;
      else nochmal //(bzw while nicht good)
     }
    private:
     size_t count, odd, sum usw...
     std::mt19937 eng; // o.a.
     std::uniform_int<unsigned int> dist;
    };
    

    Was soll das denn?

    Das ist ne Mischung aus C++ und Pseudocode 😃
    Ziehe ne Zufallszahl so lange sie bestimmte Bedingungen erfüllt. Ich dachte das könne man vielleicht daraus ablesen.


Anmelden zum Antworten