No, hai ragione. però la 3 x 5 la puoi fare comunque. Infatti tu fai num/10 perché con la 3 x 9 in ogni colonna metti un range di 10 valori (1-10 , 11-20 , 21-30 , e così via) , con la 3 x 5 fai lo stesso, ma invece di dividere per 10 dividi per 18 (1-18 , 19-36 , 37-54 , 55-72 , 73-90 , i numeri in rosso sono appunto quei valori dell'array base). Dato che poi l'intera cartella verrà riempita , e quindi tutti e 15 valori della matrice 3 x 5 saranno validi, non ci sarà bisogno di sapere quanti elementi sono presenti in una riga o colonna, al massimo bisognerà sapere se un valore nella cartella è uscito o no. questo può essere fatto facilmente definendo un tipo 'struttura' di nome Numero, che contiene 2 campi: il primo rappresenta il valore, il secondo rappresenta la sua estrazione, ad esempio:
typedef struct{
int valore;
bool estratto;
}Numero;
e poi usre questo nuovo tipo strutturato come elemento per la tua matrice:
// come semplice matrice
typedef Numero Cartella[5][3];
//come tipo Cartella
typedef Numero Colonna[3];
typedef Colonna Cartella[5];
Ora per accedere ad un numero specifico non devi fare altro che accedervi come una normale matrice:
Cartella cartella; //dichiaro una variabile di tipo Cartella
Numero cart[5][3]; //questa variabile è una matrice identica a 'cartella'
printf("%4d",cartella[3][1].valore); //stampo a video il 'valore' del Numero in 4° colonna e 2° riga.
Così è anche più facile verificare i numeri estratti, infatti bisognerà solo vedere se 'estratto' di un numero risulta 'true'
if(cartella[2][0].estratto==true)printf("\nIl numero è stato estratto"); //verifico semplicemente il valore di 'estratto' del Numero posto nella 3° colonna e 1° riga
else printf("\nIl numero non è stato estratto");
Il codice risulta semplificato anche per la generazione dei numeri e per la pulizia della cartella.
Per tenere traccia invece di tutti i numeri estratti, puoi semplicemente utilizzare un array di 90 elementi booleani che ti indicano se il numero è stato estratto o no, ad esempio:
typedef bool Banco[90] //definisco un array di 90 elementi booleani che tiene conto i numeri estratti
//Ora posso dichiarare una variabile che rappresenta il mio banco
Banco banco; //dichiaro la variabile che rappresenterà le mie estrazioni
bool banco[90]; //fa la stessa cosa della riga sopra
Ora, la funzione che 'svuota' il banco può essere implementata semplicemente ponendo a 'false' tutti gli elementi dell'array passato alla funzione:
void PulisciBanco(Banco &banco){
for(int i=0;i<90;i++)
banco[i]=false;
}
void PulisciBanco(bool banco[90]){ //Fa la stessa e identica cosa della funzione sopra
for(int i=0;i<90;i++)
banco[i]=false;
}
Per le cartelle invece possono essere 'pulite' semplicemente ponendo a 'false' il valore di 'estratto' per ogni Numero:
void PulisciCartella(Carella &cartella){
for(int i=0;i<5;i++){
for(int j=0;j<3;j++)
cartella[i][j].estratto=false;
}
}
void PulisciCartella(Numero cartella[5][3]){ //fa la stessa cosa della funzione sopra
for(int i=0;i<5;i++){
for(int j=0;j<3;j++)
cartella[i][j].estratto=false;
}
}
Per quanto riguarda la generazione di una cartella, invece che generare il numero da 1 a 90 e poi scegliere la colonna giusta in base al numero, puoi generare il numero in base alla colonna in cui ti trovi, così che il numero sia solo un valore compreso tra '[(i*18)+1] + (rand() % 18)' , con 'i' indice di colonna. In questo modo eviti un sacco di controlli su quanti numeri una colonna possiede validi, in quanto con questo metodo non passi alla colonna successiva fintanto ché non sarà riempita per intero . Ed è quello che la funzione 'GeneraCartella' del mio codice precedente fa. Lo stesso vale per la funzione 'NumeroEsistente'.
Io penso sempre che prima di cominciare a scrivere del codice sia meglio valutare tutte le possibili soluzioni,in base alle risorse che abbiamo a disposizione, per poi scegliere quella che risulta 'ottimale' oppure un giusto compromesso tra velocità di esecuzione (molto importante) e spazio occupato in memoria (anch'esso importante). Poi è logico che nei vari 'casi di test' si può accendere la lampadina ( o molto spesso lo si sogna la notte e ci si sveglia con l'idea in testa ) con il codice 'perfetto' per così dire , questo però raramente accade!
Comunque non voglio costringerti a cambiare la tua logica sul funzionamento del programma, per cui se vuoi continuare in base al tuo codice, allora ti aiuterò su quello