Lottozahlengenerator



  • Hallo, ich bin dabei mir selbst ein bisschen C++ beizubringen und habe da online ein paar Aufgaben gefunden, allerdings keine Lösungen. Für eine Aufgabe interessiere ich mich sehr stark. Das ist der Lottozahlengenerator (vielleicht werde ich ja mal Millionär :D)

    Ich möchte dafür gerne arrays benutzen.
    Man soll dem Programm sagen können wie viele mögliche Lösungen man haben möchte (max 12, weil mehr darf man ja glaub ich beim echten Lotto auch nicht?).
    Das Programm soll keine doppelten Zahlen ausgeben.
    Und die Zahlen sollen von klein nach groß sortiert werden.

    Gibt es da schon ein fertiges Programm, welches ich mir mal angucken könnte. Also den kompletten Code, damit ich das dann nochmal neu schreiben kann? Kann mir was neues am Besten beibringen, wenn ich mir ein fertiges Programm angucke und dann neu für mich aufschreibe.

    Vielen Dank schonmal im Voraus!



  • Wenn du die gesamte Aufgabenstellung postest, gibt es bestimmt jemanden der dir das schreibt. Aber so ist die Beschreibung zu ungenau, was genau soll das Programm generieren? Und warum sind das "Lösungen"? (Ich spiele kein Lotto, entschuldigt falls das irgendwie selbsterklärend sein sollte.)



  • 1. Dein Lern-Stil ist sehr merkwürdig. Mach/Versuch es doch selbst. 🙂
    2. Anzahl möglicher Lösungen? Hmmm? Weiß nicht was du meinst.

    Wie auch immer, das ist IMO sehr einfach; alles was du wissen brauchst, ist folgendes (ich nehme einfach mal so an, du bist vollkommener Anfänger):

    std::cin
    std::cout
    std::random_shuffle() (kannst dir auch eine Funktion dafür schreiben, meine Empfehlung)
    std::vector
    Schleifen
    ... (übliches, grundlegenes Zeux)

    Du schreibst also alle Zahlen von 1 - 49 in einen vector, random-shufflest sie und nimmst die ersten 6 (oder 7? Keine Ahnung 😃 ).
    Anschließend vergleichst du sie mit den eingelesenen (ja, du liest auch vorher 7 Werte ein und speicherst sie in einem vector 🙄 ).



  • Also Aufgabe ist mal grob von mir geschrieben:

    Entwickle einen Lottozahlengenerator, der x-mal (x soll maximal 12 sein) 6 Zahlen aus dem Bereich 1-49 ausgibt, dabei aber keine pro Reihe doppelt ist. Als Eingabe soll gemacht werden, wie viele Reihen "gedruckt" werden sollen (wie oben beschrieben max 12). Die Zahlen sollen anschließend pro Reihe von klein nach groß sortiert werden.

    Bsp. Ausgabe:
    4 15 36 41 45 48
    2 8 19 27 39 41
    .....................



  • Deniska93 schrieb:

    Also Aufgabe ist mal grob von mir geschrieben:
    Die Zahlen sollen anschließend pro Reihe von klein nach groß sortiert werden.

    Hmmm, das ist aber nicht übliches Lotto! 😮 😃



  • Es geht nicht um Lotto, sondern um das automatische generieren von den 6 Zahlen, die man beim Lottoschein dann am Ende ankreuzt. 😉

    Also er sagt mir 6 Zahlen und ich kreuz die dann auf dem zettel an 😛



  • Du meinst also die "Super 6" und nicht "6 aus 49". 😃



  • Deniska93 schrieb:

    Es geht nicht um Lotto, sondern um das automatische generieren von den 6 Zahlen, die man beim Lottoschein dann am Ende ankreuzt. 😉

    Also er sagt mir 6 Zahlen und ich kreuz die dann auf dem zettel an 😛

    Haha, nicht ehrlich? Willst du jetzt ein Programm schreiben, dass dir zum Lotto-Gewinn verhilft...? 🙄



  • Deniska93 schrieb:

    Gibt es da schon ein fertiges Programm, welches ich mir mal angucken könnte. Also den kompletten Code, damit ich das dann nochmal neu schreiben kann? Kann mir was neues am Besten beibringen, wenn ich mir ein fertiges Programm angucke und dann neu für mich aufschreibe.

    Abschreiben bringt beim Auswendiglernen vielleicht was, aber beim Programmieren gehts ums Verstehen. Deshalb nutzt selber denken da meist mehr. Aber na gut:

    #include <ctime>
    #include <set>
    #include <iostream>
    int main() {
    	using namespace std;
    	srand(static_cast<unsigned int>(time(0)));
    	typedef set<int> TZahlen;
    	cout << "Wie viele Runden?\n";
    	int runden;
    	cin >> runden;
    	runden = std::min(runden, 12);
    	for(int i = 0; i < runden; ++i) {
    		TZahlen zahlen;
    		do {
    			zahlen.insert(rand() % 48 +1);
    		} while(zahlen.size() != 6);
    		for(auto it = zahlen.begin(); it != zahlen.end(); ++it)
    			cout << *it << ' ';
    		cout << "\n";
    	}
    }
    

    Da du es ja mit arrays haben willst, musst du ja doch noch selbst denken, um es diesbezüglich umzuschreiben. 😉

    Edit: seed noch eingebaut ; )



  • Doch 6 aus 49 😃

    Nochmal das Beispiel 😃

    Reihe 1: 8 12 15 25 26 31
    Reihe 2: 5 11 26 37 42 49
    Reihe x: ................

    😃



  • Danke Dobi!

    Aber bei dem programm kommt bei mir eine Fehlermeldung.

    In function `int main()':
    ISO C++ forbids declaration of 'it' with no type
    cannot convert 'std::_Rb_tree_const_iterator<int>' to 'int' in initialization



  • Gut, dann halt so:

    #include <ctime>
    #include <set>
    #include <iostream>
    int main() {
        using namespace std;
        srand(static_cast<unsigned int>(time(0)));
        typedef set<int> TZahlen;
        cout << "Wie viele Runden?\n";
        int runden;
        cin >> runden;
        runden = std::min(runden, 12);
        for(int i = 0; i < runden; ++i) {
            TZahlen zahlen;
            do {
                zahlen.insert(rand() % 48 +1);
            } while(zahlen.size() != 6);
            for(TZahlen::iterator it = zahlen.begin(); it != zahlen.end(); ++it)
                cout << *it << ' ';
            cout << "\n";
        }
    }
    


  • Vielen vielen Dank!

    Sieht gut aus, ich verstehe es sogar fast komplett. Bis auf das mit dem typedef set<int> TZahlen;

    aber Danke vielmals!!



  • Das set ( http://www.cplusplus.com/reference/stl/set/ ) ist das, was die eigentliche Arbeit macht. Es sorgt dafür, dass keine Zahl doppelt vorkommt und dass sie geordnet werden.
    Deine Aufgabe ist es ja jetzt, diese Dinge mit den von dir gewünschten Arrays zu implementieren.



  • Finde die Lösungen der Art "versuche so lange bis..." nicht so schön. Alternative:

    #include <ctime>
    #include <vector>
    #include <iostream>
    #include <iomanip>
    #include <iterator>
    #include <algorithm>
    
    struct Generator
    {
    	unsigned int Next;
    
    	Generator() : Next( 0 )
    	{
    	}
    
    	unsigned int operator()()
    	{
    		return ++Next;
    	}
    };
    
    int main()
    {
    	std::srand( std::time( 0 ) );
    	std::vector<unsigned int> Numbers;
    
    	std::generate_n( std::back_inserter( Numbers ), 49, Generator() );
    
    	for( unsigned int i = 0; i < 12; ++i )
    	{
    		std::random_shuffle( Numbers.begin(), Numbers.end() );
    		std::sort( Numbers.begin(), Numbers.begin() +6 );
    		std::copy( Numbers.begin(), Numbers.begin() +6, std::ostream_iterator<unsigned int>( std::cout, " " ) );
    		std::cout << "\n";
    	}
    }
    


  • DocShoe schrieb:

    ...

    👍


  • Mod

    DocShoe schrieb:

    Finde die Lösungen der Art "versuche so lange bis..." nicht so schön. Alternative:

    Ich mag aber auch nicht die Einstellung, unnötig viele Zufallszahlen zu ziehen, wenn wir nur 6 möchten:

    #include <vector>
    #include <iterator>
    #include <algorithm>
    #include <iostream>
    #include <cstdlib>
    
    using namespace std;
    
    template <class RandomAccessIterator, class Size, class RandomNumberGenerator>
    void random_shuffle_n (RandomAccessIterator first, 
                           RandomAccessIterator last, 
                           Size N,
                           RandomNumberGenerator& rng)
    {
      iterator_traits<RandomAccessIterator>::difference_type distance = last - first, i;
      for (; i < N; ++i)
        swap(first[i], first[rng() % distance]);
    }
    
    template <class RandomAccessIterator, class Size>
    void random_shuffle_n (RandomAccessIterator first, 
                           RandomAccessIterator last, 
                           Size N)
    {
      random_shuffle_n(first, last, N, std::rand);
    }
    
    int counter () { static int current = 0; return ++current; }
    
    int main()
    {
      vector<int> zahlen;
      generate_n(back_inserter(zahlen), 49, counter);
      for (int i = 0; i < 12; ++i ) 
        {
          random_shuffle_n(zahlen.begin(), zahlen.end(), 6);
          ostream_iterator<int> out_it (cout," ");
          sort(zahlen.begin(), zahlen.begin()+6);
          copy(zahlen.begin(), zahlen.begin()+6, out_it);
          cout << '\n';
       }
    }
    


  • Hatte ich mir auch überlegt, aber weil es im Standard keinen random_shuffle_n gibt und ich zu faul war, das auch noch zu machen, hab´ ich´s sein gelassen.

    PS:
    Wenn du den RandomNumberGenerator nicht als Referenz sondern per Value übergibst kann man auch temporäre Generatorobjekte benutzen.



  • Hehe, hübsch. 🙂
    Irgendwie déjà-vue ich gerade. Hatten wir sowas nicht schonmal und damals sogar rumgerechnet und profiled bis welches n es schneller ist, einfach solange Zahlen zu ziehen bis man n verschiedene hat?


  • Mod

    Dobi schrieb:

    Hehe, hübsch. 🙂
    Irgendwie déjà-vue ich gerade. Hatten wir sowas nicht schonmal und damals sogar rumgerechnet und profiled bis welches n es schneller ist, einfach solange Zahlen zu ziehen bis man n verschiedene hat?

    Ja, das haben wir alle paar Monate mal. Bei 6 aus 49 haben (leider) immer die naiven Wegwerfalgorithmen gewonnen, also wie z.B. deiner (wobei vector dort deutlich schneller wäre als set, weil die Zahl 6 so klein ist). Was natürlich für Anfänger nicht so doll ist, weil sie dann keine Motivation haben, bessere Algorithmen zu benutzen. Aber für Fortgeschrittene wieder gut, weil sie sehen, dass primitiv nicht unbedingt schlecht ist.


Log in to reply