6 unikátních čísel

Webdesign, HTML, CSS, Flash, PHP, ASP, .NET, JavaScript. Kritika www stránek na Smetišti.

Moderátor: Moderátoři Živě.cz

Odeslat příspěvekod Zbynas 29. 7. 2018 20:29

Zdar jak sviňa, můžete mi prosím vysvětlit, kde mám chybu, potřebuju 6 uniktních čísel z 50, ale generuje to občas dvě stejná čísla. Díky ... :)

Kód: Vybrat vše
   if ($losovat_pocet > 0){
      $insert_prikaz = "INSERT INTO tazena_cisla
      (cislo_losovani,datum,cislo1,cislo2,cislo3,cislo4,cislo5,cislo6) VALUES ";

      while ($losovano <= $losovat_pocet){
      $res42 = @mysql_query("select * from tazena_cisla");
      $pocet_losovani = @mysql_num_rows($res42)+1;


      $datum_losovani = $posledni_datum + ((10*60)*$losovano);

      $numbers[0] = 0; $numbers[1] = 0; $numbers[2] = 0;
      $numbers[3] = 0;$numbers[4] = 0; $numbers[5] = 0; unset($numbers);
      do {$cislo1 = round(rand(1,50)); $numbers[]=$cislo1; $counts = array_count_values($cislo1,$numbers)."x";} while (array_count_values($cislo1,$numbers)==1);
      do {$cislo2 = round(rand(1,50)); $numbers[]=$cislo2; $counts = array_count_values($numbers);} while ($counts[$counts]==1);
      do {$cislo3 = round(rand(1,50)); $numbers[]=$cislo3; $counts = array_count_values($numbers);} while ($counts[$counts]==1);
      do {$cislo4 = round(rand(1,50)); $numbers[]=$cislo4; $counts = array_count_values($numbers);} while ($counts[$counts]==1);
      do {$cislo5 = round(rand(1,50)); $numbers[]=$cislo5; $counts = array_count_values($numbers);} while ($counts[$counts]==1);
      do {$cislo6 = round(rand(1,50)); $numbers[]=$cislo6; $counts = array_count_values($numbers);} while ($counts[$counts]==1);
      echo "test ".count($numbers)."<br>";
      print_r(array_values($numbers));
      
      $insert_prikaz = $insert_prikaz."('$pocet_losovani','$datum_losovani','$cislo1','$cislo2','$cislo3','$cislo4','$cislo5','$cislo6')";
      if ($losovano < $losovat_pocet) $insert_prikaz = $insert_prikaz.",";
      $losovano += 1;
      }
   $insert = @MySQL_Query($insert_prikaz);
   //if ($insert == 0) echo "CHYBA ve vkládání do DB"; else echo "TAŽENO ".$pocet_losovani." x.";
   }
NVidia GTX 1060 6GB, Intel Core i7-2600K @ 3,4 GHz, 16 GB DDR 3
Download 100 Mbps, Upload 100 Mbps, ping 8
VINOTÉKA U FREJKA
FREJK.CZ, FREJK.SK, FREJK.COM
Zbynas
Junior
Uživatelský avatar

Odeslat příspěvekod Zbynas 29. 7. 2018 21:42

PS chybu na prvním řádku jsem hned poté našel (tedy na řádku táhnutí prvního čísla), ale tímj to nebylo ...
NVidia GTX 1060 6GB, Intel Core i7-2600K @ 3,4 GHz, 16 GB DDR 3
Download 100 Mbps, Upload 100 Mbps, ping 8
VINOTÉKA U FREJKA
FREJK.CZ, FREJK.SK, FREJK.COM
Zbynas
Junior
Uživatelský avatar

Odeslat příspěvekod Wikan 30. 7. 2018 07:22

No já teda v PHP nedělám, ale řekl bych, že je to naprosto špatně:
Losuješ určitý počet čísel, proč to neděláš v cyklu?
Proč tam máš proměnné $cisloX, a nepoužiješ pole (které tam už stejně máš - $numbers)?
Kód: Vybrat vše
$numbers[]=$cisloX

Nepřepisuješ si to pole náhodou pořád dokola?
Kód: Vybrat vše
$counts[$counts]==1

Tohle asi taky nebude dobře. Indexuješ pole polem samotným?
Wikan
Moderátor
Uživatelský avatar

Odeslat příspěvekod djkubas91 30. 7. 2018 08:23

No, v tom jak je to správně napsaný ti moc neporadím, ale není to holt tím, že tam nemáš žádnou pojistku proti dvěma stejným číslům? Vybíráš 6x náhodné číslo z oboru hodnot 1-50, což může být při troše štěstí klidně šestkrát jednička. Ty bys IMHO potřeboval po každém výběru ověřit, že tam ta daná hodnota už v Array jednou není.
MacBook Pro 13" TB 2017
RaspberryPi 3B
Synology DS213j

IoT je závislost
djkubas91
Junior

Odeslat příspěvekod JirkaVejrazka 30. 7. 2018 08:53

Cele to mas nejak zbytecne slozite a komplikovane - proc do toho michas databazi? Proste si napis funkci, ktera vrati sest cisel a az s jejim vystupem pak pracuj.

V PHP ti neporadim, mam na nej alergii. Ale v Pythonu sest ruznych cisel generuje tenhle kod:

Kód: Vybrat vše
from random import randint
nums = set()

while len(nums) < 6:
    nums.add(randint(1,50))

print(nums)
JirkaVejrazka
Mírně pokročilý

Odeslat příspěvekod Nargon 30. 7. 2018 16:27

V PHP nedělám tak nepoznám co z toho je chyba zápisu a co je chyba návrhu, ale zdá se mi to celé nějaké divné. Viz to co psal Wikan, ten zápis se mi vůbec nelíbí, podle mě tam máš nějaké takové zásadní chyby v syntaxi.
Ale když to vezmu obecně. Tak kód by měl vypadat asi takto, je to takový pseudokód, ale snad to pochopíš:

Kód: Vybrat vše
Proměnná $NUMBERS (asi nějaké pole), která slouží pro uložení těch 6ti čísel.

while ($NUMBERS.COUNT < 6) //test zda pole numbers obsahuje 6 čísel, pokud ne, tak se opakuje cyklus níže
{
   $RND = NewRandomNumber (1,50) //vygenerování nového náhodného čísla z rozsahu.
   IF ($NUMBERS.NOTCONTAINS($RND)) //test zda pole $NUMBERS neobsahuje nově vygenerované číslo
   {
        $NUMBERS.ADD($RND)  //pokud neobsahuje, tak do pole toto číslo přidáme
   }  //pokud obsahuje, tak nic neděláme a necháme cyklus proběhnout znovu
}

//A tady máš pole $NUMBERS, naplněné 6ti rozdílnými čísly z rozsahu 1-50.
Desktop: Ryzen 7 1800X (3.95GHz, 1.35V), Asus Crosshair VI Hero, 16GB DDR4 Ram (3200MHz), 128GB SSD + 3TB HDD, Nvidia GTX 1080
Notebook: Asus UL50VT 15.6" (SU7300@1.7GHz, 4GB ram, 500GB HDD, Intel GMA 4500MHD + nVidia G210M, dlouha vydrz cca 7+ hod)
Nargon
Moderátor

Odeslat příspěvekod Zbynas 2. 8. 2018 08:36

Díky moc všem, Nargon - to zkusím díky, ale stejně mě zajímá, proč tohle nefunguje. Stáhle to občas generuje stejná čísla ...

Kód: Vybrat vše
do {$cislo1 = round(rand(1,50)); $numbers[]=$cislo1; } while (array_count_values($numbers)==1);

do {$cislo2 = round(rand(1,50)); $numbers[]=$cislo2; } while (array_count_values($numbers)==1);

do {$cislo3 = round(rand(1,50)); $numbers[]=$cislo3; } while (array_count_values($numbers)==1);

do {$cislo4 = round(rand(1,50)); $numbers[]=$cislo4; } while (array_count_values($numbers)==1);

do {$cislo5 = round(rand(1,50)); $numbers[]=$cislo5; } while (array_count_values($numbers)==1);

do {$cislo6 = round(rand(1,50)); $numbers[]=$cislo6; } while (array_count_values($numbers)==1);




-- 2. 8. 2018 10:21 --

Tak tohle by už mělo fungovat, jsem zapnul i ty mozkový bunky co nemám :D

Kód: Vybrat vše
      
do {$cislo1 = round(rand(1,50)); } while (in_array($cislo1,$numbers)); $numbers[]=$cislo1;
do {$cislo2 = round(rand(1,50)); } while (in_array($cislo2,$numbers)); $numbers[]=$cislo2;
do {$cislo3 = round(rand(1,50)); } while (in_array($cislo3,$numbers)); $numbers[]=$cislo3;
do {$cislo4 = round(rand(1,50)); } while (in_array($cislo4,$numbers)); $numbers[]=$cislo4;
do {$cislo5 = round(rand(1,50)); } while (in_array($cislo5,$numbers)); $numbers[]=$cislo5;       
do {$cislo6 = round(rand(1,50)); } while (in_array($cislo6,$numbers)); $numbers[]=$cislo6;


PS NOTCONTAINS() mi píše, že funkce je neznámá ...
NVidia GTX 1060 6GB, Intel Core i7-2600K @ 3,4 GHz, 16 GB DDR 3
Download 100 Mbps, Upload 100 Mbps, ping 8
VINOTÉKA U FREJKA
FREJK.CZ, FREJK.SK, FREJK.COM
Zbynas
Junior
Uživatelský avatar

Odeslat příspěvekod Wikan 2. 8. 2018 09:41

PS NOTCONTAINS() mi píše, že funkce je neznámá ...

je to takový pseudokód


I když ti ten současný kód funguje, tak je to vcelku prasárna.
Wikan
Moderátor
Uživatelský avatar

Odeslat příspěvekod Prochycz 2. 8. 2018 13:16

Kód: Vybrat vše
$numbers = range(1, 50);
shuffle($numbers);
$uniqueNumbers=array_slice($numbers, 0, 6);
Prochycz
Junior

Odeslat příspěvekod Václav M. 8. 12. 2018 23:49

JirkaVejrazka píše:Cele to mas nejak zbytecne slozite a komplikovane - proc do toho michas databazi? Proste si napis funkci, ktera vrati sest cisel a az s jejim vystupem pak pracuj.

Problém není v zamíchání databáze samotném, ale v způsobu, jakým je to uděláno.

Jestliže chci 6 náhodných čísel z určitého rozsahu (jestli jsem správně pochopil), pak potřebuji nějak získat ten rozsah (například seznam losovatelných čísel). Ten bych si ale z DB nejprve načetl, poté z něj teprve losoval - a teprve po vylosování zápis do DB.

Ale teď k losování - trochu zobecněno. V tomto případě (asi) není zaručeno, že všech 6 čísel bude opravdu unikátních.
Kód: Vybrat vše
$SeznamLosovatelnychCisel = [...];
$Losovano = array_rand($SeznamLosovatelnychCisel, 6);

Je to ale jen jedno z mnoha možných řešení. Dala by se napsat spousta dalších - např.
Kód: Vybrat vše
$SeznamLosovatelnychCisel = [...];
$Losovano = [];
$VylosovaneCislo = 0;
for($Cislo = 0; count($Losovano) == 6; $Cislo++)
{
$VylosovaneCislo = array_rand($SeznamLosovatelnychCisel);

if(!in_array($VylosovaneCislo))
{
  $Losovano[] = $VylosovaneCislo;
}
}

nebo (možná trochu rychlejší)
Kód: Vybrat vše
$SeznamLosovatelnychCisel = [...];
$Losovano = [];
$VylosovanaCisla = [];
for($Cislo = 0; count($Losovano) == 6; $Cislo++)
{
$VylosovanaCisla = array_rand($SeznamLosovatelnychCisel, 6);
$Losovano = array_unique(array_merge($Losovano, $VylosovanaCisla));
}
Václav M.
Junior
Uživatelský avatar


Kdo je online

Uživatelé procházející toto fórum: Žádní registrovaní uživatelé a 0 návštevníků