IT rekvalifikace s garancí práce. Seniorní programátoři vydělávají až 160 000 Kč/měsíc a rekvalifikace je prvním krokem. Zjisti, jak na to!
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.
Avatar
John Ronald Reuel Tolkien:19.10.2018 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.10.2018 17:40
Avatar

Člen
Avatar
:19.10.2018 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.10.2018 18:47
Akceptované řešení
+20 Zkušeností
+2,50 Kč
Řešení problému
 
Nahoru Odpovědět
19.10.2018 18:45
Avatar
John Ronald Reuel Tolkien:19.10.2018 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.10.2018 18:54
Avatar
Odpovídá na John Ronald Reuel Tolkien
Matúš Olejník:19.10.2018 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.10.2018 19:33
Nahoru Odpovědět
19.10.2018 19:32
/* I am not sure why this works but it fixes the problem */
Avatar

Člen
Avatar
Odpovídá na John Ronald Reuel Tolkien
:19.10.2018 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.10.2018 20:12
 
Nahoru Odpovědět
19.10.2018 20:11
Avatar
Odpovídá na Matúš Olejník
John Ronald Reuel Tolkien:19.10.2018 20:39

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

 
Nahoru Odpovědět
19.10.2018 20:39
Avatar
Odpovídá na
Matúš Olejník:19.10.2018 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
19.10.2018 20:42
/* I am not sure why this works but it fixes the problem */
Avatar

Člen
Avatar
Odpovídá na Matúš Olejník
:19.10.2018 22:49

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

 
Nahoru Odpovědět
19.10.2018 22:49
Avatar

Člen
Avatar
Odpovídá na John Ronald Reuel Tolkien
:20.10.2018 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
20.10.2018 0:59
Avatar
Odpovídá na
John Ronald Reuel Tolkien:20.10.2018 16:15

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

 
Nahoru Odpovědět
20.10.2018 16:15
Avatar

Člen
Avatar
Odpovídá na John Ronald Reuel Tolkien
:20.10.2018 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.10.2018 19:53
 
Nahoru Odpovědět
20.10.2018 19:51
Avatar
Odpovídá na
Matúš Olejník:20.10.2018 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.10.2018 20:01
Nahoru Odpovědět
20.10.2018 20:00
/* I am not sure why this works but it fixes the problem */
Avatar

Člen
Avatar
Odpovídá na Matúš Olejník
:20.10.2018 20:04

Ok, idem sa na to pozrieť.

 
Nahoru Odpovědět
20.10.2018 20:04
Avatar

Člen
Avatar
Odpovídá na Matúš Olejník
:20.10.2018 20:07

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

 
Nahoru Odpovědět
20.10.2018 20:07
Avatar
Peter Mlich
Člen
Avatar
Peter Mlich:22.10.2018 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.10.2018 8:32
 
Nahoru Odpovědět
22.10.2018 8:31
Avatar

Člen
Avatar
Odpovídá na Peter Mlich
:22.10.2018 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.10.2018 10:07
Avatar
Peter Mlich
Člen
Avatar
Peter Mlich:22.10.2018 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.10.2018 16:01
Avatar

Člen
Avatar
Odpovídá na Peter Mlich
:22.10.2018 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.10.2018 16:43
Avatar
Peter Mlich
Člen
Avatar
Peter Mlich:23.10.2018 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.10.2018 7:47
Avatar

Člen
Avatar
Odpovídá na Peter Mlich
:23.10.2018 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.10.2018 11:14
Avatar
Peter Mlich
Člen
Avatar
Peter Mlich:23.10.2018 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.10.2018 11:18
 
Nahoru Odpovědět
23.10.2018 11:17
Avatar
Peter Mlich
Člen
Avatar
Peter Mlich:23.10.2018 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.10.2018 12:55
Avatar
Peter Mlich
Člen
Avatar
Peter Mlich:23.10.2018 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.10.2018 13:06
Avatar
Peter Mlich
Člen
Avatar
Peter Mlich:23.10.2018 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.10.2018 13:55
Avatar
Odpovídá na Peter Mlich
Neaktivní uživatel:24.10.2018 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.10.2018 12:27
Neaktivní uživatelský účet
Avatar
Peter Mlich
Člen
Avatar
Odpovídá na Neaktivní uživatel
Peter Mlich:24.10.2018 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.10.2018 12:55
Avatar
Peter Mlich
Člen
Avatar
Peter Mlich:24.10.2018 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.10.2018 13:05
 
Nahoru Odpovědět
24.10.2018 13:05
Avatar
Peter Mlich
Člen
Avatar
Peter Mlich:24.10.2018 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.10.2018 13:31
 
Nahoru Odpovědět
24.10.2018 13:30
Avatar
Peter Mlich
Člen
Avatar
Peter Mlich:24.10.2018 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.10.2018 13:48
Avatar
Peter Mlich
Člen
Avatar
Peter Mlich:24.10.2018 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.10.2018 13:58
 
Nahoru Odpovědět
24.10.2018 13:56
Avatar

Člen
Avatar
Odpovídá na Peter Mlich
:24.10.2018 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.10.2018 17:47
Avatar

Člen
Avatar
Odpovídá na Peter Mlich
:24.10.2018 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.10.2018 20:15
Avatar
Peter Mlich
Člen
Avatar
Peter Mlich:25.10.2018 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.10.2018 10:27
 
Nahoru Odpovědět
25.10.2018 10:27
Avatar

Člen
Avatar
Odpovídá na Peter Mlich
:25.10.2018 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.10.2018 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.