PROBLEMA [C] Estrazione tipo superenalotto

romathena

Nuovo Utente
5
1
Ciao a tutt*,
sto cercando di fare un programmino in realtà semplice ma che mi sta dando molte difficoltà.
Farmi dare dal pc sei numeri random, ma uno alla volta, cioè non gli chiedo la sestina tutto in un colpo ma i numeri uno alla volta.
Io penso si debba usare il ciclo if...else.... ma non riesco a fargli fare quello che vorrei:

Ecco un esempio esemplificato di ciò che sto facendo:
C:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

main ()
{
    int n1, n2, n3;
    srand (time(0));
    n1 = rand()%5+1;
    printf("Il Primo Numero Magico è %d",n1);
    getchar ();
  
    n2 = rand()%5+1;
   
    if(n2!=n1)
   
    printf("Il Secondo Numero Magico è %d",n2);
    else {
        n2 = rand()%5+1;
printf("Il Secondo Numero Magico è %d",n2);
       
    }
    getchar ();
    n3 = rand()%5+1;
   
    if(n3!=n1,n2)
  
   
    printf("Il Terzo Numero Magico è %d",n3);
    else {
        n3 = rand()%5+1;
printf("Il Terzo Numero Magico è %d",n3);
       
    }
    getchar ();
  
   
   
}

Questo è limitato a 3 numeri su un massimo di 5 e non di 90, perchè così se ci sono dei problemi si capisce quasi subito.
Ho corretto una cosa; ora il programma non mi nasconde più alcune volte il numero estratto. Però non riesco a fargli evitare le ripetizioni. cioè succede che mi estraggatre numeri tipo: 4, 2, 4.
quindi il mio if....lui non lo considera proprio.

ho guardato alcuni tutorial...ma non riesco a trovare la soluzione.

Qualcun* può aiutarmi per favore??

Grazie mille per l'attenzione!!!
Ciaociao

Romano Tenan
 
Ultima modifica:

sp3ctrum

Amministratore
Staff Forum
16,106
7,923
CPU
AMD Ryzen 5 3900X
Dissipatore
Scythe Mugen 5 rev.b Push&Pull
Scheda Madre
ASUS TUF Gaming B550M-Plus WIFI
HDD
Nvme Samsung EVO 1Tb + SSD Samsung evo 850 250gb + Toshiba P300 3Tb
RAM
HyperX FURY 16gb 3200Mhz
GPU
ASUS Dual GeForce RTX 4070 OC White Edition 12GB GDDR6X
Audio
Topping DX3 Pro + Focusrite Scarlett 2i2 + Mackie MR524 + Beyer DT 770 Pro + Presonus SubWoofer
Monitor
LG Ultragear 27gp850
PSU
Corsair RM850x 80 PLUS Gold
Case
Thermaltake V200 RGB
Net
Vodafone 1000Mb
OS
Windows 11 Pro
Ciao, puoi correggere il titolo?
Non si scrive in maiuscolo
 
  • Mi piace
Reazioni: DispatchCode

DispatchCode

Moderatore
Staff Forum
Utente Èlite
2,233
1,868
CPU
Intel I9-10900KF 3.75GHz 10x 125W
Dissipatore
Gigabyte Aorus Waterforce X360 ARGB
Scheda Madre
Asus 1200 TUF Z590-Plus Gaming ATX DDR4
HDD
1TB NVMe PCI 3.0 x4, 1TB 7200rpm 64MB SATA3
RAM
DDR4 32GB 3600MHz CL18 ARGB
GPU
Nvidia RTX 3080 10GB DDR6
Audio
Integrata 7.1 HD audio
Monitor
LG 34GN850
PSU
Gigabyte P850PM
Case
Phanteks Enthoo Evolv X ARGB
Periferiche
MSI Vigor GK30, mouse Logitech
Net
FTTH Aruba, 1Gb (effettivi: ~950Mb / ~480Mb)
OS
Windows 10 64bit / OpenSUSE Tumbleweed

pabloski

Utente Èlite
2,868
916
Ciao a tutt*,
sto cercando di fare un programmino in realtà semplice ma che mi sta dando molte difficoltà.
Farmi dare dal pc sei numeri random, ma uno alla volta, cioè non gli chiedo la sestina tutto in un colpo ma i numeri uno alla volta.
Io penso si debba usare il ciclo if...else.... ma non riesco a fargli fare quello che vorrei:

Vedo un pò di problemi. Intanto compila? Perchè questo è un errore sintattico

C:
    if (n3!=n1,n2)

Poi il fatto che vengano nascosti dei numeri dipende proprio da quegli if. Cioè tu controlli che n2 sia diverso da n1, in caso contrario estrai di nuovo n2. Poi però non c'è il printf nel ramo else e quindi n2 non viene stampato.

Stessa cosa per n3.

Riguardo i numeri duplicati, beh su 5 numeri totali che gli chiedi, vuoi davvero che non escano dei duplicati?

Lì occorre un for esterno. Con un while interno che controlli che l'ultimo numero estratto non sia già presente nella lista di quelli estratti precedentemente.
 

M1n021

Utente Attivo
159
73
Ciao, il modo migliore per implementare quello che stai cercando di fare è:

- considerare un array di n (90 nel tuo caso) elementi (costituiti dai numeri che vanno da 1 a n);
- "mischiare" i primi k (6 nel tuo caso) elementi dell'array;
- a questo punto i primi k elementi dell'array costituiranno la sequenza casuale ricercata.


P.S.
Capisco i "progressi" della modernità, ma quel <<Ciao a tutt*>> mi infonde una certa tristezza...
 
  • Mi piace
Reazioni: bigendian

Andretti60

Utente Èlite
6,440
5,091
P.S.
Capisco i "progressi" della modernità, ma quel <<Ciao a tutt*>> mi infonde una certa tristezza...
pensa a tutte le persone che per tutta la loro vita sono sempre state interpellate usando un genere diverso dal loro, e tutta la “tristezza” da loro provata.
Non si tratta di “progressi della modernità”. Le lingue evolvono, non parliamo più l’italiano usato da Petrarca o Manzoni, non parliamo nemmeno più l’italiano usato trenta anni fa.
 
  • Mi piace
Reazioni: romathena

romathena

Nuovo Utente
5
1
Ciao, puoi correggere il titolo?
Non si scrive in maiuscolo
scusa......
Post unito automaticamente:

Vedo un pò di problemi. Intanto compila? Perchè questo è un errore sintattico

C:
    if (n3!=n1,n2)

Poi il fatto che vengano nascosti dei numeri dipende proprio da quegli if. Cioè tu controlli che n2 sia diverso da n1, in caso contrario estrai di nuovo n2. Poi però non c'è il printf nel ramo else e quindi n2 non viene stampato.

Stessa cosa per n3.

Riguardo i numeri duplicati, beh su 5 numeri totali che gli chiedi, vuoi davvero che non escano dei duplicati?

Lì occorre un for esterno. Con un while interno che controlli che l'ultimo numero estratto non sia già presente nella lista di quelli estratti precedentemente.
Ecco, grazie per la risposta....come vedi ho messo i printf ...e infatti ora mi stampa sempre il risultato ma....rimane il fatto che ripete i numeri. comunque ....compila..... non mi segnala errori.
Post unito automaticamente:

Ciao, il modo migliore per implementare quello che stai cercando di fare è:

- considerare un array di n (90 nel tuo caso) elementi (costituiti dai numeri che vanno da 1 a n);
- "mischiare" i primi k (6 nel tuo caso) elementi dell'array;
- a questo punto i primi k elementi dell'array costituiranno la sequenza casuale ricercata.


P.S.
Capisco i "progressi" della modernità, ma quel <<Ciao a tutt*>> mi infonde una certa tristezza...
grazie per la risposta.....
 

M1n021

Utente Attivo
159
73
pensa a tutte le persone che per tutta la loro vita sono sempre state interpellate usando un genere diverso dal loro, e tutta la “tristezza” da loro provata.
Non si tratta di “progressi della modernità”. Le lingue evolvono, non parliamo più l’italiano usato da Petrarca o Manzoni, non parliamo nemmeno più l’italiano usato trenta anni fa.
Sinceramente non vedo come certe forzature grammaticali possano tradursi in vantaggi concreti per determinate persone.
Che poi sarebbe anche interessante capire come esprimere queste novità nel linguaggio parlato! ?
Per quanto mi riguarda sono alquanto allergico a certe derive del politicamente corretto, ma capisco che possano esistere sensibilità diverse al riguardo.
Scusatemi per l'OT

grazie per la risposta.....
Di niente, comunque se può essere utile provo a spiegare meglio il secondo punto, che mi rendo conto può risultare poco chiaro:
- in pratica nel tuo caso ipotizziamo di avere un array di 90 elementi, costituito dai numeri ordinati che vanno da 1 a 90;
- iniziamo con lo scambiare il primo elemento con un elemento a caso tra quelli successivi al primo (compreso);
- scambiamo poi il secondo elemento con un elemento a caso tra quelli successivi al secondo (compreso);
- effettuiamo quindi la stessa operazione di scambiare l'elemento corrente con un elemento a caso tra quelli successivi all'elemento corrente (compreso) per 6 volte;
- infine andando a considerare i primi 6 elementi dell'array otterremo la sestina casuale ricercata.

In questo modo inoltre viene anche meno l'esigenza di andare a controllare ogni volta che il numero estratto non sia stato già estratto in precedenza.
 

BAT

Moderatore
Staff Forum
Utente Èlite
23,124
11,677
CPU
1-Neurone
Dissipatore
Ventaglio
RAM
Scarsa
Net
Segnali di fumo
OS
Windows 10000 BUG
Ciao, il modo migliore per implementare quello che stai cercando di fare è:

- considerare un array di n (90 nel tuo caso) elementi (costituiti dai numeri che vanno da 1 a n);
- "mischiare" i primi k (6 nel tuo caso) elementi dell'array;
- a questo punto i primi k elementi dell'array costituiranno la sequenza casuale ricercata.
Di niente, comunque se può essere utile provo a spiegare meglio il secondo punto, che mi rendo conto può risultare poco chiaro:
- in pratica nel tuo caso ipotizziamo di avere un array di 90 elementi, costituito dai numeri ordinati che vanno da 1 a 90;
- iniziamo con lo scambiare il primo elemento con un elemento a caso tra quelli successivi al primo (compreso);
- scambiamo poi il secondo elemento con un elemento a caso tra quelli successivi al secondo (compreso);
- effettuiamo quindi la stessa operazione di scambiare l'elemento corrente con un elemento a caso tra quelli successivi all'elemento corrente (compreso) per 6 volte;
- infine andando a considerare i primi 6 elementi dell'array otterremo la sestina casuale ricercata.
non va bene... il concetto è giusto ma per questioni matematiche non sono minimamente sufficienti k scambi
In questo modo inoltre viene anche meno l'esigenza di andare a controllare ogni volta che il numero estratto non sia stato già estratto in precedenza
questo è vero

mi spiego:
  • è corretto mettere 90 numeri in modo ordianto da 1 a 90 in un array
  • non è corretto fare solo k scambi (per es. k=6): se procedi in questo modo è molto probabile che i numeri da 1 a k (tutti o parte di essi) non facciano parte della sequenza pseudocasuale dei numeri estratti ed in ogni caso l'array non è mischiato affatto!
Il problema è analogo al mescolamento di un mazzo di 90 carte: per essere sicuro che sia ben mischiato bisogna eseguire l'operazione di mescolamento molte volte. Il modo corretto di farlo è:
  • riempi un array ordinato da 1 a 90
  • estari 2 numeri pseudocasuali tra 0 e 89 (gli indici di un array C) e scambi le posizioni dei rispettivi elementi --> questa operazione va fatta un numero elevato di volte, per esempio 200 volte (non solo k), di più è meglio.
  • alternativa: estrai un numero pseudocasuale k compreso tra 0 a 89 (indice dell'array in C) e scambi la posizione a[k] con il primo elemento a[0], e ripeti il procedimento per TUTTI gli indici successivi (quindi estrai un secondo numero pseudocasuale h e scambi a[1] con a[h]); la volta 90° ogni elemento risulta scambiato, ma non basta --> il ciclo va ripetuto almeno 4 volte (di più è meglio)
  • solo alla fine, quando tutto è veramente ben mischiato, la sequenza pseudocasuale è costituita dai primi k numeri
 

DispatchCode

Moderatore
Staff Forum
Utente Èlite
2,233
1,868
CPU
Intel I9-10900KF 3.75GHz 10x 125W
Dissipatore
Gigabyte Aorus Waterforce X360 ARGB
Scheda Madre
Asus 1200 TUF Z590-Plus Gaming ATX DDR4
HDD
1TB NVMe PCI 3.0 x4, 1TB 7200rpm 64MB SATA3
RAM
DDR4 32GB 3600MHz CL18 ARGB
GPU
Nvidia RTX 3080 10GB DDR6
Audio
Integrata 7.1 HD audio
Monitor
LG 34GN850
PSU
Gigabyte P850PM
Case
Phanteks Enthoo Evolv X ARGB
Periferiche
MSI Vigor GK30, mouse Logitech
Net
FTTH Aruba, 1Gb (effettivi: ~950Mb / ~480Mb)
OS
Windows 10 64bit / OpenSUSE Tumbleweed
Ne aggiungo una io in merito allo shuffle di un array. Servirà però un secondo array.

È anche piuttosto semplice in realtà:
  • Viene scelto randomicamente un numero da 0 a N (dimensione array)
  • viene inserito in un nuovo array l'elemento estratto, e al suo posto viene inserito l'ultimo numero dell'array (ora l'array sarà lungo N-1)
  • si prosegue sino alla fine
Provo con un esempio numerico anche se da smartphone è un po' scomodo

Codice:
// array di partenza
In = 1,2,3,4,5
Out = {} // output

// indice random generato (0,4)
r = 3
In = 1,2,3,5
Out = 4

r=1
In=1,3,5
Out=4,2

r=0
In=3,5
Out=4,2,1

r=1
In=3
Out=4,2,1,5

r=0
In={}
Out=4,2,1,5,3

Non ricordo per cosa lo utilizzai anni fa (l'avevo letto da Knuth).
È l'algoritmo Fisher-Yates shuffle migliorato https://en.m.wikipedia.org/wiki/Fisher–Yates_shuffle#The_modern_algorithm

Probabilmente lo si riesce ad implementare anche con un solo array, ad esempio prelevando l'i-esimo elemento generato, metterlo in posizione 0, e mettere l'elemento che è in zero alla i-esima posizione.
Poi il numero generato non sarà da 0 a N-1, ma da M+1 a N.
 
  • Mi piace
Reazioni: Andretti60

M1n021

Utente Attivo
159
73
Il problema è analogo al mescolamento di un mazzo di 90 carte: per essere sicuro che sia ben mischiato bisogna eseguire l'operazione di mescolamento molte volte.
Mescolare più volte un mazzo di carte fisico serve per generare aleatorietà nel mondo reale, cosa che a livello informatico è invece affidata ad un generatore di numeri pseudocasuali, quindi il fatto di ripetere più volte una stessa operazione di scambio non penso servi a qualcosa, in quanto un processo o è aleatorio o non lo è, non esistono diversi livelli di aleatorietà.

alternativa: estrai un numero pseudocasuale k compreso tra 0 a 89 (indice dell'array in C) e scambi la posizione a[k] con il primo elemento a[0], e ripeti il procedimento per TUTTI gli indici successivi
La distribuzione di probabilità ottenuta in questo modo non è uniforme, in quanto ad ognuna delle possibili n! sequenze saranno associate probabilità diverse che sono funzione dell'ordinamento iniziale dell'array.

non è corretto fare solo k scambi (per es. k=6): se procedi in questo modo è molto probabile che i numeri da 1 a k (tutti o parte di essi) non facciano parte della sequenza pseudocasuale dei numeri estratti ed in ogni caso l'array non è mischiato affatto!
Ovviamente se mi fermo a k=6 l'array non sarà mischiato per intero, ma quello che conta è che i primi 6 elementi costituiranno una sestina casuale.

Ne aggiungo una io in merito allo shuffle di un array. Servirà però un secondo array.
Probabilmente lo si riesce ad implementare anche con un solo array, ad esempio prelevando l'i-esimo elemento generato, metterlo in posizione 0, e mettere l'elemento che è in zero alla i-esima posizione.
Poi il numero generato non sarà da 0 a N-1, ma da M+1 a N.
Credo equivalga a quello che ho scritto in precedenza:
- in pratica nel tuo caso ipotizziamo di avere un array di 90 elementi, costituito dai numeri ordinati che vanno da 1 a 90;
- iniziamo con lo scambiare il primo elemento con un elemento a caso tra quelli successivi al primo (compreso);
- scambiamo poi il secondo elemento con un elemento a caso tra quelli successivi al secondo (compreso);
- effettuiamo quindi la stessa operazione di scambiare l'elemento corrente con un elemento a caso tra quelli successivi all'elemento corrente (compreso) per 6 volte;
Tradotto in codice questa funzione di mescolamento dovrebbe ridursi a qualcosa del genere:
C:
void scambia(int *a, int *b)
{
    int temp = *a;
    *a = *b;
    *b = temp;
}

void mischia_array(int *v, const unsigned int n)
{
    for(unsigned int i = 0; i < n - 1; ++i)
    {
        scambia(v + i, v + i + rand() % (n - i));
    }
}
Poi ovviamente nel caso specifico, come detto in precedenza, non serve neanche mischiare l'array per intero, ma basta fermarsi a 6 scambi.
 
  • Mi piace
Reazioni: DispatchCode

BAT

Moderatore
Staff Forum
Utente Èlite
23,124
11,677
CPU
1-Neurone
Dissipatore
Ventaglio
RAM
Scarsa
Net
Segnali di fumo
OS
Windows 10000 BUG
Mescolare più volte un mazzo di carte fisico serve per generare aleatorietà nel mondo reale, cosa che a livello informatico è invece affidata ad un generatore di numeri pseudocasuali, quindi il fatto di ripetere più volte una stessa operazione di scambio non penso servi a qualcosa, in quanto un processo o è aleatorio o non lo è, non esistono diversi livelli di aleatorietà
falso: pensa a come avviene una "mescolata" reale;
quando mischi una volta un mazzo di carte reale è come se tu scambiassi di posto un certo numero di carte 2 a 2
la maggior parte delle persone mischia circa 4-5 volte ritenendolo sufficiente, in realtà ci sono studi dietro che dimostrano che non è così, per esempio nei casinò americani l'operazione di mescolamento è affidata a macchina mescolatrici che ripetono l'operazioni un numero elevatissimo di volte (ed è stato osservato che per aumentare l'aleatorietà del fenomeno andrebbero usare in sequenza 2 macchine...)
Ovviamente se mi fermo a k=6 l'array non sarà mischiato per intero, ma quello che conta è che i primi 6 elementi costituiranno una sestina casuale.
vero, ma funziona solo ai fini dell'esercizio, devi tener conto il quadro generale
La distribuzione di probabilità ottenuta in questo modo non è uniforme, in quanto ad ognuna delle possibili n! sequenze saranno associate probabilità diverse che sono funzione dell'ordinamento iniziale dell'array.
  1. la distribuzione di probabilità non è mai uniforme perché i numeri sono pseudocasuali che possono solo simularla in modo a volte grossolano (dipende dall'algoritmo usato, i randomizzatori in C integrati nei linguaggi per motivi di efficienza purtoppo non brillano sotto questo aspetto)
  2. l'array iniziale è sempre e comunque ordinato da 1 a 90, quindi non esiste che le sequenze siano "in funzione di"; tra l'altro se fossero "in funzione di" qualcosa si perderebbe proprio quello che serve di più: la casualità
il problema del mescolamento corretto è ben studiato e noto, come dicevo prima ai soli fini dell'esercizio può bastare fare pochi scambi, ma in generale non è corretto
 

M1n021

Utente Attivo
159
73
@BAT apprezzo che almeno tu legga quello che scrivo, ma mi sa che non hai capito bene quello che intendo dire...

L'algoritmo che ho proposto fin dall'inizio è il seguente:
- considerare un array di n (90 nel tuo caso) elementi (costituiti dai numeri che vanno da 1 a n);
- "mischiare" i primi k (6 nel tuo caso) elementi dell'array;
- a questo punto i primi k elementi dell'array costituiranno la sequenza casuale ricercata.
se può essere utile provo a spiegare meglio il secondo punto, che mi rendo conto può risultare poco chiaro:
- in pratica nel tuo caso ipotizziamo di avere un array di 90 elementi, costituito dai numeri ordinati che vanno da 1 a 90;
- iniziamo con lo scambiare il primo elemento con un elemento a caso tra quelli successivi al primo (compreso);
- scambiamo poi il secondo elemento con un elemento a caso tra quelli successivi al secondo (compreso);
- effettuiamo quindi la stessa operazione di scambiare l'elemento corrente con un elemento a caso tra quelli successivi all'elemento corrente (compreso) per 6 volte;
- infine andando a considerare i primi 6 elementi dell'array otterremo la sestina casuale ricercata.
e si concretizza nel codice postato in precedenza
C:
void scambia(int *a, int *b)
{
    int temp = *a;
    *a = *b;
    *b = temp;
}

void mischia_array(int *v, const unsigned int n)
{
    for(unsigned int i = 0; i < n - 1; ++i)
    {
        scambia(v + i, v + i + rand() % (n - i));
    }
}
Se poi hai frainteso quello che intendevo dire, non so che dirti, ma in ogni caso ribadisco che con questo procedimento non ha alcun senso logico mischiare più del necessario come da te proposto e anzi, relativamente al problema in esame, bastano solo 6 scambi per ottenere una sestina perfettamente casuale.
Se poi ritieni comunque che quello che dico sia sbagliato, allora spiegami e dimostrami il perché.


  1. la distribuzione di probabilità non è mai uniforme perché i numeri sono pseudocasuali che possono solo simularla in modo a volte grossolano (dipende dall'algoritmo usato, i randomizzatori in C integrati nei linguaggi per motivi di efficienza purtoppo non brillano sotto questo aspetto)
  2. l'array iniziale è sempre e comunque ordinato da 1 a 90, quindi non esiste che le sequenze siano "in funzione di"; tra l'altro se fossero "in funzione di" qualcosa si perderebbe proprio quello che serve di più: la casualità
Anche qui penso che non ci stiamo capendo... il metodo da te proposto:
alternativa: estrai un numero pseudocasuale k compreso tra 0 a 89 (indice dell'array in C) e scambi la posizione a[k] con il primo elemento a[0], e ripeti il procedimento per TUTTI gli indici successivi
se ho ben capito consiste nello scambiare ogni elemento dell'array con un elemento a caso dell'intero array, e in tal caso ribadisco quanto detto in precedenza:
La distribuzione di probabilità ottenuta in questo modo non è uniforme, in quanto ad ognuna delle possibili n! sequenze saranno associate probabilità diverse che sono funzione dell'ordinamento iniziale dell'array.
Come prova guarda il seguente schema ad albero basato su un array di 3 elementi (inizialmente ordinato da 1 a 3):

ss.png


Innanzitutto salta subito all'occhio che i 27 risultati così ottenuti non possono essere uniformemente distribuiti tra le possibili sequenze diverse di 3 elementi (il cui numero è dato dalle permutazioni di 3 elementi, pari a 3!=6), in quanto banalmente 27 non è divisibile per 6. E infatti se si contano i 27 risultati si nota che 3 sequenze si ripetono 4 volte e 3 sequenze 5 volte, ed è proprio questo che intendevo con "distribuzione di probabilità non uniforme".
 

DispatchCode

Moderatore
Staff Forum
Utente Èlite
2,233
1,868
CPU
Intel I9-10900KF 3.75GHz 10x 125W
Dissipatore
Gigabyte Aorus Waterforce X360 ARGB
Scheda Madre
Asus 1200 TUF Z590-Plus Gaming ATX DDR4
HDD
1TB NVMe PCI 3.0 x4, 1TB 7200rpm 64MB SATA3
RAM
DDR4 32GB 3600MHz CL18 ARGB
GPU
Nvidia RTX 3080 10GB DDR6
Audio
Integrata 7.1 HD audio
Monitor
LG 34GN850
PSU
Gigabyte P850PM
Case
Phanteks Enthoo Evolv X ARGB
Periferiche
MSI Vigor GK30, mouse Logitech
Net
FTTH Aruba, 1Gb (effettivi: ~950Mb / ~480Mb)
OS
Windows 10 64bit / OpenSUSE Tumbleweed
Credo equivalga a quello che ho scritto in precedenza:

Tradotto in codice questa funzione di mescolamento dovrebbe ridursi a qualcosa del genere:
C:
void scambia(int *a, int *b)
{
    int temp = *a;
    *a = *b;
    *b = temp;
}

void mischia_array(int *v, const unsigned int n)
{
    for(unsigned int i = 0; i < n - 1; ++i)
    {
        scambia(v + i, v + i + rand() % (n - i));
    }
}
Poi ovviamente nel caso specifico, come detto in precedenza, non serve neanche mischiare l'array per intero, ma basta fermarsi a 6 scambi.

Si, esatto. Ho risposto ieri notte e ammetto di non essere riuscito a leggere tutti i vostri interventi ?
Non l'ho testato ma secondo me è corretto.

quando mischi una volta un mazzo di carte reale è come se tu scambiassi di posto un certo numero di carte 2 a 2

Questo è vero, però considera che in questo caso il range degli elementi che consideri viene ristretto.
Per usare il mazzo di carte:

Codice:
v = [0, 52];

c = 0; // indice considerato dell'array
s = c +  (rand() % (n-c)); // indice random

// Scambi
v[c] ^= v[s];
v[s] ^= v[c];
v[c] ^= v[s];

// Passo successivo
c = 1;
s = c +  (rand() % (n-c)); // indice random

// Scambi
v[c] ^= v[s];
v[s] ^= v[c];
v[c] ^= v[s];

// Passo n

La posizione c la modifichi solo al passo c. Gli elementi non avranno più l'ordine che avevano in precedenza. Certo che come dici può anche succedere che l'elemento che vai a scambiare (l'indice randomico) sia l'elemento successivo a quello preso in precedenza.


EDIT:
Sono andato a guardare anche l'implementazione specifica di shuffle in Java ad esempio:

Java:
    public static void shuffle(List<?> list, Random rnd) {
        int size = list.size();
        if (size < SHUFFLE_THRESHOLD || list instanceof RandomAccess) {
            for (int i=size; i>1; i--)
                swap(list, i-1, rnd.nextInt(i));
        } else {
            Object arr[] = list.toArray();
            // Shuffle array
            for (int i=size; i>1; i--)
                swap(arr, i-1, rnd.nextInt(i));
            // Dump array back into list
            // instead of using a raw type here, it's possible to capture
            // the wildcard but it will require a call to a supplementary
            // private method
            ListIterator it = list.listIterator();
            for (int i=0; i<arr.length; i++) {
                it.next();
                it.set(arr[i]);
            }
        }
    }

Praticamente è il Fisher-Yates.
 
Ultima modifica:

Entra

oppure Accedi utilizzando
Discord Ufficiale Entra ora!

Discussioni Simili