Lottotehtävän algoritmi

Anonyymi

Löysin tällaisen tehtävän Ohjelmointiputkan putkapostista Lottovoitto;

Lotossa oli ennen 39 numeroa, joista valittiin 7. Mikä on pienin määrä lottorivejä siten, että arvottiinpa mikä tahansa 7 numeron rivi, on kyseisellä rivillä ainakin 4 yhteistä numeroa jonkun kyseisen rivikokoelman rivin kanssa.

Olen miettinyt, miten tuollainen ohjelma kannattaisi tehdä. Toistaiseksi pystyn tekemään ohjelman, joka arpoo tietyn määrän rivejä. Mutta onko olemassa nopeaa tapaa tarkistaa rivien validius? Yritin tehdä ohjelman, joka tekee listan kaikista eri riveistä ja tarkistaa ne kaikkien rivien kanssa. Mutta noin 15000000 rivin tarkastaminen 400 rivin kanssa on hidasta. Lisäksi kaikkien rivien generoiminen vie aikaa ja muistia.

Onko siis tapaa tehdä funktio nextRow, joka palauttaisi annetusta lottorivistä seuraavan? Eli nextrow([1,2,3,4,5,6,7])=[1,2,3,4,5,6,8], nextrow([1,2,3,4,5,6,8])=[1,2,3,4,5,6,9] jne, vai miten kannattaisi iteroida kaikki rivit? Vai onko olemassa tapaa, jolla ei tarvitsisi tarkistaa kaikkia 15 miljoonaa riviä, eli joku suppeampi osajoukko riittäisi todistamaan, että nyt valittiin kunnollinen joukko rivejä?

13

2036

    Vastaukset 13

    Anonyymi (Kirjaudu / Rekisteröidy)
    5000
    • Anonyymi

      Eikös oikea vastaus irtoa suoraan talukkolaskennan kaavalla:

      =KOMBINAATIO(7;4)

      eli 35 varitaatiota.

      • Anonyymi

        Lisätäänpä vielä tapa jolla poimit nuo numerosarjat;

        >>> python3
        >>> from itertools import permutations
        >>> perm = permutations([1, 2, 3, 4, 5, 6, 7], 4)
        >>> for i in list(perm): print(i);

        Eikös se näin mene?


      • Anonyymi
        Anonyymi kirjoitti:

        Lisätäänpä vielä tapa jolla poimit nuo numerosarjat;

        >>> python3
        >>> from itertools import permutations
        >>> perm = permutations([1, 2, 3, 4, 5, 6, 7], 4)
        >>> for i in list(perm): print(i);

        Eikös se näin mene?

        Ehkä tuossa jäi epäselvyyttä lisäävä vaikutelma, kun laitoin oikeaa riviä kuvaamaan numerot 1..7, voit käyttää mitä tahansa muita lukuja noiden tilalla.


    • Anonyymi

      Minusta tuntuu, että yrität ratkaista tuota tarpeettoman monimutkaisesti, mutta kyllä sen varmasti noinkin saa oikein. Kannattaa kuitenkin huomata, että NextRow-funktiota ei kannata tehdä käymään rivejä läpi tuossa järjestyksessä, koska se on paljon työläämpää kuin "normaalissa" suuruusjärjestyksessä läpikäyminen.

      Ensimmäinen rivi on siis 1, 2, 3, 4, 5, 6, 7 ja
      toinen rivi on 1, 2, 3, 4, 5, 6, 8, kuten sinullakin, mutta
      kolmas rivi on 1, 2, 3, 4, 5, 6, 9, ja
      neljäs 1, 2, 3, 4, 5, 6, 10,
      ja niin edelleen, kunnes viimeinen luku on käyty läpi kaikilla vaihtoehdoilla:
      1, 2, 3, 4, 5, 6, 39.
      Sitten toiseksi viimeistä numeroa kasvatetaan yhdellä, ja taas käydään viimeinen numero läpi kaikilla vaihtoehdoilla:
      1, 2, 3, 4, 5, 7, 8
      1, 2, 3, 4, 5, 7, 9
      1, 2, 3, 4, 5, 7, 10,
      ...
      1, 2, 3, 4, 5, 7, 39.
      Ja taas kasvatetaan seuraavaa lukua yhdellä:
      1, 2, 3, 4, 5, 8, 9.
      1, 2, 3, 4, 5, 8, 10
      1, 2, 3, 4, 5, 8, 11
      ...
      1, 2, 3, 4, 5, 8, 39
      Ja taas kasvatetaan seuraavaa lukua yhdellä:
      1, 2, 3, 4, 5, 9, 10
      1, 2, 3, 4, 5, 9, 11
      1, 2, 3, 4, 5, 9, 12.
      ...

      Ja niin edelleen.
      Kun käytät tuota järjestystä, niin NextRow-funktio on paljon helpompi keksiä.

    • Hauska tehtävä. Päivitän sitä sen verran, että otan numeron 40 mukaan, kuten lotossa tehtiin kierroksella 48/2016. Erilaisia rivejä on siis 18643560 kappaletta, kuten Veikkauksen sivuilla (peliohjeet / todennäköisyys) kerrotaan.

      Pienin määrä lottorivejä, à 7 numeroa, että ainakin 4 oikein -tulos (jäljempänä "voitto") osuisi niihin on teoriassa 93. Käytännössä tällaista rivikokoelmaa ei pysty valitsemaan, koska osa mahdollisesti arvottavista riveistä tuottaisi väistämättä useamman voiton. Tämä päällekkäisyys tarkoittaa ylimääräisiä rivejä teoreettisen minimin lisäksi.

      Optimaalisen rivikokoelman löytäminen ei ole suoraviivainen tehtävä enkä usko, että löytyy oikotietä onneen, mutta kokoelmassa täytyy olla yli 200 lottoriviä. Alla hieman alustusta aiheeseen. Arvottavan lisänumeron merkitystä en ole huomioinut.

      Mikä tahansa yksittäinen lottorivi tuottaa voiton 202280 tapauksessa 18643560:sta. Jos kokoelman seuraavalla rivillä ei ole yhteisiä numeroita ensimmäisen kanssa, sekin tuottaa voiton 202280 tapauksessa. Ilman yhteisiä numeroita voidaan laatia vain 5 riviä. Kuudenteen riviin on poimittava mukaan kertaalleen jo käytettyjä numeroita ja jos kahdella rivillä on vain yksi yhteinen numero, riveihin osuu kaksi voittoa 400 tapauksessa. Jos kahdella rivillä on kaksi yhteistä numeroa, riveihin osuu kaksi voittoa 3200 tapauksessa jne.

      Tehtävänä on siis tuon päällekkäisyyden minimointi siten, että jokaisella mahdollisesti arvottavalla rivillä 18643560:sta voittaisi yhden, mutta mahdollisimman pienen määrän voittoja.

      Tehtävään kannattaa valita tehokas ohjelmointikieli koska kuten kirjoitit, tarkistaminen on hidasta. Jos unohdamme assemblerin, C-kieli lienee paras vaihtoehto. Esimerkiksi näin:

      char rivi[7] = {1,2,3,4,5,6,7};
      ...

      for (;;)
      {
      // Tarkista voittaako rivi[]
      ...

      // nextrow
      for (int i=7; rivi[i-1] == 40-7 i;)
      if (--i==0)
      exit(0); // Valmis, kaikki rivit läpikäyty
      for (rivi[i-1] ; i <= 7; rivi[i-1] = rivi[i-2] 1);
      }

      Uloin for-luuppi funktion sisään ja "Tarkista voittaako rivi[]" -kohtaan silmukka, jossa tarkistataan kokoelman rivit. Jos rivi[] ei tuota voittoa yhdenkään kokoelmassa olevan rivin kanssa, kokoelmaan on lisättävä numeroita tai kokonainen rivi siten, että rivi[] tuottaa voiton.

      Kokoelman rivien tarkistaminen kannattaa tehdä taitavasti, koska siitä saattaa tulla ohjelman ylivoimaisesti eniten aikaavievä osuus. Tarvittaessa kerron lisää. Onnea tehtävään!

      • Anonyymi

        Mikä on tehokkain tapa tarkistaa voittaako rivi?


      • Anonyymi
        Anonyymi kirjoitti:

        Mikä on tehokkain tapa tarkistaa voittaako rivi?

        Tämän päivän PC-koneet ovat siksi tehokkaita, että C-kielellä koodattu ohjelma käy esimerkiksi kaikki 18643560 riviä läpi silmänräpäyksessä, oli tarkistustapa mikä tahansa.

        Mutta tehokkain tapa on sellainen, missä kokoelman rivit säilytettään bittimaskeina (uint64_t), samoin esimerkin rivi[]. Testaaminen tapahtuu yksinkertaisesti and-operaattorilla ja laskemalla tuloksen ykkösbitit. Laskeminen on ylivoimaisesti tehokkainta prosessorin POPCNT-käskyllä (ks. __popcnt64() ja vastaavat funktiot), jos prosessorista sellainen löytyy.


      • Anonyymi
        Anonyymi kirjoitti:

        Tämän päivän PC-koneet ovat siksi tehokkaita, että C-kielellä koodattu ohjelma käy esimerkiksi kaikki 18643560 riviä läpi silmänräpäyksessä, oli tarkistustapa mikä tahansa.

        Mutta tehokkain tapa on sellainen, missä kokoelman rivit säilytettään bittimaskeina (uint64_t), samoin esimerkin rivi[]. Testaaminen tapahtuu yksinkertaisesti and-operaattorilla ja laskemalla tuloksen ykkösbitit. Laskeminen on ylivoimaisesti tehokkainta prosessorin POPCNT-käskyllä (ks. __popcnt64() ja vastaavat funktiot), jos prosessorista sellainen löytyy.

        Kyseisiä algoritmejä on ollut 70. vuodasta lähtien! Kato netistä mallia!


    • Anonyymi

      Koodasin aikanaan Amigalla tuontyyppisen softan, ja voitin joka viikko muutamia satasia, mutta mitään isompaa pottia ei tullut. Syy tähän oli, että numerot pääsääntöisesti oli aina oikein, mutta se lisänumerojärjestelmä sotki sitten pakkaa juuri sen verran että mitään isompaa pottia ei omalle kohdalleni osunut.

      Iterointia olisi pitänyt kehittää niin että otetaan huomioon todennäköisyys jokaiselle numerolle sen suhteen että tulisiko kyseeseen lisänumero, vai ns. 'virallinen' numero.

      Empä tuon jälkeen ole kokeillut, mutta kokemusta on, ja aika positiivistakin suoraan sanottuna.

      Tulipahan ainakin todistettua että toimii, ja että mahdollista tämä on.

      • Anonyymi

        Amigan aikoihin rivit piti ehkä jättää paperiselle kupongille rastitettuina. Taisi olla hikinen urakka. Nykyään on helpompaa, kun rivit voi rastittaa netissä.

        Lisänumerot eivät sotke tällaista järjestelmää. Varsinkaan, kun nykylotossa arvotaan vain yksi lisänumero ja ainoa voittoluokka, johon se käytännössä vaikuttaa on 6 1 oikein. 3 1 tuloksen voitto on yhtä tyhjän kanssa, joten ei ole väärin lukea pienimmäksi voitoksi 4 oikein tulos.

        Tässä tarkoitettu järjestelmä on käytännössä järjetön siksi koska nykylotossa pienimpien voittojen euromäärät ovat kuihtuneet käytännösä olemattomiksi. Edellä on kerrottu, että rivien optimimäärä olisi 93 ja käytännössä yli 200. Järjestelmän hinnaksi tulisi siis ainakin 200 euroa ja se takaisi vain 4-oikein tuloksen, jolla voittaa 10 euroa!

        Ohjelmointitehtävänä silti mielenkiintoinen ja vaativakin Laitahan Amiga-koodisi näytille...


      • Anonyymi

        "voitin joka viikko muutamia satasia"
        Höpö höpö.


      • Anonyymi
        Anonyymi kirjoitti:

        "voitin joka viikko muutamia satasia"
        Höpö höpö.

        Lotossa ei ole mitään mahdollisuutta kehittää mitään järkevää järjestelmää joka toisi enemmän voittoja. Kaikki perustuu satunnaisuuteen.


      • Anonyymi
        Anonyymi kirjoitti:

        Lotossa ei ole mitään mahdollisuutta kehittää mitään järkevää järjestelmää joka toisi enemmän voittoja. Kaikki perustuu satunnaisuuteen.

        Lotto perustuu satunnaisuuteen, olet oikeassa. Mutta olet väärässä siinä, etteikö järkevällä järjestelmällä voisi vaikuttaa voittojen määrään.

        Tunnetuin esimerkki voittojen määrään vaikuttamisesta lienee kautta aikain yleisimmän rivin lottoaminen. Jos rastitat numerot 1, 2, 3, 4, 5, 6 ja 7 ja voitat, joudut tiettävästi jakamaan (5 oikein tai paremman) voittoluokan voiton poikkeuksellisen suuren pelaajajoukon kanssa.

        Toinen esimerkki on ero järjestelmä- ja haravapelien välillä. Järjestelmä takaa osumien määrää vastaavan voiton ja tuo suuren määrän pienempiä voittoja. Harava takaa vain 4- ja 5-oikein tuloksen, mutta huomattavasti pienemmällä kustannuksella. Toki voiton todennäköisyys sijoitettua euroa kohden on kummassakin pelissä sama. Vastaavasti ruletissa voi asettaa panoksensa yhdelle numerolle (1:30) tai esim. kolmelle (1:10).

        Tämän ketjun aloittaja haki siis haravaa, joka antaisi varman voiton joka kerta. Sellaisessa olisi hyvinkin järkeä mm. lottoporukoiden peli-innon ylläpitäjänä. Tuskin mikään on lannistavampaa kuin pelata viikosta toiseen lottoporukassa, joka ei koskaan voita mitään.

        Keskustelemme ohjelmoinnista ja sen suhteen järjestelmän pohtimisessa on järkeä, mitä Veikkauksen lotossa ei juuri ole.


    Ketjusta on poistettu 0 sääntöjenvastaista viestiä.

    Luetuimmat keskustelut

    1. Ampuminen kylpylässä

      Onko vornasen timbe käynyt hiukan kylpemässä vai mikä tämä ampumatapaus on kylpylässä? Tuntuu aika villi meno olevan naa
      Naantali
      99
      2184
    2. Kemijärvellä vesionnettomuus

      Pitkänsillan ja taiteilijanniemen välillä nähty henkilön painuvan veden alle. Mitä on tapahtunut? Onko vesihiisi taas as
      Kemijärvi
      41
      1438
    3. Hei, voitko kuunnella

      Voisitko auttaa minua selvittämään asioita? En halua ajaa sinua hulluuteen kanssani, en sitoa sinua, en esittää vaatimu
      Ikävä
      138
      1064
    4. Joku porukka lähtenyt täältä

      Ihmeen hiljainen on palsta nyt. Yleensä tänne tulvii aloituksia yms, mutta nyt on kyllä erikoisen hiljaista.
      Ikävä
      232
      1028
    5. 96
      904
    6. Miten yrität

      Vielä saada kaivattusi?
      Ikävä
      82
      856
    7. Tuletko tänään

      Jos soitan? Niin... tuletko?🖤
      Ikävä
      79
      751
    8. Se kun olit pitkästä aikaa silmieni edessä

      Oli kyllä sykähdyttävää. Tiedätkö, mikä laittaa minut ikävöimään sinua? Kun palautan mieleeni valtavan ihanan olemuksen,
      Ikävä
      53
      747
    9. Olipa yllätys

      Kuten hyvin moni tiesi/arvasi että valetta alusta loppuun toi *olemme ystäviä* satu. Instassaan käsi kädessä kuva kertoo
      Kotimaiset julkkisjuorut
      215
      744
    10. Muutto auto hakee sut tänään!

      Tein sulle oman huoneen! mieheltä naiselle
      Ikävä
      93
      719
    11. 51
      689
    12. On todella ikävää

      Todella ikävää, että asiat ovat menneet tällaisiksi. Tämä ei ollut missään vaiheessa tarkoitukseni. Olen tehnyt virheit
      Ikävä
      79
      648
    13. Kiinni jäit

      Ei olisi uskonut sinusta
      Ikävä
      40
      646
    14. Oletteko koskaan torjuneet kaivattuanne?

      Minä olen, kun en silloin tajunnut vielä ihastuneeni. Yritin paikata tapahtunutta, mutta ei onnistunut enää.
      Ikävä
      28
      526
    15. Ottanet yhteyttä

      Facebookissa,jos on jotain asiaa.Miehelle! T.M-nainen.
      Ikävä
      55
      517
    16. Costa Rica on tympeän makuinen kahvi

      Ostin kahvin hinnan romahduksen kunniaksi Costa Rican "Premium Blendiä". Piti olla sataprosenttista arabialaista. No ain
      Maailman menoa
      32
      501
    17. Hämmentävä hetki: TTK:sta pudonnut Johanna Puhakka lataa pettyneenä: "Sitä ei voi kieltää"

      Johanna Puhakka ja Jurijs Jurza Trosenko tippuivat Tanssii Tähtien Kanssa -kisasta. Suositussa viihdeohjelmassa nähtiin
      Tanssii tähtien kanssa
      14
      480
    18. Kai sä mies ymmärrät..

      ..ettet jättänyt vaihtoahtoa. Tottakai toivon vielä, että pystyisit toimimaan niin että asiat korjaantuisivat. Vahvast
      Ikävä
      28
      472
    19. Nyt ei enää ole

      Mitään mikä pitäisi mut hiljaa, kaikesta. Tämä on muutamalle henkilölle täällä.
      Ikävä
      35
      464
    20. En tiedä mitä sanoa

      Siksi en vastannut😔
      Ikävä
      33
      443
    Aihe