Newsgroup: it.comp.lang.javascript
Titolo: Permutazione casuale array

Esiste un codice javascript che mi permette di permutare casualmente i
valori di un array contenente semplicemente i numeri da 1 a 10?
Grazie

 i numeri da 1 a 10?
Se ho capito bene, hai un array di 10 elementi (indici dell'array da 0 a 9)
che contengono i numeri da 1 a 10. Piů o meno cosě:
    a = new Array();
    for (i = 0; i < 10; i++)
        a[i] = i + 1;
Giusto?
Ora tu vorresti mischiare i numeri casualmente, in modo che, ad esempio il
primo elemento contenga 7, il secondo 5, e cosě via...
Se ho capito bene quello che vuoi, puoi fare cosě: prima prendi un numero
casuale compreso fra 0 e 9 (n - 1); il numero che corrisponde a questo
indice lo scambi con quello che si trova in ultima posizione. Quindi ora in
ultima posizione hai uno dei 10 valori preso a caso.
Ripeti poi il procedimento per i rimanenti 9 numeri, poi per i rimanenti
8...
Non č complicato; č piů semplice da fare che da dire:
    // a č l'array da mischiare
    function mischia(a) {
        n = a.length;
        while(n > 1) {
            // numero intero casuale fra 0 e n - 1
            x = (Math.random() * n * 0.999) >> 0; // (c) A. Carabelli
            // scambia l'ultimo elemento
            temp = a[n - 1];
            // con quello estratto casualmente
            a[n - 1] = a[x];
            a[x] = temp;
            n--
        }
    }
Maurizio.

             x = (Math.random() * n * 0.999) >> 0; // (c) A. Carabelli
.. chi diamine e' Carabelli, e perche' avrebbe il (c) su un codice del 
genere? ^__^"
P.S.
Tra l'altro a mio avviso e' in casi come questi non solo inutile ma poco 
performante. Associa direttamente n a .length-1; invece che a .length.
Ti elimini ad ogni ciclo una moltiplicazione con un float e le 
successive sottrazioni in riferimento all'array.
-- 
C'ya,
ZER0
  :. job profile - coder.gfxer.webDesigner
"When you have eliminated the impossible, whatever remains,
however improbable, must be the truth." (S.H.)

 con un float e le successive sottrazioni in riferimento all'array.
Tutto QUASI giusto. Avrei dovuto decrementare n prima di effettuare lo
scambio, cioè:
    temp = a[--n];
    a[n] = a[x];
    a[x] = temp;
ma ho preferito lasciarlo com'era perché mi sembrava più comprensibile.
Se avessi messo subito n = a.length -1 poi lo avrei dovuto incrementare per
ricavare il numero casuale.
Insomma è vero che la funzione random() riporta un numero fra 0 e 1
(compresi gli estremi); per cui basterebbe moltiplicare Math.random() per
n - 1 per ottenere un numero compreso fra 0 e n - 1. Però il valore
superiore si otterebbe una volta ogni morte di papa e non avrebbe la stessa
probabilità degli altri.
Invece, moltiplicando random() per n si corre il rischio di ottenere (semel
in anno) anche il valore n che dovrebbe essere escluso. Quindi avrei dovuto
scrivere:
    if (x == n)
        x--;
Per evitare questo ulteriore controllo ho preferito moltiplicare il tutto
per 0.999.
Maurizio.

 per 0.999.
E' che io digerisco molto male sia le moltiplicazioni, che i valori 
float.. :) Sono cose che mi porto dietro dalle compo grafiche in 
assembly.. ;)


 grafiche in assembly.. ;)
Assembly per quale processore? Anch'io avevo queste avversioni quando facevo
programmi assembler. Però poi mi sono passate.
Scusa, ma in JS non esistono solo i float?
Maurizio.

 Scusa, ma in JS non esistono solo i float?
In quanto a specifiche, i numeri in JS dovrebbero essere tutti a 
precisione doppia.
Ma l'inteprete gestisce piu' velocemente i numeri interi rispetto a 
quelli in virgola mobile (benche' non con la differenza che potrebbe 
esserci in ASM/C).


 l'intero. Il (c) si riferisce solo a questo.
Sara' ovvio che non l'ho inventato io, sara' stupido, ma effettivamente non
l'ho mai visto usare da nessuno.

 Ahh.. figuriamoci :)
zzo vuoi?

 zzo vuoi?
Non il tuo, tesoVo :*


 l'ho mai visto usare da nessuno.
Rif. Notazione in virgola fissa.
Non si usa ">> 0" in C semplicemente per "troncare" un numero in quanto 
esiste il casting (inoltre il tipo di variabile rimarrebbe float, e 
cio' non e' bene), ma il procedimento analogo si utilizza per passare 
dalla notazione in virgola mobile alla notazione in virgola fissa.
In JS puo' essere utile quando si ha un Number() a cui troncare la parte 
in virgola mobile, in quanto non vi e' differenza di tipizzazione (non 
essendo appunto, tipizzato.. ergo in JS 2.0 gia' si dovrebbe fare un 
casting, presumo.. e quindi non conviene piu').
Si usa.. o meglio, forse e' il caso di dire "si usava", la notazione in 
virgola fissa, per le compo grafiche in assembly, per ottimizzare i 
calcoli ridondanti in virgola mobile.


 rimarrebbe float, e cio' non e' bene),
Non si usa in C perché l'operatore shift si può applicare solo agli int. Se
si tenta di applicarlo ad un float verrebbe un errore in fase di
compilazione.
Maurizio.

 Non si usa in C perché l'operatore shift si può applicare solo agli int.
Stavo parlando a livello logico :)


 Stavo parlando a livello logico :)
Non capisco lo stesso. Il cast serve per convertire un tipo in un altro non
per fare troncamenti. Se si vuole troncare un float in C (come in JS) esiste
la funzione floor. Non mi sognerei mai di convertire un float in int solo
per troncarlo e poi riconvertirlo in float.
Maurizio.

 per troncarlo e poi riconvertirlo in float.
Infatti, ma chi ha mai detto questo? Il concetto di base nasceva 
dall'idea di avere un float e volerlo troncare per ottenere un int.
In C, se anche fosse possibile usare lo shift in tal senso, bisognerebbe 
cmq utilizzare l'operatore di casting, quindi sarebbe un passaggio 
inutile (sempre a livello logico, intendo.. a questo mi riferivo prima).
Forse adesso sono stato piu' chiaro.


 Forse adesso sono stato piu' chiaro.
Decisamente... qui è facile fraintendere. Poi alla fine ci si accorge che si
dice la stessa cosa.
Maurizio.