Autor Zpráva
Vladik.B
Profil
Ahojte Mám výpočet

<head>

<meta http-equiv="Content-Type" content="text/html; charset=utf-8">

</head>

<h1>Možnosti výsledků</h1>

<?php
$k10 = 3.35;
$k11 = 2.37;
$k12 = 3.10;
$k20 = 3.99;
$k21 = 2.30;
$k22 = 2.80;
$k30 = 3.71;
$k31 = 2.75;
$k32 = 2.44;
$k40 = 3.46;
$k41 = 2.68;
$k42 = 2.41;
/*$k10 = 3.45;
$k11 = 1.99;
$k12 = 4.27;
$k20 = 4.32;
$k21 = 5.38;
$k22 = 1.64;
$k30 = 3.45;
$k31 = 1.99;
$k32 = 4.27;
$k40 = 4.32;
$k41 = 5.38;
$k42 = 1.64;*/

$sloupec = 1;
echo "
Rozpis pro 4 zápasů a 3 stavy (0, 1, 2):<br>
";
for ($x=0; $x<=2; $x++)

{
for ($y=0; $y<=2; $y++)

{
for ($z=0; $z<=2; $z++)

{
for ($a=0; $a<=2; $a++)

{
if     ($x == 0){
  
  $k1 = $k10;
}
else
if     ($x == 1){
  
  $k1 = $k11;
}else
if     ($x == 2){
  
  $k1 = $k12;
};
if     ($y == 0){
  
  $k2 = $k20;
}else
if     ($y == 1){
  
  $k2 = $k21;
}else
if     ($y == 2){
  
  $k2 = $k22;
};
if     ($z == 0){
  
  $k3 = $k30;
}else
if     ($z == 1){
  
  $k3 = $k31;
}else
if     ($z == 2){
  
  $k3 = $k32;
};
if     ($a == 0){
  
  $k4 = $k40;
}else
if     ($a == 1){
  
  $k4 = $k41;
}else
if     ($a == 2){
  
  $k4 = $k42;
};    
/*for ($b=0; $b<=2; $b++)
{
for ($c=0; $c<=2; $c++)
{
for ($d=0; $d<=2; $d++)
{
for ($e=0; $e<=2; $e++)
{
for ($f=0; $f<=2; $f++)
{
for ($g=0; $g<=2; $g++)
{
for ($h=0; $h<=2; $h++)/*
{
for ($i=0; $i<=2; $i++)
{
for ($j=0; $j<=2; $j++)
{
for ($k=0; $k<=2; $k++)
{
for ($l=0; $l<=2; $l++)
{
for ($m=0; $m<=2; $m++)
{
for ($n=0; $n<=2; $n++)
{
for ($o=0; $o<=2; $o++)
{
for ($p=0; $p<=2; $p++)*/
$celkem = $k1*$k2*$k3*$k4;
$celkem1 = $k1*$k2*$k3*$k4*5;

/*echo "$sloupec - $x$y$z$a$b$c$d$e$f$g$h$i$j$k$l$m$n$o$p|"; */
echo "<p style='text-align: left'><h5><b>$sloupec</b></h5> $x - $k1<br>$y - $k2<br>$z - $k3<br>$a - $k4 = $celkem =<h5><b style='color: red;'>$celkem1</b></h5><p>";


$sloupec = $sloupec + 1;
}
}
}
}
/*
}
}
}
}
}
}/*
}
}
}
}
}
}
}
}
*/
$sum = 0;
for ($celkem1 = 0; $celkem1 < $index; $celkem1++) {
        if (isset($numbers[$celkem1])) {  // aby náhodou index nebyl vyšší než nejvyšší možný
                $sum += $numbers[$celkem1];
        }
}

echo $sum;
?>

Zobrazí se. Ale pokud chci více Zápasů tak se nedopočítá a nezobrazí celé. Jde to na stránkovat?
Keeehi
Profil
Rád bych pomohl ale tohle se bohužel číst nedá. Data měj nějak vhodně uložená v poli/polích. Proměnné inteligentně pojmenované. Až to předěláš a popíšeš, co to je za data a co ti to má počítat, pak se můžeme podívat na to, zda se to dá někde zefektivnit => urychlit => stihne se to vypočítat v rozumném čase.
Holup
Profil
Kód čo si postol na konci nezobrazí sumu (čohokoľvek čo tie dáta majú reprezentovať), lebo nie je definované pole $numbers.
Inak mi vypísal všetky kombinácie 4 zápasov a 3 stavov. Spolu 3^4 = 81 kombinácií.

Ak chceš variabilný počet zápasov, treba použiť niečo sofistikovanejšie ako opakovať for{...} pre každý zápas.

Nasledujúci kód k tomu využíva rekurzívnu funkciu. Ak chceš pridať viac zápasov, pridaj riadky do poľa $zapasy. Každý riadok je pole hodnôt jedného zápasu pre stavy 0, 1, 2...

Kvôli chýbajúcemu popisu a slabej čitateľnosti tvojho kódu som musel spraviť nejaké predpoklady o jeho účele. Takže ak ho použiješ poriadne si over či výpočet sedí.

<?php
 
    // Definicia zapasov
    $zapasy = [
        [ 3.35, 2.37, 3.10 ],
        [ 3.99, 2.30, 2.80 ],
        [ 3.71, 2.75, 2.44 ],
        [ 3.46, 2.68, 2.41 ]
    ];
    
    // Kontrola definice zapasov
    if( !is_array( $zapasy ) || count( $zapasy ) == 0 || !is_array( $zapasy[ 0 ] ) ) {
        die( "Chyba pri citani zapasov!" );
    }
    
    // Definicia rekurzivnej funkcie na vypis kombinacii zapasov a stavov + vypocet sumy
    function generuj_kombinacie( $zapasy, $aktualna_kombinacia = [], $index_zapasu = 0 ) {
 
        static $index_kombinacie;
 
        if( $index_zapasu == count( $zapasy ) ) {
            // Kombinacia hotova...
            echo "<p>";
            $stlpec = $index_kombinacie + 1;
            echo "<h5><b>$stlpec</b></h5>";
            $celkom = 1; // dalej nasobime pre kazdy zapas
            foreach( $aktualna_kombinacia as $index => $zapas ) {
                $celkom *= $zapas[ "hodnota" ];
                echo $zapas[ "stav" ] . " - " . $zapas[ "hodnota" ];
                if( $index == array_key_last( $aktualna_kombinacia ) ) {
                    // Ak sme na poslednom zapase kombinacie, vypiseme produkt
                    echo " = $celkom = ";
                }
                echo "<br>";
            }
            $celkom_krat_5 = $celkom * 5;
            echo "<h5><b style='color: red;'>" . $celkom_krat_5 . "</b></h5>";
            echo "</p>";
            $index_kombinacie++;
            return $celkom_krat_5;
        }
 
        $suma = 0;
        $pocet_stavov = count( $zapasy[ 0 ] );
        for( $stav = 0; $stav < $pocet_stavov; $stav++ ) {
            $aktualna_kombinacia[ $index_zapasu ][ "stav" ] = $stav;
            $aktualna_kombinacia[ $index_zapasu ][ "hodnota" ] = $zapasy[ $index_zapasu ][ $stav ];
            $suma += generuj_kombinacie( $zapasy, $aktualna_kombinacia, $index_zapasu + 1 );
        }
 
        return $suma;
 
    }
    
    // HTML start...
    
?>
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
</head>
<body>
 
    <h1>Možnosti výsledků</h1>
 
    Rozpis pro <?= count( $zapasy ) ?> zápasů a <?= count( $zapasy[ 0 ] ) ?> stavy (<?= implode( ", ", array_keys( $zapasy[ 0 ] ) ) ?>):<br>
 
    <?php
        // Prvotne volanie definovanej rekurzivnej funkcie
        $suma = generuj_kombinacie( $zapasy );
        echo "SUMA: $suma<br>";
    ?>
    
</body>
</html>
Holup
Profil
Aby som aj naozaj odpovedal na tvoju otázku prikladám kód rozšírený o stránkovanie.

Treba si tu uvedomiť že počet kombinácií rastie exponenciálne s počtom zápasov.

Vzorec je počet kombinácií = počet stavov ^ počet zápasov.

Zakomentované premenné v tvojom kóde naznačujú že si sa to snažil použiť pre cca 20 zápasov. To je 3,486,784,401 kombinácií. To je 1,594,323 strán pri 729 kombináciách na stranu. Ak to chceš naozaj použiť s týmito číslami tak sa pohraj s funkciou vypis_zoznam_stran() aby zobrazovala napr. len predchádzajúcu, aktuálnu a nasledujúcu stranu, inak ten zoznam strán bude mať PHP problém generovať a prehliadač zobraziť.

Ber do úvahy že tento stránkovaný kód na konci zobrazí sumu len pre aktuálnu stranu. Ak potrebuješ vždy celkovú sumu všetkých možných kombinácií, mám tušenie že by sa dal použiť nejaký matematický trik aby nebolo treba prechádzať všetky kombinácie... ale neviem ti povedať aký.

<?php
    
    // Definicia zapasov
    $zapasy = [
        [ 3.35, 2.37, 3.10 ],
        [ 3.99, 2.30, 2.80 ],
        [ 3.71, 2.75, 2.44 ],
        [ 3.46, 2.68, 2.41 ],
        [ 3.35, 2.37, 3.10 ],
        [ 3.99, 2.30, 2.80 ],
        [ 3.71, 2.75, 2.44 ],
        [ 3.46, 2.68, 2.41 ]
    ];
    
    // Kontrola definice zapasov
    if( !is_array( $zapasy ) || count( $zapasy ) == 0 || !is_array( $zapasy[ 0 ] ) ) {
        die( "Chyba pri citani zapasov!" );
    }
    
    // Rekurzivna funkcia na vypis kombinacii zapasov a stavov + vypocet sumy
    function generuj_kombinacie( $zapasy, $pocet_zapasov_na_kombinovanie_na_stranu, $aktualna_kombinacia = [], $index_zapasu = 0 ) {
        
        static $index_kombinacie = 0; // rata sa z neho cislo stlpca
        
        $pocet_zapasov = count( $zapasy );
        $pocet_stavov = count( $zapasy[ 0 ] );
        $pocet_kombinacii_na_stranu = pow( $pocet_stavov, $pocet_zapasov_na_kombinovanie_na_stranu );
        
        // Ak je kombinacia hotova vypiseme ju a ukoncime funkciu
        if( $index_zapasu == $pocet_zapasov ) {
            echo "<p>";
            $stlpec = ( ( ziskat_aktualnu_stranu() - 1 ) * $pocet_kombinacii_na_stranu ) + ( $index_kombinacie + 1 );
            echo "<h5><b>$stlpec</b></h5>";
            $celkom = 1; // dalej nasobime pre kazdy zapas
            foreach( $aktualna_kombinacia as $index => $zapas ) {
                $celkom *= $zapas[ "hodnota" ];
                echo $zapas[ "stav" ] . " - " . $zapas[ "hodnota" ];
                if( $index == array_key_last( $aktualna_kombinacia ) ) {
                    // Ak sme na poslednom zapase kombinacie, vypiseme produkt
                    echo " = $celkom = ";
                }
                echo "<br>";
            }
            $celkom_krat_5 = $celkom * 5;
            echo "<h5><b style='color: red;'>" . $celkom_krat_5 . "</b></h5>";
            echo "</p>";
            $index_kombinacie++;
            return $celkom_krat_5;
        }
        
        // Ak nie je kombinacia hotova pokracujeme/zacneme v kombinovani
        $suma = 0;
        for( $stav = 0; $stav < $pocet_stavov; $stav++ ) {
            $aktualna_kombinacia[ $index_zapasu ][ "stav" ] = $stav;
            $aktualna_kombinacia[ $index_zapasu ][ "hodnota" ] = $zapasy[ $index_zapasu ][ $stav ];
            $suma += generuj_kombinacie( $zapasy, $pocet_zapasov_na_kombinovanie_na_stranu, $aktualna_kombinacia, $index_zapasu + 1 );
        }
        
        return $suma;
        
    }
    
    // Funkcia ktora zavola generuj_kombinacie() tak aby vypisali len kombinacie pre danu stranu
    function vypisat_stranu( $zapasy, $pocet_zapasov_na_kombinovanie_na_stranu, $strana = 1 ) {
        
        // Inicializacna kombinacia - bude mat posledne zapasy (urcene parametrom $pocet_zapasov_na_kombinovanie_na_stranu) so stavom 0,
        // tieto na danej strane prejdu cez vsetky kombinacie. Ostatne zapasy budu mat stav fixny - bude zavysiet od aktualnej strany.
        $inicializacna_kombinacia = [];
        $pocet_zapasov = count( $zapasy );
        $pocet_stavov = count( $zapasy[ 0 ] );
        foreach( $zapasy as $index_zapasu => $zapas ) {
            if( $index_zapasu >= $pocet_zapasov - $pocet_zapasov_na_kombinovanie_na_stranu ) {
                // Posledne zapasy (tie ktore na danej strane kombinujeme) inicializijeme vzdy so stavom 0
                $stav = 0;
            } else {
                //  Zistenie stavu fixneho zapasu na zaklade strany, indexu zapasu a konfiguracie strankovania...
                // Ak mame 3 stavy (0,1,2)...
                // - Posledny fixny zapas bude mat stavy:         0 1 2 0 1 2 0 1 2 0 1 2 0 1 2 0 1 2 0 1 2 0 1 2 0 1 2
                // - Predposledny fixny zapas bude mat stavy:     0 0 0 1 1 1 2 2 2 0 0 0 1 1 1 2 2 2 0 0 0 1 1 1 2 2 2
                // - Predpredposledny fixny zapas bude mat stavy: 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2
                // ... atd. Pocet stavov je urceny na zaklade definicie zapasov.
                $kuzlo = pow( $pocet_stavov, $pocet_zapasov - $pocet_zapasov_na_kombinovanie_na_stranu - $index_zapasu - 1 );
                $stav = floor( ( $strana - 1 ) / $kuzlo ) % $pocet_stavov;
            }
            $inicializacna_kombinacia[ $index_zapasu ] = [ "stav" => $stav, "hodnota" => $zapas[ $stav ] ];
        }
        
        // Inicializacny index zapasu - od tohoto zapasu budeme vytvarat na danej strane kombinacie, zapasy pred nim budu fixne (urcene inicializacnou kombinaciou)
        $inicializacny_index_zapasu = $pocet_zapasov - $pocet_zapasov_na_kombinovanie_na_stranu;
        
        // Prvotne volanie rekurzivnej funkcie
        $suma = generuj_kombinacie( $zapasy, $pocet_zapasov_na_kombinovanie_na_stranu, $inicializacna_kombinacia, $inicializacny_index_zapasu );
        
        echo "SUMA: $suma<br>";
        
    }
    
    // Funkcia na vypis zoznamu stran
    function vypis_zoznam_stran( $zapasy, $pocet_zapasov_na_kombinovanie_na_stranu, $aktualna_strana ) {
        
        $pocet_zapasov = count( $zapasy );
        $pocet_stavov = count( $zapasy[ 0 ] );
        $pocet_kombinacii = pow( $pocet_stavov, $pocet_zapasov );
        $pocet_kombinacii_na_stranu = pow( $pocet_stavov, $pocet_zapasov_na_kombinovanie_na_stranu );
        $pocet_stran = ceil( $pocet_kombinacii / $pocet_kombinacii_na_stranu );
        
        for( $strana = 1; $strana <= $pocet_stran; $strana++ ) {
            // CSS Styl
            $css = "text-decoration: none;";
            if( $strana == $aktualna_strana ) {
                $css .= "font-weight: bold; font-size: 1.5em;";
            }
            // HTML Link
            echo "<a href='" . $_SERVER[ "PHP_SELF" ] . "?strana=$strana' style='$css'>[$strana]</a> ";
        }
        
    }
    
    // Zistit cislo strany z URL
    function ziskat_aktualnu_stranu() {
        if( isset( $_GET[ "strana" ] ) && intval( $_GET[ "strana" ] ) == $_GET[ "strana" ] ) {
            return $_GET[ "strana" ];
        } else {
            return 1;
        }
    }
    
    // HTML start...
    
?>
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
</head>
<body>
    
    <h1>Možnosti výsledků</h1>
    
    <p>
        Rozpis pro <?= count( $zapasy ) ?> zápasů
        a <?= count( $zapasy[ 0 ] ) ?> stavy
        (<?= implode( ", ", array_keys( $zapasy[ 0 ] ) ) ?>);
        strana: <?= ziskat_aktualnu_stranu() ?>
    </p>
    
    <?php
        
        // Konfiguracia strankovania
        $pocet_zapasov_na_kombinovanie_na_stranu = 4; // vacsie cislo = menej dlhsich stran
        $aktualna_strana = ziskat_aktualnu_stranu();
        
        // Zoznam stran hore
        vypis_zoznam_stran( $zapasy, $pocet_zapasov_na_kombinovanie_na_stranu, $aktualna_strana );
        
        // Kombinacie zapasov pre danu stranu
        vypisat_stranu( $zapasy, $pocet_zapasov_na_kombinovanie_na_stranu, $aktualna_strana );
        
        // Zoznam stran dole
        vypis_zoznam_stran( $zapasy, $pocet_zapasov_na_kombinovanie_na_stranu, $aktualna_strana );
        
    ?>
    
</body>
</html>
Vladik.B
Profil
je to super. přesně jak jsem si to představoval. Moc děkuji. Ale i toho stránkování je hrozně moc. Myslel jsem, že miliarda a půl není zas tak velké číslo. Si lepší založit sázkový web :-) Ještě to zkusím na localhostu, ale už tomu nevěřím. Ale je to krásně naprogramovaný. Nejspíš by bylo lepší kdybych mohl zadat jen číslo kombinace a zobrazilo by to jen aktualní tiket. To by už šlo, že? O víkendu to zkusím
Holup
Profil
Vladik.B:
To by šlo.

To by si sa mohol zbaviť tej rekurzívnej funkcie na generovanie kombinácií a iba vybrať a mierne upraviť foreach( $zapasy ){} vo funkcii vypisat_stranu(), ktorý ti zistí stavy zápasov ktoré nekombinujeme pre danú stranu. Premenná $pocet_zapasov_na_kombinovanie_na_stranu by bola v takomto prípade 0, keďže nechceme žiadnu pozíciu kombinovať - čiže ju môžeš vypustiť. A premennú $strana môžeš použiť ako je, s tým že keď bude vždy zobrazená len jedna kombinácia tak to vlastne znamená jednu kombináciu na jednu stranu, a číslo strany potom vlastne znamená číslo kombinácie. Prípadne tú premennú len premenuj na $cislo_kombinacie, aby to bolo jasné.

Ďalej v tom foreach mám premennú $kuzlo. Lepší názov by bol $delitel.
Ide o to že chceme postupnosť 012 012 012 atď pre posledný zápas, a prakticky tú istú postupnosť chceme pre predposledný zápas, ale 3x pomalšiu (lebo 3 stavy): 000 111 222 000 111 222 atď.
Pre tretí zápas z prava chceme tú postupnosť 9x pomalšiu, štvrtý 21x poamlšiu atď. Všeobecné pravidlo teda je že "rýchlosť" zmeny pre daný zápas je (počet stavov ^ index zápasu z prava) krát pomalšia.
3 ^ 0 = 1
3 ^ 1 = 3
3 ^ 2 = 9
Kúzlo je v tom že keď vydelíme index kombinácie (číslo kombinácie - 1) týmto číslom, zaokrúhlime nadol a vydelíme počtom stavov, tak zvyšok po delení bude stav zápasu (pre daný index zápasu a čislo kombinácie).
Napr. pre index kombinácie 0 až 5 a predposledný zápas (3x "pomalši"), bude postupnosť pred zaokrúhlením 0; 0.33; 0.66; 1; 1.33; 1.66; po zaokrúhlení 0; 0; 0; 1; 1; 1


Mohol by si ten foreach vytiahnuť do samostatnej funkcie ktorá zoberie zápasy a číslo kombinácie ako parameter a potom ju používať nejak takto:
$zapasy = [ ... ];

function vypis_kombinaciu( $zapasy, $cislo_kombinacie ) {
    // ...
}

$pocet_zapasov = count( $zapasy );
$pocet_stavov = count( $zapasy[ 0 ] );
$pocet_kombinacii = pow( $pocet_stavov, $pocet_zapasov );

// Vypisat kombinaciu cislo 70
vypis_kombinaciu( $zapasy, 70 );

// Vypisat rozsah kombinacii od $start do $stop
$start = 1;
$stop = $pocet_kombinacii;
for( $cislo_kombinacie = $start; $cislo_kombinacie <= $stop; $cislo_kombinacie++ ) {
    vypis_kombinaciu( $zapasy, $cislo_kombinacie );
}

Vaše odpověď

Mohlo by se hodit


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm:

0