Vaikea kombinatoriikan tehtävä

enosaatätä

Noppaa heitetään 20 kertaa. Tuloksista muodostetaan 20-numeroinen luku liittämällä numerot yhteen, esim. 24312534121134563421. Mikä on todennäköisyys, että saatu 20-numeroinen luku tulkittuna merkkijonoksi sisältää ainakin yhden seuraavista osamerkkijonoista, eli luvusta löytyy seuraavat numerot peräkkäin:

123456
112233
445566
111222
333444
555666
111111
222222
333333
444444
555555
666666

Yritin inkluusio-ekskluusioperiaatteetta, mutta sekosin laskuissani.

36

454

    Vastaukset

    Anonyymi (Kirjaudu / Rekisteröidy)
    5000
    • Kanootti3

      On tosiaan aika hankala. Lähdin tietokoneavusteisesti ratkomaan. Tein Markovin ketjun, jossa on tiloina kaikki noiden osamerkkijonojen alukkeet, näitä tuli 46kpl:

      prefixes = ['1', '11', '111', '1111', '11111', '1112', '11122', '112', '1122', '11223', '12', '123', '1234', '12345', '2', '22', '222', '2222', '22222', '3', '33', '333', '3333', '33333', '3334', '33344', '4', '44', '444', '4444', '44444', '445', '4455', '44556', '5', '55', '555', '5555', '55555', '5556', '55566', '6', '66', '666', '6666', '66666' ]

      ja lisäksi tyhjä lähtötila "" sekä absorboiva tila, johon päädyttäessä jokin halutuista osamerkkijonoista on tullut ja sitten ketju jää tähän tilaan. Siirtymätodennäköisyydet katsoin siten, että jokaiseen alukkeeseen (ja tyhjään lähtötilaan) lisätään vuorollaan kukin merkki '1', '2',..,'6' ja sitten

      JOKO:
      Jos näin saatu merkkijono on joku halutuista osamerkkijonoista lisätään 1/6 siirtymää absorboivaan tilaan
      TAI:
      Katsotaan mikä on pisin aluke joka näin saadun merkkijonon lopusta voidaan lukea, ja lisätään 1/6 siirtymää tähän kyseiseen alukkeeseen.

      Näin saadaan 48x48 siirtymämatriisi Q ja kysytty todennäköisyys on tn. että ketju on 20 siirtymän jälkeen absorboivassa tilassa eli matriisin Q^20 alkio vasemmassa alanurkassa [48][1] (kun lähtötila "" on asetettu ensimmäiseksi tilaksi ja absorboiva viimeiseksi).
      Se on likimain 0,0035471102445.

      Simulointi tukee tätä tulosta, joten luullakseni tuo ketjun muodostaminen meni oikein. Tiedä sitten tarkasta arvosta. Senkin kyllä saisi, kun käyttäisi tarkkoja rationaalilukuja matriisissa, mutta minulla ei ollut sellaista kirjastoa valmiina.

      • Anonyymi

        Miksi on riittävää tutkia 46 tilaa? Minusta osamerkkijonon alkuja on 59 kpl:

        finalstates = ['123456',
        '112233',
        '445566',
        '111222',
        '333444',
        '555666',
        '111111',
        '222222',
        '333333',
        '444444',
        '555555',
        '666666']
        print(finalstates)
        states = []
        for j in range(len(finalstates)):
        for i in range(len(finalstates[j]) 1):
        states.append(finalstates[j][:i])
        states = list(set(states))
        print(len(states))

        tulostaa 59


      • Anonyymi
        Anonyymi kirjoitti:

        Miksi on riittävää tutkia 46 tilaa? Minusta osamerkkijonon alkuja on 59 kpl:

        finalstates = ['123456',
        '112233',
        '445566',
        '111222',
        '333444',
        '555666',
        '111111',
        '222222',
        '333333',
        '444444',
        '555555',
        '666666']
        print(finalstates)
        states = []
        for j in range(len(finalstates)):
        for i in range(len(finalstates[j]) 1):
        states.append(finalstates[j][:i])
        states = list(set(states))
        print(len(states))

        tulostaa 59

        Mitään kokonaista finalstatea ei tarvitse ottaa tilaksi, vaan ne voi yhdistää yhdeksi "jokin final on tullut". Eli jätetään vain 1 pois riviltä
        for i in range(len(finalstates[j]) 1):

        Tulee 47 ja sitten lisätään se yksi absorboiva tila, niin saadaan tuo mainittu 48.
        (Niissä 46 "alukkeessa" ei oltu taidettu laskea mukaan sitä tyhjää tilaa.)


    • 3kj46h

      Kysyttyjä yhdistelmiä on 12 kpl. Todennäköisyys saada nopanheitossa jokin tietty kuuden numeron mittainen yhdistelmä kuudella peräkkäisellä heitolla on (1/6)^6. Kukin kuuden numeron mittainen yhdistelmä kahdenkymmenen heiton sarjassa voi saada alkunsa heitoilla 1-15 eli alkusijainti koko merkkijonossa voi olla mikä tahansa positioista 1-15.

      Todennäköisyys, että jokin näistä kahdestatoista yhdistelmästä alkaa ensimmäisestä positiosta = 12* (1/6)^6. Sama pätee positioiden 2-15 suhteen, joten mahdollisia positioita merkkijonon sijainnille on 15 kpl. Koska nämä kaikki ovat toisistaan riippumatomia, kysytty tod.näk = 15*12*(1/6)^6 = 0,003858024.

      • pedantikko

        "Koska nämä kaikki ovat toisistaan riippumatomia,"
        Mutta kun eivät ole.


      • 3kj46h
        pedantikko kirjoitti:

        "Koska nämä kaikki ovat toisistaan riippumatomia,"
        Mutta kun eivät ole.

        Ovat.


      • hieman_ajattelua

        Jos olisi yksisivuinen noppa (joka heitolla luku 1) ja kysyttäisiin millä todennäköisyydellä n pituisessa jonossa on m pituinen jono pelkkää ykköstä niin ilmiselvästi vastaus olisi 1 kun m<=n. Sinun laskukaava antaisi kuitenkin esimerkiksi tapauksessa n=7 ja m=6 tulokseksi 2 joka on selvästi virheellinen tulos.


      • pedantikko
        3kj46h kirjoitti:

        Ovat.

        Olkoon kuusi ensimmäistä vaikkapa 123451. Sinun riippumattomuushypoteesistasi seuraa, että todennäköisyys positiosta kaksi alkavan yhdistelmän osumisesta olisi myös 12* (1/6)^6. On kuitenkin selviö, että tn on nolla, josten perättäiset sajat eivät ole riippumattomia,


    • Kanootti3

      Laskin nyt kokonaisluvuilla ja sain seuraavat arvot n:n pituisille merkkijonoille (tn. saadaan jakamalla 6^n:llä) n=1,2,3....

      [0, 0, 0, 0, 0, 12, 138, 1224, 9714, 72498, 520268, 3633165, 24867610L, 167613033L, 1116096436L, 7358932150L, 48126778830L, 312594178184L, 2018532445956L, 12968797058271L, 82957185658624L,...] (L perässä tarkoittaa vain että luku on long-tyyppiä).

      Kahdeskymmenes on 12968797058271, joten kysytty tn. on
      12968797058271 / 6^20
      = 480325816973/ 135413275557888
      = 0,003547110244502319

    • Kanootti3

      Tein Python-koodin, jolla voi ratkaista vastaavan tehtävän halutuille osamerkkijonoille (ja käytettäville symboleille ja sananpituudelle):

      http://tpcg.io/GkDnZI

      Käyttöohje:
      Viimeinen koodirivi
      print(getProbSomeSeqIsSub([0,1], ["000", "111"], 7, True))
      tulostaa todennäköisyyden halutuille symboleille, osamerkkijonoille, sananpituudelle (ja halutaanko tarkka rationaaliluku vai floating-point luku, aseta True tai False). Noilla arvoilla se ratkaisee kolmen putken esiintymistodennäköisyyden 7 pituisessa binäärijonossa.
      Tämän muokkaamisen jälkeen paina "execute" vasemmasta ylänurkasta ja tuloksen pitäisi ilmestyä oikean puoleiseen konsoliin (sivu saattaa tietenkin olla jokaisella ehkä erinäköinen).

      Koodi on melko sotkuinen mutta kyllä se näyttäisi toimivan, ainakin tuolle kolmen putki -ongelmalle (sen komplementille) antaa ihan oikeita vastauksia.

      Ihan vaan, jos joku haluaa testailla :-).

      • Kanootti3

        Yhden pituisille osajonoille ei taida tuollaiseltaan toimia, mutta näyttäisi korjutuvan, kun muuttaa kohdan (rivillä 53)

        if stateStr str(i) in seqs:

        paikalle

        if stateStr str(i) in seqs or str(i) in seqs:

        eli lisää jokaisesta tilasta siirtymä tn:ää absorboivaan tilaan jokaista yhden merkin pituista osamerkkijonoa kohti.


      • Kanootti3
        Kanootti3 kirjoitti:

        Yhden pituisille osajonoille ei taida tuollaiseltaan toimia, mutta näyttäisi korjutuvan, kun muuttaa kohdan (rivillä 53)

        if stateStr str(i) in seqs:

        paikalle

        if stateStr str(i) in seqs or str(i) in seqs:

        eli lisää jokaisesta tilasta siirtymä tn:ää absorboivaan tilaan jokaista yhden merkin pituista osamerkkijonoa kohti.

        Siis rivillä 50 (muuttui itsellä kun muokkasin siellä jo alkupäässäkin jotain).


      • enosaatätä

        Hieno tarkaisu. Täytyy opetella enemmän Pythonia ja Markovin ketjuja, jotta ymmärrän kaiken. Mutta näyttäisi toimivan!


      • Kanootti3

        Tajusinkin juuri, että eihän tuo algoritmi toimi kaikenlaisille osajonolistoille ollenkaan. Jos esim yksi jono on toisen alku, niin sitä ei huomata eikä mennä absorboivaan tilaan, jos ollaan "kartuttamassa" sitä pitempää osajonoa.

        Voisikohan tuota korjata sillä että poistaa aluksi osajonolistasta yksi kerrallaan sellaiset jonot, joista löytyy sisältä jokin toinen osajono?


      • Kanootti3

        Kun tilasta lisätään siirtymä tietyllä symbolilla pitää tietenkin tarkastaa saadaanko muodostettua mistään asti luettuna jokin päätösosajono. Tämä käsittelee myös "yhdenpituiset osajonot" -tapaukset. Eikä sitten tuota osajonolistan "siivoustakaan" tarvitse tehdä. Mutta antaa sen olla; hyvähän se on jos niitä saadaan karsittua pois.

        Korjattu versio:

        http://tpcg.io/JUVcIw

        Toimineekohan tuo sitten kaikilla :-D


      • Kanootti3

        Joo, nyt se taitaa toimia. Tein satunnaisia testejä aika paljon ja katsoin tuleeko sama tulos kuin brute-force -metodilla.
        Testit mukana:
        http://tpcg.io/D8cZzv


    • YxVain

      Todennäköisyys on 10 %

    • Anonyymi

      0,0001540702...

    • Anonyymi

      tn = 15*12*6^14/6^20 =5/6^4 = 0,00385802.....

      • Anonyymi

        Huomasin jo että kommenttini/ 04:28 on täyttä puppua.


    • Anonyymi

      Kuinka pitkä tuon merkkijonon pitää olla, jotta kysytty todennäköisyys olisi suurempi kuin 0,1?

      Vinkki: Todennäköisyys on tuolloin
      tn = 31837618718...4782 / 318065396940...1216

      Aikaa laskentaan kului Pythonilla (PyPy) n. 18 s.

      • 453

        Laskitko kaikki pituudet tuohon asti? Senhän voi tehdä puolitushaulla (aluksi tuplaa niin pitkään kunnes menee yli ja sitten lähtee hakemaan sieltä välistä). Itse sain tuon tällä tavoin ihan käsipelissä kokeilemalla (en nyt tismalleen tuplaillut ja puolitellut vaan lisäsin aluksi satasia ja silleen...)


      • Anonyymi
        minkkilaukku kirjoitti:

        453

        Laskitko kaikki pituudet tuohon asti? Senhän voi tehdä puolitushaulla (aluksi tuplaa niin pitkään kunnes menee yli ja sitten lähtee hakemaan sieltä välistä). Itse sain tuon tällä tavoin ihan käsipelissä kokeilemalla (en nyt tismalleen tuplaillut ja puolitellut vaan lisäsin aluksi satasia ja silleen...)

        Pythonilla on helppo laskea ihan tarkasti vaikka kuinka pitkälle ilman mitään ymmärräystä matematiikan vaikeuksista ihan vaan kansakoulun lyhyen oppimäärän (4 v) tiedoilla. Riittää hallita kokonaislukujen yhteenlasku ja 10:llä jakaminen! Missään vaiheessa ei tarvita mitään merkkijonoja.

        Kysehän on vain kuusinumeroisista kymmenjärjestelmän luvuista, joissa esiintyy vain numeroita 1...6. Tehdään niitä varten suoraan indeksoitava lista, jossa on jokaista lukua varten tyhjä lista.

        Muodostetaan kaikki ehdot täyttävät luvut silmukassa ja suodatetaan pois 12 haettavaa lukua (111111, ...666666).

        Jokaisesta näistä luvuista voidaan muodostaa 6 tai 5 lukua jakamalla luku 10:llä ja lisäämällä siihen silmukassa 100000. Haetut 12 lukua suodatetaan pois. Lisätään muodostetut 6 tai 5 lukua alkuperäisellä luvulla indeksoitavan listan alilistaan.

        Kaikki tämä riittää tehdä vain kerran. Muodostetussa kaksitasoisessa listassa on kaikki tarvittava tieto. Aluksi kaikkia lukua oli vain 1 (gnk = [1]*666667). Lisätään muodostettujen lukujen lukumäärät indeksoitavaan summalistaan (gns) ja kopsataan se lopuksi uudeksi kerroinlistaksi gnk. Tätä voidaan toistaa silmukassa ikuisesti, kunnes tietokoneen muisti loppuu.

        Lyhyt kertakäyttökoodi. Korvaa jokainen alaviiva (_) kahdella blankolla editorissa. Ja jälkimmäisen silmukan n:n arvo halutuksi.

        No = [123456,112233,445566,111222,333444,555666,111111,222222,333333,444444,555555,666666]
        gl = []
        for i in range(0,666667): gl.append([])

        for a in range(111111,666667):
        __s = a
        __for i in range(0,5):
        ____if s==0 or s>6: break
        ____s = s//10
        ____if s>6: continue
        ____if a in No: continue
        ____for i in range(1,7):
        ______b = a//10 i*10**5
        ______if b in No: continue
        ______gl[a].append(b)

        gnk = [1]*666667
        for n in range(7,100):
        __c1 = 0
        __gns = [0]*666667
        __for z in range(111111,666667):
        ____if len(gl[z])==0: continue
        ____for y in gl[z]: gns[y] = gnk[z]
        __for z in range(111111,666667): c1 = gns[z]
        __gnk = gns[:]
        __print(n,6**n - c1)
        __print(n,6**n)

        Tulostus (lopun printit) pitää muuttaa itselle sopiviksi ihan tarpeen mukaan. Näyttäisi toimivan ilman Pypyäkin ihan riittävän nopeasti. Aika kuluu isoilla n:n arvoilla monisatanumeroisen lukujen summaamisessa. Tulostuksesta näkee lukujen aluista halutut kohdat ihan paljain silmin. Vähän päässälaskua ja laskimella varmistus.


      • Anonyymi
        Anonyymi kirjoitti:

        Pythonilla on helppo laskea ihan tarkasti vaikka kuinka pitkälle ilman mitään ymmärräystä matematiikan vaikeuksista ihan vaan kansakoulun lyhyen oppimäärän (4 v) tiedoilla. Riittää hallita kokonaislukujen yhteenlasku ja 10:llä jakaminen! Missään vaiheessa ei tarvita mitään merkkijonoja.

        Kysehän on vain kuusinumeroisista kymmenjärjestelmän luvuista, joissa esiintyy vain numeroita 1...6. Tehdään niitä varten suoraan indeksoitava lista, jossa on jokaista lukua varten tyhjä lista.

        Muodostetaan kaikki ehdot täyttävät luvut silmukassa ja suodatetaan pois 12 haettavaa lukua (111111, ...666666).

        Jokaisesta näistä luvuista voidaan muodostaa 6 tai 5 lukua jakamalla luku 10:llä ja lisäämällä siihen silmukassa 100000. Haetut 12 lukua suodatetaan pois. Lisätään muodostetut 6 tai 5 lukua alkuperäisellä luvulla indeksoitavan listan alilistaan.

        Kaikki tämä riittää tehdä vain kerran. Muodostetussa kaksitasoisessa listassa on kaikki tarvittava tieto. Aluksi kaikkia lukua oli vain 1 (gnk = [1]*666667). Lisätään muodostettujen lukujen lukumäärät indeksoitavaan summalistaan (gns) ja kopsataan se lopuksi uudeksi kerroinlistaksi gnk. Tätä voidaan toistaa silmukassa ikuisesti, kunnes tietokoneen muisti loppuu.

        Lyhyt kertakäyttökoodi. Korvaa jokainen alaviiva (_) kahdella blankolla editorissa. Ja jälkimmäisen silmukan n:n arvo halutuksi.

        No = [123456,112233,445566,111222,333444,555666,111111,222222,333333,444444,555555,666666]
        gl = []
        for i in range(0,666667): gl.append([])

        for a in range(111111,666667):
        __s = a
        __for i in range(0,5):
        ____if s==0 or s>6: break
        ____s = s//10
        ____if s>6: continue
        ____if a in No: continue
        ____for i in range(1,7):
        ______b = a//10 i*10**5
        ______if b in No: continue
        ______gl[a].append(b)

        gnk = [1]*666667
        for n in range(7,100):
        __c1 = 0
        __gns = [0]*666667
        __for z in range(111111,666667):
        ____if len(gl[z])==0: continue
        ____for y in gl[z]: gns[y] = gnk[z]
        __for z in range(111111,666667): c1 = gns[z]
        __gnk = gns[:]
        __print(n,6**n - c1)
        __print(n,6**n)

        Tulostus (lopun printit) pitää muuttaa itselle sopiviksi ihan tarpeen mukaan. Näyttäisi toimivan ilman Pypyäkin ihan riittävän nopeasti. Aika kuluu isoilla n:n arvoilla monisatanumeroisen lukujen summaamisessa. Tulostuksesta näkee lukujen aluista halutut kohdat ihan paljain silmin. Vähän päässälaskua ja laskimella varmistus.

        Jos yläpuolen kertoo tuhannella (1000*(6**n-c1)/6**n) , oikean kohdan löytää Python 2:llakin suoraan myös kokonaisluvuilla laskien ilman turhaa tulostusta. Muuttuu 100:ksi ensimäisen kerran. (Python 3 osaa jakaa kokonaislukuja kokonaisluvuilla ja muodostaa myös desimaaliosan ilman liukulukumuunnosta ja sen rajoitusta.)

        Yli 0,5 todennäköisyys saavutetaan kun n = 2950 ja 0,6 kun n = 3898 ja 0,7 kun n = 5121 ja 0,8 kun n = 6843 ja 0,9 kun n = 9788 ja 0,95 kun n = 12733 ja 0,99 kun n = 19571.

        Lopussa n kasvoi yhdellä n. 0,3 sekunnissa. Muistia kului n. 1,3 Gtavua ja aikaa n. tunti.

        On tietysti täysin typerää laskea monituhatnumeroisilla kokonaisluvuilla näin turhaa laskua. Varmasti löytyisi joku toistuva jaksotus ja paljon symmetriaa, joilla laskennan saisi murto-osaan ja voisi jakaa homman useille eri ytimille.


      • Anonyymi kirjoitti:

        Pythonilla on helppo laskea ihan tarkasti vaikka kuinka pitkälle ilman mitään ymmärräystä matematiikan vaikeuksista ihan vaan kansakoulun lyhyen oppimäärän (4 v) tiedoilla. Riittää hallita kokonaislukujen yhteenlasku ja 10:llä jakaminen! Missään vaiheessa ei tarvita mitään merkkijonoja.

        Kysehän on vain kuusinumeroisista kymmenjärjestelmän luvuista, joissa esiintyy vain numeroita 1...6. Tehdään niitä varten suoraan indeksoitava lista, jossa on jokaista lukua varten tyhjä lista.

        Muodostetaan kaikki ehdot täyttävät luvut silmukassa ja suodatetaan pois 12 haettavaa lukua (111111, ...666666).

        Jokaisesta näistä luvuista voidaan muodostaa 6 tai 5 lukua jakamalla luku 10:llä ja lisäämällä siihen silmukassa 100000. Haetut 12 lukua suodatetaan pois. Lisätään muodostetut 6 tai 5 lukua alkuperäisellä luvulla indeksoitavan listan alilistaan.

        Kaikki tämä riittää tehdä vain kerran. Muodostetussa kaksitasoisessa listassa on kaikki tarvittava tieto. Aluksi kaikkia lukua oli vain 1 (gnk = [1]*666667). Lisätään muodostettujen lukujen lukumäärät indeksoitavaan summalistaan (gns) ja kopsataan se lopuksi uudeksi kerroinlistaksi gnk. Tätä voidaan toistaa silmukassa ikuisesti, kunnes tietokoneen muisti loppuu.

        Lyhyt kertakäyttökoodi. Korvaa jokainen alaviiva (_) kahdella blankolla editorissa. Ja jälkimmäisen silmukan n:n arvo halutuksi.

        No = [123456,112233,445566,111222,333444,555666,111111,222222,333333,444444,555555,666666]
        gl = []
        for i in range(0,666667): gl.append([])

        for a in range(111111,666667):
        __s = a
        __for i in range(0,5):
        ____if s==0 or s>6: break
        ____s = s//10
        ____if s>6: continue
        ____if a in No: continue
        ____for i in range(1,7):
        ______b = a//10 i*10**5
        ______if b in No: continue
        ______gl[a].append(b)

        gnk = [1]*666667
        for n in range(7,100):
        __c1 = 0
        __gns = [0]*666667
        __for z in range(111111,666667):
        ____if len(gl[z])==0: continue
        ____for y in gl[z]: gns[y] = gnk[z]
        __for z in range(111111,666667): c1 = gns[z]
        __gnk = gns[:]
        __print(n,6**n - c1)
        __print(n,6**n)

        Tulostus (lopun printit) pitää muuttaa itselle sopiviksi ihan tarpeen mukaan. Näyttäisi toimivan ilman Pypyäkin ihan riittävän nopeasti. Aika kuluu isoilla n:n arvoilla monisatanumeroisen lukujen summaamisessa. Tulostuksesta näkee lukujen aluista halutut kohdat ihan paljain silmin. Vähän päässälaskua ja laskimella varmistus.

        Mielenkiintoinen strategia, joo sen voi noinkin tosiaan. En tiedä tuliko mulla kopioidessa virhe vai miksi minulla tuo koodi ei toiminut (gl jäi tyhjäksi, loppuosa toimi kyllä). Mistä nuo merkit , muuten tuli riville
        ____if s==0 or s>6: break

        No sain tuon toimimaan itselläni kun muokkasin vähän sitä koodia. Saanko ehdottaa tällaista versiota:
        https://repl.it/@minkkilaukku2/subseq2
        Siinä tarkastellaan vain lukuja jotka koostuu 1-6:sta eikä kaikkia kymmenjärjestämän lukuja väliltä 111111-6666666 ja käytetään dict:iä (onkohan tämä miten paljon listaa hitaampi/epätehokkaampi?)


      • Anonyymi
        minkkilaukku kirjoitti:

        Mielenkiintoinen strategia, joo sen voi noinkin tosiaan. En tiedä tuliko mulla kopioidessa virhe vai miksi minulla tuo koodi ei toiminut (gl jäi tyhjäksi, loppuosa toimi kyllä). Mistä nuo merkit , muuten tuli riville
        ____if s==0 or s>6: break

        No sain tuon toimimaan itselläni kun muokkasin vähän sitä koodia. Saanko ehdottaa tällaista versiota:
        https://repl.it/@minkkilaukku2/subseq2
        Siinä tarkastellaan vain lukuja jotka koostuu 1-6:sta eikä kaikkia kymmenjärjestämän lukuja väliltä 111111-6666666 ja käytetään dict:iä (onkohan tämä miten paljon listaa hitaampi/epätehokkaampi?)

        Kokeilin eilen ja nyt uudstaan. Kyllä tuo koodi toimii ihan copy-pastella _ replace sekä Python 2:lla ja 3:lla ja Pypyillä. Pitää tietysti poistaa ne ihme-merkit. Kirjoitin tuon rivin käsin editoriini uudestaan ilman mitään virhepainalluksia, tallensin tiedoston ja kopsasin tuon rivin uudestaan tänne. Katsotaan sainko tehtyä nuo erikoismerkit vahingossa jotenkin vai muodostaako Suomi24:n editori ne.

        ____if s==0 or s>6: break

        Teen tälläiset kertakäyttökoodit aina ilman ilman (hidastavia) kirjasto-ohjelmia, jotta voisi vapaasti käyttää eri Pypy-versioita. Nykyisin monet kirjasto-ohjelmat alkavat jo toimia Pypyilläkin, mutta niiden Pypy-versiot on ladattava erikseen tietokoneelle. Nyt yli 99,9 % ajasta kuluu yli 1000...15000 -numeroisten lukujen typerään ynnäämisessä, joten koodin pieni optimointi ei vaikuta mitenkään lopputulokseen. Listoja tarkkailemalla löytyy symmetriota, joita hyödyntäen laskenta-ajan saisi murto-osaan muutaman päivän työllä.

        Jos haluaa nopeutta isoilla n:n arvoilla, niin sitä käyttämällä gmpy2:n liukuluja tai taskulaskinta. Riittää laskea c1:n arvo (21853993454719232) kun n=21. Sen jälkeen kasvuvauhti (k) on käytännössä ihan vakioita. k = mpfr(5.998587939741517).

        c1 = mpfr(21853993454719232*k**(n-21))

        Esim. jos n=19571, niin todennäköisyys on 0,9900012309059978. Taskulaskimellakin laskettuna.


      • Anonyymi
        Anonyymi kirjoitti:

        Kokeilin eilen ja nyt uudstaan. Kyllä tuo koodi toimii ihan copy-pastella _ replace sekä Python 2:lla ja 3:lla ja Pypyillä. Pitää tietysti poistaa ne ihme-merkit. Kirjoitin tuon rivin käsin editoriini uudestaan ilman mitään virhepainalluksia, tallensin tiedoston ja kopsasin tuon rivin uudestaan tänne. Katsotaan sainko tehtyä nuo erikoismerkit vahingossa jotenkin vai muodostaako Suomi24:n editori ne.

        ____if s==0 or s>6: break

        Teen tälläiset kertakäyttökoodit aina ilman ilman (hidastavia) kirjasto-ohjelmia, jotta voisi vapaasti käyttää eri Pypy-versioita. Nykyisin monet kirjasto-ohjelmat alkavat jo toimia Pypyilläkin, mutta niiden Pypy-versiot on ladattava erikseen tietokoneelle. Nyt yli 99,9 % ajasta kuluu yli 1000...15000 -numeroisten lukujen typerään ynnäämisessä, joten koodin pieni optimointi ei vaikuta mitenkään lopputulokseen. Listoja tarkkailemalla löytyy symmetriota, joita hyödyntäen laskenta-ajan saisi murto-osaan muutaman päivän työllä.

        Jos haluaa nopeutta isoilla n:n arvoilla, niin sitä käyttämällä gmpy2:n liukuluja tai taskulaskinta. Riittää laskea c1:n arvo (21853993454719232) kun n=21. Sen jälkeen kasvuvauhti (k) on käytännössä ihan vakioita. k = mpfr(5.998587939741517).

        c1 = mpfr(21853993454719232*k**(n-21))

        Esim. jos n=19571, niin todennäköisyys on 0,9900012309059978. Taskulaskimellakin laskettuna.

        Nyt tuo rivi kopioitui oikein, eli olin vahingossa painanut editoidessa tuolla rivillä joitain erikoisnäppäimiä. Todennäköisesti vasta Suomi24:n editorissa kopioinnin jälkeen, sillä Python tai Pypy ei noita näkymättömiä virhemerkkejä havainneet. Copy-paste ei tee virheitä.


      • Anonyymi
        minkkilaukku kirjoitti:

        Mielenkiintoinen strategia, joo sen voi noinkin tosiaan. En tiedä tuliko mulla kopioidessa virhe vai miksi minulla tuo koodi ei toiminut (gl jäi tyhjäksi, loppuosa toimi kyllä). Mistä nuo merkit , muuten tuli riville
        ____if s==0 or s>6: break

        No sain tuon toimimaan itselläni kun muokkasin vähän sitä koodia. Saanko ehdottaa tällaista versiota:
        https://repl.it/@minkkilaukku2/subseq2
        Siinä tarkastellaan vain lukuja jotka koostuu 1-6:sta eikä kaikkia kymmenjärjestämän lukuja väliltä 111111-6666666 ja käytetään dict:iä (onkohan tämä miten paljon listaa hitaampi/epätehokkaampi?)

        Kopsasin sen gl:n alustuksen alkuperäisestä tiedostosta uudestaan mitään muuttamatta.

        gl = []
        for i in range(0,666667): gl.append([])

        Mikähän tuossa voisi olla väärin? Pitäisi kyllä toimia Python 2:lla ja 3:lla ongelmitta. Jos ei toimi, jossakin on joku näkymätön piilomerkki. Kokeile noita kahta riviä ihan puhtaassa ympäristössä. Jos ei toimi, kirjoita käsin uudestaan muutaman merkin erissä. Kyllä se piilomerkki jossakin vaiheessa häviää!

        Minulla on vanhat Python 2.7.12 ja 3.5.2 versiot.


      • Anonyymi kirjoitti:

        Kopsasin sen gl:n alustuksen alkuperäisestä tiedostosta uudestaan mitään muuttamatta.

        gl = []
        for i in range(0,666667): gl.append([])

        Mikähän tuossa voisi olla väärin? Pitäisi kyllä toimia Python 2:lla ja 3:lla ongelmitta. Jos ei toimi, jossakin on joku näkymätön piilomerkki. Kokeile noita kahta riviä ihan puhtaassa ympäristössä. Jos ei toimi, kirjoita käsin uudestaan muutaman merkin erissä. Kyllä se piilomerkki jossakin vaiheessa häviää!

        Minulla on vanhat Python 2.7.12 ja 3.5.2 versiot.

        Siis jokainen gl[i] jää tyhjäksi tarkoitin. Kokeilin myös täällä (Python 3.8.1): https://repl.it/@minkkilaukku2/subseq3 ja sama virhe toistuu.

        Hetkonen, eikös tuo johdu siitä että, kun

        for a in range(111111,666667):
        s = a #puuttuuko tästä jotain?
        for i in range(0,5):
        if s==0 or s>6: break

        asetetaan s = a niin tuohan breikkaa aina kun a on tuolta väliltä. Pitäisikö s:n olla a:n ensimmäinen numero (ja sitten luupissa i:s numero tai vastaavaa?

        No mutta kuitenkin kyllähän tuo toimii, kun gl:n saa oikein muodostettua. Tulkitsenkohan oikein kun ajattelen, että se on niinkuin Markovin ketju, joka pitää tilana merkkijonon viimeisintä kuutta merkkiä?


      • minkkilaukku kirjoitti:

        Siis jokainen gl[i] jää tyhjäksi tarkoitin. Kokeilin myös täällä (Python 3.8.1): https://repl.it/@minkkilaukku2/subseq3 ja sama virhe toistuu.

        Hetkonen, eikös tuo johdu siitä että, kun

        for a in range(111111,666667):
        s = a #puuttuuko tästä jotain?
        for i in range(0,5):
        if s==0 or s>6: break

        asetetaan s = a niin tuohan breikkaa aina kun a on tuolta väliltä. Pitäisikö s:n olla a:n ensimmäinen numero (ja sitten luupissa i:s numero tai vastaavaa?

        No mutta kuitenkin kyllähän tuo toimii, kun gl:n saa oikein muodostettua. Tulkitsenkohan oikein kun ajattelen, että se on niinkuin Markovin ketju, joka pitää tilana merkkijonon viimeisintä kuutta merkkiä?

        Aaa, nyt tajusin: se pitää olla

        s (prosentti) 10 jne.

        sillähän ne erikoismerkit tuli
        ja lisäksi luupin for i in range(0,5): sisällä on vaan kaksi riviä. (Korjasin ne nyt itselleni tuonne replittiinkin.)


    • Keksin approksimatiivisen kaavan

      1 - a*b^n
      missä
      a = 1.0011546714408708
      b = 0.9997646566235854

      Sain tämän diagonalisoimalla siirtymämatriisin ja ottamalla vain kaksi itseisarvoltaan suurinta ominaisarvoa mukaan. Siihen voi ottaa lisääkin ja tietysti jos kaikki ottaa niin saa itse asiassa tarkan kaavan. Jos ottaa ei-reaalisia ominaisarvoja, niin lausekkeesta pitää sitten ottaa reaaliosa. Tai siinä käy varmaan silleen, että jos ottaa myös konjugaatti-ominaisarvon (näissä pareissahan ne tulee, koska karakteristinen polynomi on reaalikertoiminen), niin imaginaariset osat kumoutuu laskuissa.
      En mene kyllä vannomaan miten tarkat nuo arvot on. Jotain se Sage herjasi, että ominaisvektoreista mudostetun matriisin konditio-luku on pieni ja laskuissa saattaa esiintyä epätarkkuutta (onneksi koko matriisia ei tarvitse kääntää vaan inverssin viimeinen sarake riittää, jotta saadaan haluttu elementti laskettua diagolisoinnista).
      Koodini on täällä:
      https://github.com/minkkilaukku/sub-sequence-markov/blob/master/subseq_probs2.py
      Muodostan siirtymämatriisin tekemällä ensin annetuista osamerkkijonoista Trie-puun ( https://en.wikipedia.org/wiki/Trie ) ja sen avulla katsotaan mihin kustakin tilasta pudotaan takaisin.

      • Anonyymi

        Nyt kun kaikki toimii hyvin, niin laske kysytty todennäköisyys n:n arvolla 20, jos annetut 12 kuusinumeroista lukua ovat satunnaisia ja erisuuria (ja niissä on vain numeroita (1,2,3,4,5,6)).

        Sain todennäköisyydeksi 0,0038511.
        Toistin 5000 kertaa.


      • Anonyymi kirjoitti:

        Nyt kun kaikki toimii hyvin, niin laske kysytty todennäköisyys n:n arvolla 20, jos annetut 12 kuusinumeroista lukua ovat satunnaisia ja erisuuria (ja niissä on vain numeroita (1,2,3,4,5,6)).

        Sain todennäköisyydeksi 0,0038511.
        Toistin 5000 kertaa.

        Tässä versiossa varmaan riippumattomuusoletus tulee pätemään ja vastaus olisi

        15*12*6^14/6^20 =5/6^4 = 0,00385802


      • Anonyymi
        minkkilaukku kirjoitti:

        Tässä versiossa varmaan riippumattomuusoletus tulee pätemään ja vastaus olisi

        15*12*6^14/6^20 =5/6^4 = 0,00385802

        Vastaus on simuloimalla n. 0,00385107.

        Nopea simuloida, jos muuntaa nuo numerot ensin kuusijärjetelmään eli nopassa numerot (0,1,2,3,4,5) ja näin muodostetun luvun arvon kymmenjärjestelmään. Mikään ei muutu matemaattisesti ajatellen. Riittää siis käydä läpi lukualuetta 0...6^6-1 (0...46655). Seuravat luvut saadaan jakamalla tuo (kymmenjärjestelmän) luvut 6:lla ja ja lisäämällä niihin 6^5. Kaikki yksinkertaistuu ja ohjelma lyhenee ja nopeutuu.

        Alkuperäisen kysymyksen luvut olisivat siis

        Nl = [1865, 266, 28259, 43, 18705, 37367, 0, 9331, 18662, 27993, 37324, 46655]

        Satunnainen lista saadaan nopeasti suoraan randint(0,46655):lla ja if not in Nl:.

        Riittää laskea kokonaismäärä vain n:n arvolla 20 ja summata noita arvoja. Tutulostuksessa summan voi jakaa toistojen 10000:n tai 100000:n määrällä päässälaskuna. Ja ohjelmaa voi ajaa useilla eri ytimillä useita kertoja ja summata luvut copy-pastella taskulaskimella.

        Mitään "riippumattomuusoletuksia"? ei tarvitse miettiä. Ei varsinkaan, jos laskettu tulos ei vastaa simulointia. Ei 12 satunnaislukua ole (juuri koskaan?) täysin riippumattomia tässä tehtävässä. Jos nuo luvut olisivat kuusijärjestelmässä 2 merkkisiä, niitä olisi 4 kpl ja n olisi esim. 8, niin ei olisi mitään ongelmaa käydä läpi joka ikinen vaihtoehto. Kokeile. Saattaa paljastua jotain matemaattisesti mielenkiintoista. Ihan paperillakin laskien.


      • Anonyymi kirjoitti:

        Vastaus on simuloimalla n. 0,00385107.

        Nopea simuloida, jos muuntaa nuo numerot ensin kuusijärjetelmään eli nopassa numerot (0,1,2,3,4,5) ja näin muodostetun luvun arvon kymmenjärjestelmään. Mikään ei muutu matemaattisesti ajatellen. Riittää siis käydä läpi lukualuetta 0...6^6-1 (0...46655). Seuravat luvut saadaan jakamalla tuo (kymmenjärjestelmän) luvut 6:lla ja ja lisäämällä niihin 6^5. Kaikki yksinkertaistuu ja ohjelma lyhenee ja nopeutuu.

        Alkuperäisen kysymyksen luvut olisivat siis

        Nl = [1865, 266, 28259, 43, 18705, 37367, 0, 9331, 18662, 27993, 37324, 46655]

        Satunnainen lista saadaan nopeasti suoraan randint(0,46655):lla ja if not in Nl:.

        Riittää laskea kokonaismäärä vain n:n arvolla 20 ja summata noita arvoja. Tutulostuksessa summan voi jakaa toistojen 10000:n tai 100000:n määrällä päässälaskuna. Ja ohjelmaa voi ajaa useilla eri ytimillä useita kertoja ja summata luvut copy-pastella taskulaskimella.

        Mitään "riippumattomuusoletuksia"? ei tarvitse miettiä. Ei varsinkaan, jos laskettu tulos ei vastaa simulointia. Ei 12 satunnaislukua ole (juuri koskaan?) täysin riippumattomia tässä tehtävässä. Jos nuo luvut olisivat kuusijärjestelmässä 2 merkkisiä, niitä olisi 4 kpl ja n olisi esim. 8, niin ei olisi mitään ongelmaa käydä läpi joka ikinen vaihtoehto. Kokeile. Saattaa paljastua jotain matemaattisesti mielenkiintoista. Ihan paperillakin laskien.

        Joo, ei se tarkasti tuo riippumattomuudella oletettu kaava pädekään. Kokeilin itsekin pienillä arvoilla ja antoi aika eri tuloksen tuo riippumattomuus-kaava. En mitään kaava kyllä niissä tarkoissa arvoissakaan huomannut (aika rajoitettuahan se on minkä kokoiset tapaukset pystyy kaikki enää tarkasti laskemaan).

        Mutta onhan tuo arvo aika lähellä, niin kai siinä jotain sellaista tapahtuu, että ne riippuvuudet "kumoaa toisiaan" kun lasketaan keskiarvoa kaikkien mahdollisten kaksitoistikoiden yli.


      • Anonyymi
        minkkilaukku kirjoitti:

        Joo, ei se tarkasti tuo riippumattomuudella oletettu kaava pädekään. Kokeilin itsekin pienillä arvoilla ja antoi aika eri tuloksen tuo riippumattomuus-kaava. En mitään kaava kyllä niissä tarkoissa arvoissakaan huomannut (aika rajoitettuahan se on minkä kokoiset tapaukset pystyy kaikki enää tarkasti laskemaan).

        Mutta onhan tuo arvo aika lähellä, niin kai siinä jotain sellaista tapahtuu, että ne riippuvuudet "kumoaa toisiaan" kun lasketaan keskiarvoa kaikkien mahdollisten kaksitoistikoiden yli.

        Muuta tehtävän sanamuoto toiseksi. Varmasti joku 1800-luvun matemaatikko on tätä miettinyt ja oeis.org:sta löytyy sitten kaavoja ja listoja eri tapauksille. Vähän mielikuvitusta! Voisi olla 2-numeroisia 5-järjestelmän lukuja 5 kpl ja n = 5.


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

    Luetuimmat keskustelut

    1. Nellietä Emmaa ja Amandaa stressaa

      Ukkii minnuu Emmaa ja Amandaa stressaa ihan sikana joten voidaanko me koko kolmikko hypätä ukin kainaloon ja syleilyyn k
      Isovanhempien jutut
      6
      1247
    2. Mielessäni vieläkin T

      Harmi että siinä kävi niinkuin kävi, rakastin sinua. Toivotan sulle kaikkea hyvää. Toivottavasti löydät sopivan ja hyvän
      Ikävä
      17
      1225
    3. Nähtäiskö ylihuomenna taas siellä missä viimeksikin?

      Otetaan ruokaöljyä, banaaneita ja tuorekurkkuja sinne messiin. Tehdään taas sitä meidän salakivaa.
      Ikävä
      1
      1159
    4. Ei luottoa lakko maahan

      Patria menetti sovitun ksupan.
      Suomen Keskusta
      4
      1154
    5. Sinäkö se olit...

      Vai olitko? Jostain kumman syystä katse venyi.. Ajelin sitten miten sattuu ja sanoin ääneen siinä se nyt meni😅😅... Lis
      Ikävä
      0
      1134
    6. Persut petti kannattajansa, totaalisesti !

      Peraujen fundamentalisteille, vaihtkaa saittia. Muille, näin sen näimme. On helppo luvata kehareille, eikä ne ymmärrä,
      Maailman menoa
      0
      1133
    7. Housuvaippojen käyttö Suomi vs Ulkomaat

      Suomessa housuvaippoja aletaan käyttämään vauvoilla heti, kun ne alkavat ryömiä. Tuntuu, että ulkomailla housuvaippoihin
      Vaipat
      0
      1118
    8. Pupuhuhdasta löytyi lähes sadan kilon miljoonalasti huumeita

      Pupuhuhdasta löytyi lähes sadan kilon miljoonalasti huumeita – neljä Jyväskylän Outlaws MC:n jäsentä vangittu: "Määrät p
      Jyväskylä
      41
      1114
    9. Hyvää yötä ja kauniita unia!

      Täytyy alkaa taas nukkumaan, että jaksaa taas tämän päivän haasteet. Aikainen tipu madon löytää, vai miten se ärsyttävä
      Tunteet
      2
      1105
    10. Lepakot ja lepakkopönttö

      Ajattelin tehdä lepakkopöntön. Tietääkö joku ovatko lepakot talvella lepakkopöntössä ´vai jossain muualla nukkumassa ta
      1
      1100
    Aihe