Avaleht
uus teema   vasta Tarkvara »  Programmeerimine »  JS random generator märgi kõik teemad loetuks
märgi mitteloetuks
vaata eelmist teemat :: vaata järgmist teemat
Hinnavaatlus :: Foorum :: Uudised :: Ärifoorumid :: HV F1 ennustusvõistlus :: Pangalink :: Telekavad :: HV toote otsing
autor
sõnum Saada viide sõbrale.  :: Teata moderaatorile teata moderaatorile
otsing:  
andrusny
Kreisi kasutaja
andrusny

liitunud: 20.03.2006




sõnum 24.10.2009 23:34:49 JS random generator vasta tsitaadiga

Ehitasin mingi suvanumbri generaatori JS peale. Kontrollib, et ei annaks korduvaid numbreid ega numbreid, väljaspool etteantud piire. Miskipärast, kui etteantud vahemik on suur niteks 2-12 toimib aga 2-13 ütleb, et Out of memory , mis selle kokku jooksutab? Ei saa pihta.
Kas lihtsalt toodab kogu aeg vale numbreid ja jääb ringi jooksma see rekursiivsus ja ennem, kui õige tuleb, saab mälu täis?

<div id="LOTO">
<input type="text" id="n1" size="40" maxlength="256">
<input type="text" id="n2" size="40" maxlength="256" >
<input type="text" id="bingo" size="40" maxlength="256">
<input type="button" value="BINGO" id="n3" onclick="kontr();randNR();">
<input type="button" value="RESTART" id="n4" onclick="uus();">
</div>

<script>
// Suva arvu generaator arvust arvuni
var arh = new Array();
var i=0;var plok=0;
var arh2 = new Array();

function uus(){
arh = arh2;
i=0;plok=0;
}

function randNR() {
   if(plok==1){
           document.getElementById('n2').value="";
            document.getElementById('n1').value="";
                return;
                             }
      nr1=document.getElementById('n1').value;
      nr2=document.getElementById('n2').value-0+1;
      
         if(arh.length == (nr2-nr1)){
                        plok=1;document.getElementById('n2').value="";
                            document.getElementById('n1').value="";
                                       return;
                                                  }
                                             
                  var rand_no = Math.floor(Math.random() *nr2);
                        kontrol = verif(arh, rand_no);
                              if(rand_no<nr1 || kontrol){
                                    randNR();
                                                                         }
                                       else {
                                              arh[i] = rand_no;
                                                  i++;
                                                   document.getElementById('bingo').value=rand_no;
                                                      }
                                    }

function verif(myArray,myValue) {
   var yesno = eval(myArray).join().indexOf(myValue)>=0;
      return yesno;
                                                }

function kontr() {
      nr21=document.getElementById('n1').value-0;
      nr22=document.getElementById('n2').value-0;
            if(nr21==nr22){plok==1;}
               if(nr21>nr22){
                     document.getElementById('n2').value=nr21;
                         document.getElementById('n1').value=nr22;
                                     }
                                 }

</script>

_________________


viimati muutis andrusny 25.10.2009 01:35:55, muudetud 3 korda
Kommentaarid: 7 loe/lisa Kasutajad arvavad:  :: 0 :: 0 :: 7
tagasi üles
vaata kasutaja infot saada privaatsõnum mine selle kasutaja kodulehele
troglodyte
Kreisi kasutaja
troglodyte

liitunud: 09.08.2002




sõnum 25.10.2009 00:27:40 vasta tsitaadiga

Tee oma kood loetavaks - trepi ära, iga statement eraldi reale jne, siis ehk viitsib ka sisusse süveneda.
_________________
ph'nglui mglw'nafh Cthulhu R'lyeh wgah'nagl fhtagn
Kommentaarid: 34 loe/lisa Kasutajad arvavad:  :: 0 :: 0 :: 34
tagasi üles
vaata kasutaja infot saada privaatsõnum mine selle kasutaja kodulehele
andrusny
Kreisi kasutaja
andrusny

liitunud: 20.03.2006




sõnum 25.10.2009 01:20:21 vasta tsitaadiga

Ta ongi trepitud.
Tegin natuke vahed sisse, ega siin midagi treppida pole, koodiaknas murrab lihtsalt pikad read ära.

editoris on kenasti näha.

Viskasin koodi ülesse, seal on natuke paremini näha, kuigi ühe pika rea murrab ära.
Rand generator

_________________
Kommentaarid: 7 loe/lisa Kasutajad arvavad:  :: 0 :: 0 :: 7
tagasi üles
vaata kasutaja infot saada privaatsõnum mine selle kasutaja kodulehele
nene
Kreisi kasutaja
nene

liitunud: 20.03.2004




sõnum 25.10.2009 01:20:34 vasta tsitaadiga

Oh jeerum jeerum jeerum! Sellist koodi pole ammu näinud. Kusjuures korraliku treppimise puudumine on veel vaat et see kõige väiksem viga. Paunvere väljanäitus lausa kahvatub selle kõrval kui palju erinevaid vigu on selles tõelises vigade väljanäituses.

Võtsin siinkohal vaevaks see üllitis ära treppida ja omapoolsed kommentaarid (tähistatud tärniga) juurde kirjutada. Viimastest võib ehk ka välja lugeda, miks too kood võib teinekord sattuda lõputusse tsüklisse.

javascript:
  1. // Suva arvu generaator arvust arvuni
  2. var arh = new Array();
  3. var i=0;
  4. var plok=0;
  5. var arh2 = new Array();
  6.  
  7. // nullija
  8. // * Või noh, vähemasti üritab nullida, sest
  9. // * nullib vaid arhiivi vaid esmakordsel käivitamisel
  10. function uus(){
  11.   arh = arh2; // * WTF!
  12.   i=0;
  13.   plok=0;
  14. }
  15.  
  16. // rnd generator
  17. function randNR() {
  18.   // * Kui blokeeritakse, siis lõpeta
  19.   if(plok==1){
  20.     document.getElementById('n2').value="";
  21.     document.getElementById('n1').value="";
  22.     return;
  23.   }
  24.  
  25.   // * Loe arvud sisse
  26.   nr1=document.getElementById('n1').value;
  27.   nr2=document.getElementById('n2').value-0+1; // WTF!
  28.  
  29.   // * kui juhuarvude arhiivi pikkus on võrdne sisestatud
  30.   // * arvude vahega + 1, siis blokeeri. WTF!WTF!WTF!
  31.   // *
  32.   // * See siis tähendab, et kui leitud on juba 2 juhuarvu
  33.   // * siis ei tohi sisestada enam arve, mis erinevad vaid ühe võrra.
  34.   // *
  35.   // * Seejärel peavad sisestatud arvud erinema juba kahe võrra.
  36.   // *
  37.   // * jne.
  38.   if(arh.length == (nr2-nr1)){
  39.     plok=1;
  40.     document.getElementById('n2').value="";
  41.     document.getElementById('n1').value="";
  42.     return;
  43.   }
  44.  
  45.   // * leia juhuslik arv 0..nr2
  46.   var rand_no = Math.floor(Math.random() *nr2);
  47.   // * kontrolli kas leitud arv on juhuarvude arhiivis juba olemas
  48.   kontrol = verif(arh, rand_no);
  49.   // * kui leitud arv on väiksem arvust nr1 või sisaldub arhiivis
  50.   // * siis pöördu rekursiivselt uuesti algusesse tagasi.
  51.   if(rand_no<nr1 || kontrol){
  52.     randNR();
  53.   } else {
  54.     // * muul juhul lisa leitud arv massiivi
  55.     // * ja väljasta vastuse lahtrisse
  56.     arh[i] = rand_no;
  57.     i++;
  58.     document.getElementById('bingo').value=rand_no;
  59.   }
  60. }
  61.  
  62. // vaatab kas number on massiivis juba olemas
  63. // * Kahjuks on see funktsioon aga vigane ning võib
  64. // * tagastada true ka siis kui arvu massiivis tegelikult pole
  65. function verif(myArray, myValue) {
  66.   var yesno = eval(myArray).join().indexOf(myValue)>=0; // * WTF!
  67.   return yesno;
  68. }
  69.  
  70. // kontrollib, et esimene arv oleks väiksem kui teine plokeerib,
  71. // kui mõlemad on võrdsed.
  72. // * Või noh... vähemasti üritab blokeerida
  73. function kontr() {
  74.   nr21=document.getElementById('n1').value-0;
  75.   nr22=document.getElementById('n2').value-0;
  76.   if(nr21==nr22){
  77.     plok==1; // * WTF!
  78.   }
  79.   if(nr21>nr22){
  80.     document.getElementById('n2').value=nr21;
  81.     document.getElementById('n1').value=nr22;
  82.   }
  83. }

_________________
Mõistus otsas? Pane pinusse...
Kommentaarid: 24 loe/lisa Kasutajad arvavad:  :: 0 :: 1 :: 23
tagasi üles
vaata kasutaja infot saada privaatsõnum mine selle kasutaja kodulehele
andrusny
Kreisi kasutaja
andrusny

liitunud: 20.03.2006




sõnum 25.10.2009 01:52:14 vasta tsitaadiga

Tänud vastamast. Miks sa arvad, et ta ei nulli teisel korral?

  arh = arh2; // * WTF!


arh2 on ju alguses defineeritud tühi array, miks see peaks täieks muutuma?

tsitaat:
arvude vahega + 1, siis blokeeri. WTF!WTF!WTF!
// *
// * See siis tähendab, et kui leitud on juba 2 juhuarvu
// * siis ei tohi sisestada enam arve, mis erinevad vaid ühe võrra.


eip näiteks on 2-4 leiab 2, 3, 4 pesasid kolm 4-2=2 aga vaja on kolme 4+1-2=3
ja nii edasi, see koht küll vigane pole.
Ega need 2 ja 4 ei muutu ju ühe genereerimise jooksul, need pannakse algul paika on input väljadel

Ainuke, mis sinu pakutud vigadest võiks olla on

  var yesno = eval(myArray).join().indexOf(myValue)>=0; // * WTF!


Selle sain internetist. Otsisin, kuidas kontrollida massiivis olevat avaldist.

_________________
Kommentaarid: 7 loe/lisa Kasutajad arvavad:  :: 0 :: 0 :: 7
tagasi üles
vaata kasutaja infot saada privaatsõnum mine selle kasutaja kodulehele
nene
Kreisi kasutaja
nene

liitunud: 20.03.2004




sõnum 25.10.2009 02:18:18 vasta tsitaadiga

Eriline pärl on mu meelest see verif funktsioon:

javascript:
  1. // vaatab kas number on massiivis juba olemas
  2. function verif(myArray, myValue) {
  3.   var yesno = eval(myArray).join().indexOf(myValue)>=0;
  4.   return yesno;
  5. }


1. Milleks panna talle nimeks verif, see ei ütle ju mitte kui midagi selle kohta, mida see funktsioon teeb. Hea nimi oleks näiteks contains (sisaldab), sest ta kontrollib kas massiiv sisaldab etteantud väärtust.

2. Miks lisada parameetrite ette my: myArray, myValue. Loomulikult on need sinu muutujad kui sa selle koodi kirjutasid - kelle omad siis veel? Palju parem oleks lihtsalt array, value.

3. Miks eval(myArray)? Oled sa üldse teadlik mida eval teeb? Antud kontekstis tagastab see lihtsalt sellesama myArray. Kui sa kasutad eval'i, siis pead olema 100% kindel, et sa tead, mida sa teed, sest eval on ohtlik - liiga lihtne on oma lehele selle kaudu turvaauke tekitada.

4. Milleks omistada tulemus muutujale yesno, parem oleks kirjutada kohe return eval(myAr...

5. Ja nüüd siis kõige magusam osa. Selleks, et kontrollida, kas arv sisaldub massiivis konverteerid sa massiivi kõigepealt stringiks ja siis kontrollid kas see string sisaldab alamstringina otsitavat arvu. See meetod töötab... seni kuni massiiv sisaldab vaid ühekohalisi arve. Kuid mitmekohaliste arvude puhul läheb asi kiiresti käest ära. Võtame sellise näite:

Kas arv 7 sisaldub massiivis [1, 2, 27, 8, 6]? Õige vastus on muidugi EI.

Kui sa aga konverdid massiivi join() abil stringiks ja küsid nüüd kas "7" sisaldub stringis "1,2,27,8,6", siis on vastus JAH.

6. Mida sa tegelikult vajad on vana hea lineaarse otsingu algoritm. Selle peaks suutma iga programmeerija iseseisvalt välja mõelda. Väike vihje: ei hakka massiive stringideks konvertima.

7. Pealegi on ka massiividel olemas indexOf meetod (pole küll IE poolt toetatud, aga selle toetuse saab ise vajadusel lisada). Seega võiksid selle funktsiooni kirjutada lihtsalt nii:

javascript:
  1. function contains(array, value) {
  2.   return array.indexOf(value) >= 0;
  3. }


EDIT: olin selle kõik juba valmis kirjutanud, kui sa oma vastuse postitasid ja teatasid, et leidsid selle koodi internetist:

8. Ära kunagi usalda pimesi suvalisi koodijuppe, mida sa internetist leiad. Internet on kamaluga täis vigadest kubisevaid koodinäiteid.

_________________
Mõistus otsas? Pane pinusse...
Kommentaarid: 24 loe/lisa Kasutajad arvavad:  :: 0 :: 1 :: 23
tagasi üles
vaata kasutaja infot saada privaatsõnum mine selle kasutaja kodulehele
andrusny
Kreisi kasutaja
andrusny

liitunud: 20.03.2006




sõnum 25.10.2009 02:36:59 vasta tsitaadiga

Jõudsin juba samale järeldusele, pusisin ise ühe tsükliga kontroll funktsiooni ja voila töötab, viga siin oligi.

// Masiivi kontroll       
   function kontrolliMa(Ma, Str){
        for(var ii=0;ii<Ma.length;ii++) {
            if(Ma[ii]==Str){return true;}
                                  }
                return false;
                     }


Sinu oma on muidugi tunduvalt lühem, kui ta nüüd sama asja teeb ja korralikult kontrollib.

Tänud abi eest!

hmm sinu funktsioon ei hakka tööle. Ütleb Objekt dosnˇt support this property or method
arh on massiv
kontrol = contains(arh, rand_no);
                                                      
      function contains(mas , value) {
                                 return mas.indexOf(value) >= 0;
                                                                          }


internetis kirjutab selle indexOf kohta
tsitaat:
Supported Since: Netscape 3.0, Internet Explorer: 3.0

ja interneti näidiskood ka annab sama veateate.

_________________


viimati muutis andrusny 25.10.2009 02:58:16, muudetud 2 korda
Kommentaarid: 7 loe/lisa Kasutajad arvavad:  :: 0 :: 0 :: 7
tagasi üles
vaata kasutaja infot saada privaatsõnum mine selle kasutaja kodulehele
nene
Kreisi kasutaja
nene

liitunud: 20.03.2004




sõnum 25.10.2009 03:23:58 vasta tsitaadiga

andrusny kirjutas:
Miks sa arvad, et ta ei nulli teisel korral?


Põhjus peitub selles, et JavaScripti omistamisoperaator (=) mitte ei kopeeri kogu massiivi ühest muutujast teise, vaid kopeerib üksnes viida tollele massiivile.

Võtame selle koodi uuesti ette, lühendatud kujul:

javascript:
  1. var arh = new Array();
  2. var arh2 = new Array();
  3.  
  4. function uus(){
  5.   arh = arh2;
  6. }


Alguses viitavad muutujad arh ja arh2 kumbki ühele tühjale massiivile. Seda võiks ette kujutada nõnda:

arh ----> []
arh2 ---> []


Seejärel lisatakse arh poolt viidatavasse massiivi ports elemente:

arh ----> [1,2,3,4,5]
arh2 ---> []


Siis käivitatakse uus(), mis paneb muutuja arh viitama sellele samale massiivile, millele viitab arh2. Tulemuseks on, et jääb järgi vaid üks massiiv, millele pääseb ligi mõlemi muutuja kaudu:

arh2 ---> [] <--- arh


Taas kord lisatakse arh poolt viidatavasse massiivi ports elemente. Juhtumisi viitab sellele samale massiivile ka arh2:

arh2 ---> [1,2,3,4,5] <--- arh


Taas käivitatakse uus(), mis paneb muutuja arh viitama sellele samale massiivile, millele viitab arh2, aga arh ju juba viitabki sellele samale massiivile, millele arh2, seega tulemuseks jääb endiselt:

arh2 ---> [1,2,3,4,5] <--- arh


Tegelikult peaksid sa seal uus() sees omistama muutujale arh hoopis uue tühja massiivi:

javascript:
  1. var arh = [];
  2.  
  3. function uus(){
  4.   arh = []; // [] on lühem variant ütlemaks new Array()
  5. }



andrusny kirjutas:
Ega need 2 ja 4 ei muutu ju ühe genereerimise jooksul, need pannakse algul paika on input väljadel


Ah nii. Kuid sellisel juhul ei tohiks sa lubada kasutajal neid numbreid vahepeal muuta.

andrusny kirjutas:
hmm sinu funktsioon ei hakka tööle. Ütleb Objekt dosnˇt support this property or method.


Nagu ma ütlesin: IE-ga see ei tööta. Kuid sa võid selle funktsiooni IE-le ise lisada, kui lisad oma koodi:

javascript:
  1. if (!Array.indexOf) {
  2.   Array.prototype.indexOf = function(obj) {
  3.     for (var i=0; i<this.length; i++) {
  4.       if (this[i] == obj) {
  5.         return i;
  6.       }
  7.     }
  8.     return -1;
  9.   }
  10. }


Aga see kõik ei lahenda keskset probleemi sinu koodis. Mida sa vajad on funktsioon, mis leiaks juhusliku arvu ettemääratud vahemikus. Sa paistad teadvat kuidas leida juhuslik arv vahemikus 0 kuni nr - 1:

Math.floor(Math.random() * nr)


Kuidas aga leida juhuslik arv suvalises vahemikus?

Mõista, mõista...

Mida sa teeksid kui sa tahaksid kuue-küljelise täringu abil leida juhuslikku arvu vahemikus 101 kuni 106?

Nelja-küljelise täringu abil vahemikus 6 kuni 9?

n-küljelise täringu abil vahemikus x kuni y?

_________________
Mõistus otsas? Pane pinusse...
Kommentaarid: 24 loe/lisa Kasutajad arvavad:  :: 0 :: 1 :: 23
tagasi üles
vaata kasutaja infot saada privaatsõnum mine selle kasutaja kodulehele
andrusny
Kreisi kasutaja
andrusny

liitunud: 20.03.2006




sõnum 25.10.2009 04:07:14 vasta tsitaadiga

tsitaat:

Mida sa teeksid kui sa tahaksid kuue-küljelise täringu abil leida juhuslikku arvu vahemikus 101 kuni 106?


Nii see töötabki ju
Kontrollib olemasolevaid numbreid ja teine tingimus kontrollib esimesest numbrist väiksemaid.

  if(rand_no<nr1 || kontrol){
                                    randNR();
                                                                         }
                                       else {
                                              arh[i] = rand_no;
                                                  i++;
                                                   document.getElementById('bingo').value=rand_no;
                                                      }

_________________
Kommentaarid: 7 loe/lisa Kasutajad arvavad:  :: 0 :: 0 :: 7
tagasi üles
vaata kasutaja infot saada privaatsõnum mine selle kasutaja kodulehele
mark11
HV vaatleja

liitunud: 28.01.2006




sõnum 25.10.2009 13:03:13 vasta tsitaadiga

sellele kontrollimisele läheb suur töö..
http://www.webdevelopersnotes.com/tutorials/javascript/generating_random_numbers_javascript.php3

samuti see pole koht rekursiooniks, while() ajab asja ilusasti/paremini ära
Kommentaarid: 1 loe/lisa Kasutajad arvavad:  :: 0 :: 0 :: 1
tagasi üles
vaata kasutaja infot saada privaatsõnum
nene
Kreisi kasutaja
nene

liitunud: 20.03.2004




sõnum 25.10.2009 13:52:04 vasta tsitaadiga

andrusny kirjutas:
tsitaat:

Mida sa teeksid kui sa tahaksid kuue-küljelise täringu abil leida juhuslikku arvu vahemikus 101 kuni 106?


Nii see töötabki ju
Kontrollib olemasolevaid numbreid ja teine tingimus kontrollib esimesest numbrist väiksemaid.


Niiviisi töötab küll sinu kood, aga küsimus oli, kuidas sa leiaksid juhusliku arvu vahemikus 101 kuni 106 kasutades täringut.

Sinu koodi järgi toimiksid sa nõnda:

Võtad 106-küljelise täringu ja veeretad.
Kui saadud arv < 101 siis:
  Alusta uuesti algusest.
Vastasel juhul:
  Juhuslik arv leitud. Lõpeta.


See algoritm tõesti töötab, kuid see pole kaugeltki efektiivne. 106-küljelise täringuga veeretades on tõenäosus sattuda vahemikku 101..106 umbes ühel juhul kahekümnest. Seega peaksid keskmiselt umbes 20 korda veeretama, et vastus kätte saada.

Ja mida suuremaks arvud lähevad seda hullem. Kui sa tahaksid leida juhuslikku arvu 1000001 ja 1000002 vahel peaksid tõenöoliselt veeretama oma pool miljonit korda. Teeksid sa seda?

Mina viskaksin hoopis kulli ja kirja. Kui kull siis 1000001, kui kiri siis 1000002.

Juhusliku arvu 101 ja 106 vahel leidmiseks toimiksin nii:

Võtan 6-küljelise täringu ja veeretan.
Liidan saadud tulemusele 100.


Ei mingit korduvat veeretamist tarvis.

_________________
Mõistus otsas? Pane pinusse...
Kommentaarid: 24 loe/lisa Kasutajad arvavad:  :: 0 :: 1 :: 23
tagasi üles
vaata kasutaja infot saada privaatsõnum mine selle kasutaja kodulehele
andrusny
Kreisi kasutaja
andrusny

liitunud: 20.03.2006




sõnum 25.10.2009 14:58:16 vasta tsitaadiga

mark11 antud lingil täpselt nii toimitaksegi. Tänud.
_________________
Kommentaarid: 7 loe/lisa Kasutajad arvavad:  :: 0 :: 0 :: 7
tagasi üles
vaata kasutaja infot saada privaatsõnum mine selle kasutaja kodulehele
näita postitusi alates eelmisest:   
uus teema   vasta Tarkvara »  Programmeerimine »  JS random generator
[vaata eelmist teemat] [vaata järgmist teemat]
 lisa lemmikuks
näita foorumit:  
 ignoreeri teemat 
sa ei või postitada uusi teemasid siia foorumisse
sa ei või vastata selle foorumi teemadele
sa ei või muuta oma postitusi selles foorumis
sa ei või kustutada oma postitusi selles foorumis
sa ei või vastata küsitlustele selles foorumis
sa ei saa lisada manuseid selles foorumis
sa võid manuseid alla laadida selles foorumis



Hinnavaatlus ei vastuta foorumis tehtud postituste eest.