Pagina 1 van 1

Lotto nummers

Geplaatst: 30 nov 2020, 13:32
door Leinad
Beste mensen,

Ik ben al een tijdje op zoek naar een manier om uit te rekenen welke specifieke lotingcombinatie, welk serienummer heeft. Ik kom er niet uit dus vraag ik jullie hulp.

Wat bedoel ik met serienummer? Wel, stel er is een fictieve loterij waarbij 3 getallen worden getrokken tussen de 1 en de 6. Het maximaal aantal combinaties in deze loterij is:

C = 6! : ( 3! x (6 - 3)! )
C = 20 maximaal aantal combinaties

Alle mogelijke combinaties zijn dan:

Combinatie 1: 1-2-3
Combinatie 2: 1-2-4
Combinatie 3: 1-2-5
Combinatie 4: 1-2-6
Combinatie 5: 1-3-4
Combinatie 6: 1-3-5
Combinatie 7: 1-3-6
Combinatie 8: 1-4-5
Combinatie 9: 1-4-6
Combinatie 10: 1-5-6
Combinatie 11: 2-3-4
Combinatie 12: 2-3-5
Combinatie 13: 2-3-6
Combinatie 14: 2-4-5
Combinatie 15: 2-4-6
Combinatie 16: 2-5-6
Combinatie 17: 3-4-5
Combinatie 18: 3-4-6
Combinatie 19: 3-5-6
Combinatie 20: 4-5-6

Waar ik naar op zoek ben is een berekening/formule waarin ik bijvoorbeeld kan invoeren
de combinatie: 2-4-6 en als uitkomst krijg: 15

Of (misschien) andersom waarbij ik kan invoeren: 15 en als uitkomst krijg: 2-4-6


Who? :idea:

Re: Lotto nummers

Geplaatst: 30 nov 2020, 20:42
door arie

Code: Selecteer alles

\\ geef het combinatienummer van de vector v met elementen gekozen uit in totaal n items (1,2,3,...,n)
combinatieNummer(n,v)={
l=length(v);
result=1;                       \\ initieer resultaat, tel de combinaties vanaf 1
m=n;
k=l;
for(i=1,l,                      \\ voor i = 1 t/m l:
  result+=binomial(m,k)-binomial(m-v[i]+1,k);
  m=m-v[i];
  k=k-1;
  for(j=i+1,l,
    v[j]=v[j]-v[i];
    );
  );
return(result);
}

\\ MAIN:
{
print(combinatieNummer(6, [2,4,6]));
}
Hierboven een sorteeralgoritme voor je probleem.
De functie combinatieNummer(n, v) geeft je antwoord.
n = totaal aantal items waaruit gekozen kan worden (in jouw voorbeeld 6)
v = de vector met de gegeven combinatie (in jouw voorbeeld [2, 4, 6])
Het algoritme geeft met jouw getallen als resultaat: 15.

Volstaat deze programmacode of heb je meer informatie nodig?
In het laatste geval: welke programmeertaal gebruik je?


EDIT:
En hier de omgekeerde bewerking:
De aanroep combinatieVector(6, 3, 15) geeft als resultaat de vector [2, 4, 6]

Code: Selecteer alles

\\ geef de vector van combinatienummer t van C(n,k)
combinatieVector(n,k,t)={
v=vector(k);
s=0;
for(i=1,k,
  v[i]=1;
  if(i==1,
    v[i]=1;
    , \\ELSE: 
    v[i]=1+v[i-1];
    );
  while(s+binomial(n-v[i],k-i)<t,
    s=s+binomial(n-v[i],k-i);
    v[i]=v[i]+1;
    );
  );
return(v);
}

Re: Lotto nummers

Geplaatst: 01 dec 2020, 12:32
door Leinad
Hoi Arie,

Dank je wel voor je reactie. Ik kan het helaas niet uitproberen want ik gebruik de scripttaal PHP. De taal waarin je het voorbeeld geeft is in C? Ik hoop dat je mij kunt helpen jouw code om te zetten in PHP...

Alvast bedankt!

Re: Lotto nummers

Geplaatst: 01 dec 2020, 17:48
door Leinad
Nogmaals goedendag Arie,

Het is me al gelukt om jouw code om te zetten in PHP. Enorm bedankt voor jou code want het werkt heel goed.

Het enige nadeel echter, is dat door de while en for lussen het erg lang duurt (tot wel 30 seconden) voordat het serienummer is "berekend". Weet iemand misschien een wiskundige manier in plaats van een for- of while- lus??

Alvast bedankt!

Re: Lotto nummers

Geplaatst: 01 dec 2020, 20:56
door arie
Hieronder de functie combinatieNummer(n, k) in PHP code.
Ik heb de functie iets anders geformuleerd (zonder de binnenste for()-lus).
In https://sandbox.onlinephpfunctions.com/ werk dit behoorlijk snel, bij jou ook?


PHP code:

Code: Selecteer alles

<?php

function binomial($n, $k)
{
    if($k<0 || $k>$n)
    {
        return(0);
    }
    $r=$n-$k;
    if($r<$k)
    {
        $k=$r;
    }
    $teller=1;
    $noemer=1;
    for ( $i=1; $i<=$k; $i++)
    {
        $teller *= ($n-$i+1);
        $noemer *= $i;
    }
    return($teller/$noemer);
}
  

// geef het combinatienummer van de vector v met elementen gekozen uit in totaal n items (1,2,3,...,n)
function combinatieNummer($n, $v)
{
echo "n = ".$n."\n";
$k = sizeof($v);
echo "k = ".$k."\n";
$l=$k;
$result=1;
$delta=0;
foreach( $v as $key => $value )
{
        $result+=(binomial($n,$k)-binomial($n-$value+$delta+1,$k));
        $n-=($value-$delta);
        $k--;
        $delta=$value;
}
return($result);
}


echo "result1 = ".combinatieNummer(6, array(2, 4, 6))."\n";
echo "result2 = ".combinatieNummer(20,array(5,9,12,14,18))."\n";
echo "result3 = ".combinatieNummer(100,array(4,8,12,35,67,88,92,99))."\n";
echo "result4 = ".combinatieNummer(1234, array(123,456,789,1001))."\n";


Output:

Code: Selecteer alles

n = 6
k = 3
result1 = 15
n = 20
k = 5
result2 = 12098
n = 100
k = 8
result3 = 44176091579
n = 1234
k = 4
result4 = 32929808822

Re: Lotto nummers

Geplaatst: 01 dec 2020, 22:30
door Leinad
Wauw!! Deze PHP code is inderdaad heel snel.

Ik durf het bijna niet te vragen Arie, maar... Hoe ziet de PHP code eruit als ik het serienummer invoer om de combinaties (met deze snelheid) te vinden, dus de omgekeerde bewerking?? :oops:

Re: Lotto nummers

Geplaatst: 02 dec 2020, 00:27
door arie
Hier de complete code, nu met combinatieVector() erbij.
De voorbeelden zijn hetzelfde als de vorige keer, maar nu in omgekeerde richting.
Daarna levert de code de tabel uit je eerste post.

NOOT: ik ben geen PHP programmeur, mogelijk kan je e.e.a. nog wat netter opschrijven.
Het werkt in ieder geval binnen de 3 secondenlimiet van https://sandbox.onlinephpfunctions.com/.


PHP code:

Code: Selecteer alles

<?php

function binomial($n, $k)
{
    if($k<0 || $k>$n)
    {
        return(0);
    }
    $r=$n-$k;
    if($r<$k)
    {
        $k=$r;
    }
    $teller=1;
    $noemer=1;
    for ( $i=1; $i<=$k; $i++)
    {
        $teller *= ($n-$i+1);
        $noemer *= $i;
    }
    return($teller/$noemer);
}
  

// geef het combinatienummer van de vector v met elementen gekozen uit in totaal n items (1,2,3,...,n)
function combinatieNummer($n, $v)
{
echo "n = ".$n."\n";
$k = sizeof($v);
echo "k = ".$k."\n";
$l=$k;
$result=1;
$delta=0;
foreach( $v as $key => $value )
{
        $result+=(binomial($n,$k)-binomial($n-$value+$delta+1,$k));
        $n-=($value-$delta);
        $k--;
        $delta=$value;
}
return($result);
}


// geef de vector van combinatienummer t van C(n,k)
function combinatieVector($n, $k, $t)
{
$v=array();
$s=0;
$vi=1;
for($i=1; $i<=$k; $i++)
{
  while($s<$t)
  {
      $b=binomial($n-$vi,$k-$i);
      $s+=$b;
      $vi++;
  }
  $s-=$b;
  array_push($v, $vi - 1);
}
return($v);
}


function printCombinatie($v)
{
    $l=sizeof($v);
    $i=1;
    foreach($v as $value)
    {
        if($i==1)
        {
           echo "{".$value;
        }
        elseif($i==$l)
        {
            echo ", ".$value."}\n";
        }
        else
        {
        echo ", ".$value;    
        }
        $i++;
    }    
}


printCombinatie(combinatieVector(6,3,15));
printCombinatie(combinatieVector(20,5,12098));
printCombinatie(combinatieVector(100,8,44176091579));
printCombinatie(combinatieVector(1234,4,32929808822));
echo "---------------------------------------\n";
for($z=1; $z<=20; $z++)
{
    $w=combinatieVector(6,3,$z);
    echo "Combinatie ".$z.": ";
    printCombinatie($w);
}




Output:

Code: Selecteer alles

{2, 4, 6}
{5, 9, 12, 14, 18}
{4, 8, 12, 35, 67, 88, 92, 99}
{123, 456, 789, 1001}
---------------------------------------
Combinatie 1: {1, 2, 3}
Combinatie 2: {1, 2, 4}
Combinatie 3: {1, 2, 5}
Combinatie 4: {1, 2, 6}
Combinatie 5: {1, 3, 4}
Combinatie 6: {1, 3, 5}
Combinatie 7: {1, 3, 6}
Combinatie 8: {1, 4, 5}
Combinatie 9: {1, 4, 6}
Combinatie 10: {1, 5, 6}
Combinatie 11: {2, 3, 4}
Combinatie 12: {2, 3, 5}
Combinatie 13: {2, 3, 6}
Combinatie 14: {2, 4, 5}
Combinatie 15: {2, 4, 6}
Combinatie 16: {2, 5, 6}
Combinatie 17: {3, 4, 5}
Combinatie 18: {3, 4, 6}
Combinatie 19: {3, 5, 6}
Combinatie 20: {4, 5, 6}

Re: Lotto nummers

Geplaatst: 02 dec 2020, 02:07
door Leinad
WAANZINNIG TOP ARIE!

Jij hebt er 3 kleine en snelle functies van gemaakt. Heel erg bedankt!! :D 8)