Vánoční nadílka Vánoční nadílka
Vánoční akce! Daruj lepší budoucnost blízkým nebo sobě. Až +50 % zdarma na dárkové poukazy. Více informací

Diskuze: Náhodné číslo

JavaScript JavaScript Náhodné číslo American English version English version

Aktivity (1)
Avatar
John Ronald Reuel Tolkien:19. října 17:40

Zdravím, chci udělat jednoduchý program, který vygeneruje náhodná čísla do pole, s tím že se nebude žádné opakovat. Mám tento kód, ale pořád mi to nějak nefunguje :

  • window.onload=fun­ction()

    {

    var text=document­.getElementBy­Id("cisla");

    var cisla = [0]

    for (var i=0;i<6;i++)

    {
    var nahodne = Math.floor(Mat­h.random() * 7);

    for (var j=0;j<cisla.len­gth;j++)

    {

    while (cisla[j]==nahodne)

    {

    nahodne = Math.floor(Mat­h.random() * 7);

    }

    }

    cisla.push(na­hodne);

    text.innerHTML+=na­hodne.toStrin­g() + " ";

    }
    }*

Co s tím ?
Díky

Zkusil jsem:

Chci docílit:

 
Odpovědět 19. října 17:40
Avatar
gold604
Člen
Avatar
gold604:19. října 18:45

Ahoj, takto by som to urobil ja: https://codepen.io/…4/pen/QZrPXg.

 function uniqueRandomIn(array, multiplier) {
  var random = Math.floor(Math.random() * multiplier);
  return (array.indexOf(random) == -1) ? random : uniqueRandomIn(array, multiplier);
 }

window.onload = function() {
  var randomNumsCount = 10;
  var randomNums = [];

  for(i = 0; i < randomNumsCount; i++)
    randomNums.push( uniqueRandomIn(randomNums, randomNumsCount) );

  document.querySelector('#random-numbers').innerText = randomNums.join(', ');
}
Editováno 19. října 18:47
Akceptované řešení
+20 Zkušeností
+1 bodů
Řešení problému
 
Nahoru Odpovědět 19. října 18:45
Avatar
John Ronald Reuel Tolkien:19. října 18:54

Jestli to chápu správně tak : jestliže se prvek ještě nenachází v poli, vrátí indexOf -1, a tudíž se ve funkci vrátí proměnná random, a jestli ne, funkce se spustí znovu ?
Tohle je velmi chytré řešení :D Díky.
Dokázal bys to udělat i na principu, o který se pokouším já ? :D

 
Nahoru Odpovědět 19. října 18:54
Avatar
Odpovídá na John Ronald Reuel Tolkien
Matúš Olejník:19. října 19:32

A čo takto? Ako keby si do tabuľky naskladáš čísla z ktorých chceš vyskladať unikátne náhodné čísla. Potom vygeneruješ náhodné číslo maximálnej veľkosti tej tabuľky a to použiješ ako index pre vybratie čísla do tvojho výsledku a nakoniec toto číslo zoberieš a vymeníš ho z posledným z tabuľky a tabuľku o jeden zmenšíš. Snáď som niečo nedomrvil a všetky majú rovnakú šancu :D

<script>
    //valueFrom inclusive, valueTo exclusive
    function createDataArray(valueFrom, valueTo){
        let result = [];

        let tmp = valueFrom;
        for(let i = 0; i < valueTo - valueFrom; i++){
            result.push(tmp++);
        }
        return result;
    }

    //count <= to - from
    function generateUniqueNumbers(from, to, count){
        let data = createDataArray(from, to);
        let result = [];

        for(let i = 0; i < count; i++){
            let random = Math.floor(Math.random() * (data.length - 1 - i));

            result.push(data[random]);

            //let tmp = data[random];
            data[random] = data[data.length - 1 - i];
            //data[data.length - 1 - i] = tmp;
        }
        return result;
    }
    window.onload=function() {
        document.getElementById("i").innerHTML += (generateUniqueNumbers(0, 7, 7).toString() + " ");
    }
</script>
Editováno 19. října 19:33
Nahoru Odpovědět  +3 19. října 19:32
/* I am not sure why this works but it fixes the problem */
Avatar
gold604
Člen
Avatar
Odpovídá na John Ronald Reuel Tolkien
gold604:19. října 20:11

Presne tak :). Toto funguje na podobnom princípe, ako si sa o to pokúšal ty: https://codepen.io/…4/pen/JmvgRL

window.onload = function() {
  var randomNums = [];
  var randomNumsCount, multiplier;
  randomNumsCount = multiplier = 10;

  for(i = 0; i < randomNumsCount; i++) {
        var random = Math.floor(Math.random() * multiplier);

    while(randomNums.indexOf(random) != -1)
          random = Math.floor(Math.random() * multiplier);

    randomNums.push(random);
  }

  document.querySelector('#random-numbers').innerText = randomNums.join(', ');
}
Editováno 19. října 20:12
 
Nahoru Odpovědět  +1 19. října 20:11
Avatar
Odpovídá na Matúš Olejník
John Ronald Reuel Tolkien:19. října 20:39

I to je dosti geniální řešení :D
Díky

 
Nahoru Odpovědět 19. října 20:39
Avatar
Odpovídá na gold604
Matúš Olejník:19. října 20:42

Takže keď bude chcieť 1000 unikátnych čísiel od 0 po 1000, začne sa generovať, vygeneruje sa ich napr 999 a potom sa bude dovtedy generovať náhodne číslo kým nebude v tých 999 ostatných? To platí popri celom behu, že len háda čísla ktoré ešte nevygeneroval.

Nahoru Odpovědět  +1 19. října 20:42
/* I am not sure why this works but it fixes the problem */
Avatar
gold604
Člen
Avatar
Odpovídá na Matúš Olejník
gold604:19. října 22:49

Áno, je to tak. Tvoje riešenie je oveľa rýchlejšie.

 
Nahoru Odpovědět 19. října 22:49
Avatar
Odpovídá na John Ronald Reuel Tolkien
Vladislav Ladicky:20. října 0:59

Všetci si dajte z JS päťku a zamyslite sa nad týmto jednoriadkovým riešením ;)

let arr = Array(5).fill().map((x, y) => y).sort(() => Math.random() - 0.5)
 
Nahoru Odpovědět  +4 20. října 0:59
Avatar
Odpovídá na Vladislav Ladicky
John Ronald Reuel Tolkien:20. října 16:15

Zajímavé. Mohl by jste trošku vysvětlit kód ? :-)

 
Nahoru Odpovědět 20. října 16:15
Avatar
Odpovídá na John Ronald Reuel Tolkien
Vladislav Ladicky:20. října 19:51

Oki, vysvetlenie... Tvoj (a nielen tvoj) prístup k problému, algoritmu, nie je správny. Uvedom si totiž, čo sa v tvojom, aj vo všetkých ostatných riešeniach tu uvedených deje. S každym novým náhodným číslom klesá pravdepodobnosť, že vo while v ďalšej iterácii trafíš ďalšie nepoužité číslo. Ak by si to nerobil pre 6 čísel, ale pre tisíc, je ľahko možné, že by došlo k miliónom zbytočných iterácií a badateľne pozdržanému interaktivity štartu stránky...

Ak sa však pozrieš na problém z iného uhla, tak vlastne chceš dosiahnuť náhodne zoradené pole čísiel od 0 po 5. A vygenerovať pole 0 až 5 a potom ho náhodne zamiešať bude ďaleko efektívnejšie: koľko máš čísiel, toľko krát sa zamiešajú. Pre tisíc čísiel, tisíc zamiešaní. Ani jedna zbytočná iterácia...

No a to aj ide ľahko dosiahnuť moderným JS syntaxom. Bez jediného cyklu...

Funguje to takto: Array(5) konštruktor vytvorí pole piatich elementov, ale všetky undefined. Array metóda fill() zasa plní pole hodnotami. Použil som síce prázdnu metódu, bez hodnoty ktorou sa má pole naplniť, ale len vďaka nej funguje ďalšia metóda: map(). Táto metóda je určená na to, aby si niečo urobil s každou položkou v poli. Berie dva parametre a použil som x a y. V x sa nachádza hodnota a v y sa nachádza index na ktorom tá hodnota leží. No a čo som urobil je jednoduché. Hodnotu každej položky v poli som pomocou map prepísal na hodnotu indexu na ktorom leží. Taký malý trik: Array(5).fill()­.map((x, y) => y) ti vytvorí pole piatich položiek od 0 po 4, čiže [0, 1, 2, 3, 4]. No a nad týmto poľom následne zbehne ďalšia Array metóda na zoradenie položiek poľa: sort(). Akurát, že aj tam je použitý trik: sort s callbackom () => Math.random() - 0.5 ti to pole zotriedi náhodne...

Celý tvoj kód sa tak dá s novým syntaxom zjednodušiť napríklad takto:

window.onload = function () {
  document.querySelector('#cisla').innerHTML = Array(5)
    .fill()
    .map((x, y) => y)
    .sort(() => Math.random() - 0.5)
    .join(' ')
}

Čo je nie len kratšie a prehľadnejšie to vyjadruje tvoj zámer, čiže je to deklaratívnejší kód, ale hlavne ďaleko ďaleko efektívnejší, bezpečnejší. Nehrozí tam to riziko, že na niekoľko sekúnd zamrzne frontend, kvôli miliónom možných zbytočných iterácií pri triafaní sa do neobsadeného čísla.

Editováno 20. října 19:53
 
Nahoru Odpovědět  +1 20. října 19:51
Avatar
Odpovídá na Vladislav Ladicky
Matúš Olejník:20. října 20:00

aj vo všetkých ostatných riešeniach tu uvedených deje

Veď v tom čo som napísal ja tiež naplním pole dajme tomu od 0 po 5 a potom len generujem náhodne indexy zo zmenšujúceho intervalu s tým že už vybrané číslo zahodím a nahradím tým posledným (lebo zmenšujem rozsah generovania) - akoby ho náhodne zotriedim. A v druhom komentári tiež spomínam že tým ich riešením len hádajú číslo kým nepadne také čo už nebolo vybrané. Nerobím s JS preto som použil základnú syntax.

Editováno 20. října 20:01
Nahoru Odpovědět 20. října 20:00
/* I am not sure why this works but it fixes the problem */
Avatar
Odpovídá na Matúš Olejník
Vladislav Ladicky:20. října 20:04

Ok, idem sa na to pozrieť.

 
Nahoru Odpovědět 20. října 20:04
Avatar
Odpovídá na Matúš Olejník
Vladislav Ladicky:20. října 20:07

Áno, ospravedlňujem sa, tvoj kód je efektívnejší, žiadne triafanie voľného čísla vo while.

 
Nahoru Odpovědět  +1 20. října 20:07
Avatar
Peter Mlich
Člen
Avatar
Peter Mlich:22. října 8:31

Math.random() - 0.5
Lepsi je tam pouzit jiny pomer nez 50:50. Tusim jsem pouzival 0.66 (nebo 0.33, uz nevim). Jde o to, ze kdyz a-b>1 , tak je sortovac nuceny cisla a,b navrajem prehodit (swapovat). U 50:50 ve spouste pripadu dojde k tomu, ze zachova puvodni poradi. Coz je presne to, co u michani nechces :)
Jinak, sortovani je urcite efektivni michani cisel. Je na to vyrobeny optimalizovany algoritmus.

Editováno 22. října 8:32
 
Nahoru Odpovědět 22. října 8:31
Avatar
Odpovídá na Peter Mlich
Vladislav Ladicky:22. října 10:07

Omyl. Akýkoľvek iný pomer ako 1:1 nebude fungovať správne. Odklonom len pôsobíš, že bude väčšia šanca, že sa zoradia vzostupne, alebo zostupne, podľa toho na ktorej strane šancu zväčšíš.

 
Nahoru Odpovědět 22. října 10:07
Avatar
Peter Mlich
Člen
Avatar
Peter Mlich:22. října 16:01

To mas vyzkousene nebo jen tak hadas od boku, protoze ti to matematicky pasuje? :)
Ja to mam vyzkousene. Navrhoval jsem ve volnem case ty nejoptimalnejsi algoritmy a ony skutecne, kdyz nemusi michat, nemichaji. Proto je vyhodnejsi pridat vic do prehazovani. Tam je podminka a<b, a=b, a>b. Prehazuje jen, kdyz je a>b. Teda, zalezi na tom, jak ktery.

 
Nahoru Odpovědět 22. října 16:01
Avatar
Odpovídá na Peter Mlich
Vladislav Ladicky:22. října 16:43

Ty v konečnom dôsledku tvrdíš, že Math.random() dáva častejšie číslo menšie číslo ako 0.5? Resp. väčšie ako 0.5 dáva častejšie? A tomu aj veríš? Lebo ja som naopak presvedčený, že nie ja, ale práve ty dávaš názory typu "ak nemusí miešať tak nemieša" od boku.

 
Nahoru Odpovědět 22. října 16:43
Avatar
Peter Mlich
Člen
Avatar
Peter Mlich:23. října 7:47

Nnn.
Math random funguje asi s presnosti 95%.
Ja tvrdim, ze kdyz chces cisla zamichat a pouzijes k tomu serazovaci algoritmus, tak ten cisla zamenuje pouze v pripade, kdy a>b, cili tvych 51%. Takze cele pole mas ze 49% nezamichane. Coz je spatne. Serazovaci algoritmus pracuje proti tobe. Vetsina malych cisel zustane nahore a vetsina velkych dole.
Zkus si z toho pole spocitat cisla pod 50% v prvni a posledni ctvrtine (nebo polovine). Zopakuj to treba 100x. Mel bys zjistit, ze nedostavas 50:50 ale treba 70:30 nebo 60:40.
Cili, kdyz chces pouzit serazovaci algoritmus (SA), tak ho musis donutit vic pracovat. Ale ne na 100%, protoze pak to budes mit serazene opacne, to je jasne :)
Dobry SA proste funguje jinak nez bubble sort, ktery porovnava kazde z kazdym. Dobry SA neporovnava kazde z kazdym. Nektera cisla kontroluje treba jen 10x z 1000 cisel v poli. Kdezto s jinymi se setkava 100x a vic.

 
Nahoru Odpovědět 23. října 7:47
Avatar
Odpovídá na Peter Mlich
Vladislav Ladicky:23. října 11:14

Tak postupne: kde si zobral, že random metóda funguje len na 95%? To počujem prvý krát.

 
Nahoru Odpovědět 23. října 11:14
Avatar
Peter Mlich
Člen
Avatar
Peter Mlich:23. října 11:17

Odhad. Mozna je to 98 :)
Pri pokusu se sazenkovym tiketem stastnych 10 mi vychazeli dost podobna cisla jako pri matematickem vypoctu. Ale jsem zvykly na 100% nahodu pro random prilis nespolehat, radeji.


Sis, tak ti po obede udelam program pro to sortovani, kdyz mi neveris.

Editováno 23. října 11:18
 
Nahoru Odpovědět 23. října 11:17
Avatar
Peter Mlich
Člen
Avatar
Peter Mlich:23. října 12:55

Podle vysledku IE a edge pouzivaji nejspis pomalejsi alg quicksort, ktery v nejhorsi kombinaci funguje stejne jako bubble sort. FF pouziva neco jineho, mene porovnani, mene premistovani. Konkretne vim, co pouzivaji, ale nechci jmenovat.

// 23962, 25118, 24518, 24572 // pro polovinu, alg1[leva, prava], alg2[leva, prava], firefox
// 11734,12963,12015,12125 // pro ctvrtinu, alg1[leva, prava], alg2[leva, prava], firefox
// 12027,12058,12057,12074 edge
// 24576,24513,24576,24523 edge
// 24563,24531,24549,24548 ie8
// 12028,12079,12059,12076 ie8
<script>
function isExist(item)
        {
        return typeof(item)!=='undefined' && item!=null;
        }

function arrayClone1(arr, start, end)
{
var i, j, out;
var start = isExist(start) ? start : 0;
var end   = isExist(end)   ? end   : arr.length;
out = [];
i = start;
j = 0;
while (i<end)
        {
        out[j] = arr[i];
        i++;
        j++;
        }
return out;
}

function cmpRnd1(a, b)
{
return Math.random() - 0.5;
}

function cmpRnd2(a, b)
{
return Math.random() - 0.51;
}

function sortTest(arr, start, end, max)
{
var suma, middle;
middle = max>>1;
suma = 0;
for (i=start; i<end; i++)
        {
        suma += arr[i]<middle ? 1 : 0;
        }
//alert([start, end])
return Math.floor((suma/max)*100);
}

function sortTesting()
{
var arr, i, i_end, j, j_end, vysl, a, b, interval, c, d, e, f;
a = [];
arr = [];
i_end = 1000;
for (i=0; i<i_end; i++)
        {
        arr[i] = i;
        }
c = 0;
d = i_end>>2;
e = (i_end>>1) + (i_end>>2);
f = i_end;
//c = 0;
//d = i_end>>1;
//e = i_end>>1;
//f = i_end;
vysl  = [0, 0, 0, 0];
j_end = 1000;
for (j=0; j<j_end; j++)
        {
        a = arrayClone1(arr);
        a.sort(cmpRnd1);
        vysl[0] += sortTest(a, c, d, i_end);
        vysl[1] += sortTest(a, e, f, i_end);
        a = arrayClone1(arr);
        a.sort(cmpRnd2);
        vysl[2] += sortTest(a, c, d, i_end);
        vysl[3] += sortTest(a, e, f, i_end);
        }
alert(vysl);
}

sortTesting();

</script>
 
Nahoru Odpovědět 23. října 12:55
Avatar
Peter Mlich
Člen
Avatar
Peter Mlich:23. října 13:06

prepocitano na procenta

48.8,   51.1,   49.9,   50
47.5,   52.4,   48.6,   49
49.9,   50,   50,   50.1
50,   49.9,   50,   49.9
50,   49.9,   50,   50
49.8,   50.1,   50,   50

var n;
arr = [
[ 23962, 25118, 24518, 24572 ],
[ 11734,12963,12015,12125 ],
[ 12027,12058,12057,12074 ],
[ 24576,24513,24576,24523 ],
[ 24563,24531,24549,24548 ],
[ 12028,12079,12059,12076 ]
];
for (i=0;i<arr.length;i++)
        {
        n = arr[i][0] + arr[i][1];
        arr[i][0] = Math.floor(arr[i][0]*1000/n)/10;
        arr[i][1] = Math.floor(arr[i][1]*1000/n)/10;
        arr[i][2] = Math.floor(arr[i][2]*1000/n)/10;
        arr[i][3] = Math.floor(arr[i][3]*1000/n)/10;
        arr[i] = arr[i].join(', &nbsp; ');
        }
document.write('<br>');
document.write(arr.join('<br>'));
 
Nahoru Odpovědět 23. října 13:06
Avatar
Peter Mlich
Člen
Avatar
Peter Mlich:23. října 13:55

Jeste mala zmena. Udelal jsme samozrejme jiny test, nez jsem popsal. Ale take je zajimavy. Tento bude mozna jeste vic zajimavejsi.
Pocitam cisla, ktera zustala nahore a pocitam cisla, ktera zustala dole.

2463,   1957,   2478,   2316,   4267,   6371 // ff
4862,   4862,   4960,   4960,   6527,   6527 // tohle mne docela zarazi, zavani to chybou :)
<script>
function isExist(item)
        {
        return typeof(item)!=='undefined' && item!=null;
        }

function arrayClone1(arr, start, end)
{
var i, j, out;
var start = isExist(start) ? start : 0;
var end   = isExist(end)   ? end   : arr.length;
out = [];
i = start;
j = 0;
while (i<end)
        {
        out[j] = arr[i];
        i++;
        j++;
        }
return out;
}

function cmpRnd1(a, b)
{
return Math.random() - 0.5;
}

function cmpRnd2(a, b)
{
return Math.random() - 0.51;
}

function cmpRnd3(a, b)
{
return Math.random() - 0.66;
}

function sortTest(arr, start, end, n_min, n_max)
{
var suma;
suma = 0;
for (i=start; i<end; i++)
        {
        suma += arr[i]>=n_min && arr[i]<n_max ? 1 : 0;
        }
//alert([start, end])
//return suma
//alert(arr)
//alert([suma, n_min, n_max, start, end]);
return Math.floor(100*suma/(end-start));
}

function sortTesting()
{
var arr, i, i_end, j, j_end, vysl, a, b, interval, c, d, e, f;
a = [];
arr = [];
i_end = 1000;
for (i=0; i<i_end; i++)
        {
        arr[i] = i;
        }
c = 0;
d = i_end>>2;
e = (i_end>>1) + (i_end>>2);
f = i_end;
/*
c = 0;
d = i_end>>1;
e = i_end>>1;
f = i_end;
*/
vysl  = [0, 0, 0, 0, 0, 0];
j_end = 100;
for (j=0; j<j_end; j++)
        {
        a = arrayClone1(arr);
        a.sort(cmpRnd1);
        vysl[0] += sortTest(a, c, d, c, d);
        vysl[1] += sortTest(a, e, f, e, f);
        a = arrayClone1(arr);
        a.sort(cmpRnd2);
        vysl[2] += sortTest(a, c, d, c, d);
        vysl[3] += sortTest(a, e, f, e, f);
        a = arrayClone1(arr);
        a.sort(cmpRnd3);
        vysl[4] += sortTest(a, c, d, c, d);
        vysl[5] += sortTest(a, e, f, e, f);
        }
document.write(vysl.join(', &nbsp; '));
}

sortTesting();

</script>
 
Nahoru Odpovědět 23. října 13:55
Avatar
Taskkill
Redaktor
Avatar
Odpovídá na Peter Mlich
Taskkill:24. října 12:27

Škoda že nejsou interpretace testů, pro zajímavost. Nemusel bych je pouštět na to, abych věděl co ilustrují. Nedopsal bys?

 
Nahoru Odpovědět 24. října 12:27
Avatar
Peter Mlich
Člen
Avatar
Odpovídá na Taskkill
Peter Mlich:24. října 12:55

Psal jsem to v rychlosti, tak to asi bude plne chyb :) Zkusim je jeste najit. A asi to dam spis link na stranku. tejne je to offtopic.

Včera 13:55 (neni tu id prispevku)

  • By mel projit prvky horni ctrvinu pole (0..250) a porovnat je s rozpetim 0-250. Cili to zjisti cisla, ktera tam zustavaji. (vysl[0], vysl[1])
  • Totez pro posledni 1/4, 750-1000. (vysl[2], vysl[3])
  • Zakomentovana je cast, ktera zmeni interval na 0-50% a 50%-100%

Včera 12:55

  • to melo delat puvodne totez, ale porovnava to s max/2, cili vzdy cislo<500

Včera 13:06

  • je jen prepocet cisel zakomentovanych nahore (Včera 12:55) na procenta
 
Nahoru Odpovědět 24. října 12:55
Avatar
Peter Mlich
Člen
Avatar
Peter Mlich:24. října 13:05

Ups, spatny popis. tam jsou 3 algoritmy v tom poslednim programu, vysl 0 a 1 je prvni, 2,3 druhy, 4,5 treti.
vysl 0 je pro 1/4, vysl1 je pro 3/4
Jinymi slovy, chci zjistit procentualni obsazeni cisel v poli s 1/4 a ve 3/4.

Editováno 24. října 13:05
 
Nahoru Odpovědět 24. října 13:05
Avatar
Peter Mlich
Člen
Avatar
Peter Mlich:24. října 13:30

https://mlich.zam.slu.cz/…sort-rnd.htm
Rozsiril jsem to o dalsi testy, abych si overil funkcnost. Ta posledni cisla...

25000, 25000 - serazene pole ASC, 1000 prvku, 1/4 je 250, 100x opakovani dava 25000
Cili, pro serazene pole je v 1/4 100% stejnych prvku jako bylo pred algoritmem (zadny se nepouzil)

0, 0 - serazene pole opacne DESC , 1000 prvku, 1/4 je 0, 100x opakovani dava 0
Cili, pro opacne serazene pole je v 1/4 0% stejnych prvku jako bylo pred algoritmem

12500, 12500 - je idealni stav, kdy pri rozdeleni na 4 intervaly a zamichani, zustane v intervalu 1/4 puvodnich prvku.
Takhle mela vychazet vsechna predchozi cisla a ani jeden algoritmus to nesplnil. Blizi se tomu
Math.random() - 0.66 s vysledky 10931, 16135

Zaver, pro mne zni, ze michani pomoci takoveho random sortu je nepouzitelne, nedocili se rovnomerneho rozlozeni.
Muzete zmacnout F5 kolikrat chcete, nikdy se nepriblizite k 12500 ku 12500. Ok, to bych ani neocekaval. Ale pri opakovani F5 by mela cisla vyrazne skakat, prvni vetsi, druhe mensi a naopak. To nenastava.

Editováno 24. října 13:31
 
Nahoru Odpovědět 24. října 13:30
Avatar
Peter Mlich
Člen
Avatar
Peter Mlich:24. října 13:48

Mozna lepsi by bylo vysvetleni graficky, o co mi slo :)

0 1 2 3 4 5 6 7 8, 9, 10, 11, 12, 13, 14, 15 - serazene pole
0, 1, 2, 3 - prvni ctvrtina, cislo>=0 && cislo <=1, podmince vyhovuji 4 cisla (vsechna)
12, 13, 14, 15 - posledni ctvrtina, cislo>=0 && cislo <=1, podmince vyhovuji 4 cisla (vsechna)

Pokud pole zamicha, da se ocekavat, ze v obou castech zustane 1/4 cisel (idealni stav). Jenze...
Math.random() - 0.5 vyplivne tohle:
2,0,5,1,3,7,4­,6,10,8,11,9,12,14,13,15
2,0,5,1 - puvodni cisla jsou tam 3
12,14,13,15 - puvodni cisla jsou tam dokonce 4

Totez pri opakovani
1,0,2,4,3,6,5­,7,9,8,11,10,14,12,15,13
4,1,0,3,2,5,7­,9,15,8,6,11,10,13,14,12
0,2,3,6,1,4,5­,7,9,8,10,12,14,11,15,13
0,1,2,4,3,7,5­,8,6,9,14,10,11,13,15,12
1,0,3,5,6,4,1­2,7,2,10,8,9,11,13,14,15
1,3,4,0,7,6,5­,10,8,2,9,11,12,13,15,14
....

Jako, kdysi jsem to take parkrat pouzil nez mne nekdo upozornil, ze to ne uplne dobre micha. Takze jsem premyslel nad tim, proc. A pro zajimavost pridam vysledky toho meho rozsireni, ktere se take ukazalo nepouzitelne.

Math.random() - 0.66 - tam je to podobne
1,0,2,3,10,4,­5,6,7,8,9,11,12,14,15,13
2,0,1,6,3,5,4­,7,11,9,8,14,10,12,13,15
1,0,2,3,5,4,6­,7,9,8,11,12,10,15,13,14

Math.random() - 0.33;
6,5,9,4,1,3,1­0,0,2,7,11,12,14,13,15,8
1,7,0,3,4,6,8­,2,5,9,10,12,11,14,13,15
0,3,8,1,7,10,­2,12,9,5,6,13,4,14,11,15
4,0,2,1,3,11,­5,10,8,9,6,13,12,7,15,14
Zase je videt, ze tam zustavaji v podtate puvodni cisla. Treba, kde je 1? Vzdy v prvni polovine. Kde je 15? Temer vzdy na konci.

 
Nahoru Odpovědět 24. října 13:48
Avatar
Peter Mlich
Člen
Avatar
Peter Mlich:24. října 13:56

Jo, zajimave vysledky to dava v Edge. Tam tech 0.5 skutecne micha. Ale to je dano tim, ze edge pouziva quicksort nebo neco takoveho robustniho, co ma vysoky pocet porovnavacich operaci a<>=b. QS postupuje od prostredka, kdezto te FF binarne, porovnava 1 a 1 prvek, pak 2 a 2... Takze, pokud to jde, zachova puvodni prvek tam, kde byl a dal uz ho nepresouva.

Editováno 24. října 13:58
 
Nahoru Odpovědět 24. října 13:56
Avatar
Odpovídá na Peter Mlich
Vladislav Ladicky:24. října 17:47

Skúmaš kktiny Peter :) Pozri ... on nerieši kryptografický problém. Ale drobnosť v zmysle "náhodné poradie skladieb". Tam mu môj kód s pseudonáhodným generátorom naaaaaprosto postačuje. Veď si zober, že toto je plne funkčný, moderný a prehľadný kód stránky:

<!DOCTYPE html>

<p id="cisla"></p>

<script>
  const shuffledList = len => Array(len)
    .fill()
    .map((x, y) => y)
    .sort(() => Math.random() - 0.5)
    .join(' ')

  const writeTo = (sel, text) => {
    document.querySelector(sel).innerHTML = text
  }

  window.addEventListener('load', writeTo.call(null, '#cisla', shuffledList(6)))
</script>

Šiel by tento kód urobiť podľa teba lepšie? V čomkoľvek?

 
Nahoru Odpovědět 24. října 17:47
Avatar
Odpovídá na Peter Mlich
Vladislav Ladicky:24. října 20:15

PS: Tu máš kompletný príklad aj s naozaj náhodne vygenerovaným zoznamom. A tá moja metóda funguje len ako fallback, keby sa náhodou nepodarilo získať zoznam z random.org.

<!DOCTYPE html>

<p id="cisla"></p>

<script src="https://cdnjs.cloudflare.com/ajax/libs/superagent/3.8.3/superagent.min.js"></script>

<script>
  const writeShuffledList = parms => {
    superagent
      .get('https://www.random.org/sequences/')
      .query({min: 0})
      .query({max: parms.len - 1})
      .query({col: 1})
      .query({format: 'plain'})
      .query({rnd: 'new'})
      .then(({text}) => {
        // we have truly random list
        parms.list = text.replace('/n', ' ')
      })
      .catch(_ => {
        // random list unavailable, use fallback
        parms.list = Array(parms.len)
          .fill()
          .map((x, y) => y)
          .sort(() => Math.random() - 0.5)
          .join(' ')
      })
      .finally(() => {
        // and write list to selector
        document.querySelector(parms.sel).innerHTML = parms.list
      })
  }

  window.addEventListener('load', writeShuffledList.call(null, {len: 6, sel: '#cisla', list: ''}))
</script>
 
Nahoru Odpovědět 24. října 20:15
Avatar
Peter Mlich
Člen
Avatar
Peter Mlich:25. října 10:27

Zajimave, ze ti to promicha celkem dobre i ve firefox. Dal jsem tam omezeni 16 cisel. Nezkoumal jsem ale cely kod. Treba delas neco spesl nebo pro kombinaci s map pouzivaji jiny sort.
15 6 1 11 3 13 4 2 10 12 0 8 14 5 7 9
7 10 8 9 14 3 4 5 6 2 12 11 1 0 15 13
15 1 14 13 11 6 10 7 5 2 9 4 0 8 12 3

Ps. Taskkill se ptal na podrobnosti, co to vlastne je, k cemu to je.

Editováno 25. října 10:27
 
Nahoru Odpovědět 25. října 10:27
Avatar
Odpovídá na Peter Mlich
Vladislav Ladicky:25. října 11:23

Čísla získané z random.org sú premiešané hardvérovým generátorom náhodných čísiel, tuším na základe atmosférického šumu, preto to dáva lepšie výsledky. A moja funkcia je použitá len keď zlyhá vyžiadanie čísiel z random.org. A Taskkill sa asi pýtal teba, mňa sa nemá na čo pýtať.

 
Nahoru Odpovědět 25. října 11:23
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 34 zpráv z 34.