Programma che scrive tutte le combinazioni semplici

Knuckles1
se ho 10 numeri come faccio a scrivere un programma in c, c++ che mi scriva tutte le combinazioni semplici (cioè tutte le combinazioni che differiscono tra loro per la natura degli oggetti, ma non per l'ordine degli stessi) a gruppi di 3?

Risposte
Cheguevilla
Così dovrebbe andare, ma l'ho buttato giù di getto senza controllare due volte.
Prendila come un'idea...

for (i=1;i<=8;i++)
   {for (j=i+1;j<=9;j++)
      for (k=j+1;k<=10;k++)
      printf(i,j,k);
   }

Knuckles1
Grazie del codice che potrebbe venirmi utile ma purtroppo non funziona... mi genera solo 8 combinazioni, quando le combinazioni dovrebbero essere 120....

Knuckles1
si ok... essendo un bel po arrugginito sul c, ho interpretato male il codice :) comunque... se i numeri fossero 4, e i gruppi da due, avrei 6 combinazioni, seguendo l'esempio sopra potrei scrivere questo codice?

for(i=0,i<4,i++)
  { 
     do{
            for(j=i+k,j<=4,j++) 
              {
                 k++;
                 printf(i,j);
               }
         }while(j=4)
  }

vict85
"Knuckles":
si ok... essendo un bel po arrugginito sul c, ho interpretato male il codice :) comunque... se i numeri fossero 4, e i gruppi da due, avrei 6 combinazioni, seguendo l'esempio sopra potrei scrivere questo codice?

for(i=0,i<4,i++)
  { 
     do{
            for(j=i+k,j<=4,j++) 
              {
                 k++;
                 printf(i,j);
               }
         }while(j=4)
  }


k non è inizializzato e comunque non capisco bene il principio di questo codice...

Ci sono almento 3 errori gravi e uno meno grave...
1. k non è inizializzato ne è limitato (cioé è limitato solo dal j=i+k perché se i+k è maggiore di 4 allora ti esce dal ciclo... ma da quel momento in poi non entrerà più nel for...
2. il printf non è scritto bene
3. il for è con i punti e virgola es.: for(1=0;1<10;++i) le virgole servono per esempio a questo for(i=0,j=10;i<=j;++i,--j)
3. manca il punto e virgola dopo il while(j=4)

Il metodo che ti è stato presentato è standard prova a riscriverlo in modo sensato...

Risultato dell'algoritmo corretto:

123
124
134
234

Umby2
"Knuckles":
si ok... essendo un bel po arrugginito sul c, ho interpretato male il codice :) comunque... se i numeri fossero 4, e i gruppi da due, avrei 6 combinazioni, seguendo l'esempio sopra potrei scrivere questo codice?



Dopo aver corretto il codice, prova anche a "generalizzare" il programma.
Potresti chiedere il numero degli elementi (x), ed il numero degli elementi del gruppo (y).

Knuckles1
gli errori di sintassi c li so... non ho voluto scrivere correttamente per pigrizia, ho dimenticato scrivere k=1; dopo il primo for:

for(....)
{ 
   k=1;
......
......



era solo per chiedere se il ragionamento potrebbe essere corretto....
cmq il risultato ottenuto dal codice corretto da quale codice deriva?

vict85
"Knuckles":
gli errori di sintassi c li so... non ho voluto scrivere correttamente per pigrizia, ho dimenticato scrivere k=1; dopo il primo for:

for(....)
{ 
   k=1;
......
......



era solo per chiedere se il ragionamento potrebbe essere corretto....
cmq il risultato ottenuto dal codice corretto da quale codice deriva?


Perché usi k se aumenti j indipendentemente da k? E inoltre non capisco perché c'é il do while...

il tuo codice darebbe un risultato del tipo

01 k=1
02 k=2
03 k=3
04 k=4
e poi esce ma di fatto con una condizione inutile perché ti fa la condizione j=4 no (è uguale a 5).

Cioé con le correzioni al linguaggio è corretto ma tremendamente "prolisso".

Cioé se ponevi j=i+1 e lo aumentavi di uno per volta fino a 4 avevi lo stesso effetto...

Knuckles1
ok ho più o meno capito gli errori :) adesso mi chiedo il metodo consigliatomi da cheguevilla è il più veloce? esiste un metodo estremamente più veloce?
mi spiego meglio se i le combinazioni da generare siano milioni......... ci vorrebbe più di mezz'ora a calcolarle tutte.... posso velocizzare la cosa?

Umby2
"Knuckles":
ok ho più o meno capito gli errori :) adesso mi chiedo il metodo consigliatomi da cheguevilla è il più veloce? esiste un metodo estremamente più veloce?
mi spiego meglio se i le combinazioni da generare siano milioni......... ci vorrebbe più di mezz'ora a calcolarle tutte.... posso velocizzare la cosa?


se ci sono milioni di combinazioni, ci vuole il tempo che ci vuole. Basta che compri un pc piu potente. :D
Il metodo del cheg è perfetto, ma solo "generalizzato" cosi' come prima ho scritto. :wink:

Knuckles1
noooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo
:)
cavolo.... se davvero non c'è un modo per velocizzare la cosa allora ce l'ho un pochino in quel posto.... volevo generare tutte le combinazioni del superenalotto.... ma era già due ore che il codice andava avanti e mancava ancora troppo.... devo sfoltire le combinazioni :)

Cheguevilla
Per generalizzare il problema come proposto da Umby, non è conveniente ragionare in maniera iterativa, poichè sarebbe un suicidio.
Molto meglio affrontare un approccio ricorsivo.
Tuttavia, come già fatto notare, poichè si tratta semplicemente di "generare" numeri, il tempo necessario dipende quasi esclusivamente dal numero delle combinazioni che si ottengono.
Bada bene che la printf è una funzione esageratamente "lenta".
Se parli del superenalotto, siamo di poco sopra ai 620 milioni di combinazioni.
Toglimi una curiosità: una volta che sei riuscito a stamparle su schermo, cosa te ne fai?

Knuckles1
il mio obbiettivo è sfoltire considerevolmente tali combinazioni... stampando solo le combinazioni che rispecchiano determinati requisiti...basandomi su dati statistici, fortuna e cocciutaggine :) per cui ora che ho imparato come stamparle dovrò andare a sfoltire l'enorme lista... impresa ardua e forse sciocca ma poi è pur sempre un gioco e un modo come un altro per divertirmi in maniera blanda con la programmazione :)

Cheguevilla
Scusa la domanda che potrebbe essere idiota, ma che criterio usi per sfoltire tali combinazioni?
La domanda ha due aspetti.
Uno statistico: mi incuriosisce sapere su quali basi statistiche certe combinazioni siano diverse da altre.
Uno informatico: perchè non provare a farla a priori la scrematura?

Knuckles1
La scrematura a priori è ovvio... prima scremo e poi stampo, ma prima volevo imparare a generare le combinazioni... cmq le basi statistiche sono semplici e banali e prive di ogni fondamento matematico, ma ad es statisticamente non sono mai uscite sestine costituite da tutti numeri consecutivi o con tutti i numeri compresi in una decina, per cui, cerco di sfoltire tali sestine lasciando solo le più probabili....

Knuckles1
quello che dici è perfettamente giusto e lo penso anche io... il superenalotto è un gioco, dove provi a giocare quella che secondo te è la sestina giusta, di conseguenza ognuno avrà il suo modo di inventarsi una sestina... ma so perfettamente che è inutile, ma come ho già detto il s. è pur sempre un gioco e quello che faccio è un modo come un altro per divertirmi in maniera blanda con la programmazione :).

comunque, domanda forse sciocca.... da quello che dici allora tutte le analisi statistiche sono infondate? a mio parere no... se sappiamo che al nord statisticamente ci sono più biondi che al sud, se pesco a caso una persona al nord e una a caso al sud, beh statisticamente è più probabile che il biondo sia del nord e il nero del sud... poi ovvio ci sono le eccezioni e di certo dire che al nord ci sono più biondi non vuol dire che lo sono tutti, anzi, ma è proprio quella eccezione che voglio togliere in quanto il lotto è un gioco :)

Knuckles1
ok... ma lo so che hai ragione :) metti caso che dopo tutti i mastrussi che faccio gioco una schedina e vinco? fortuna? o i conti fatti sarebbero stati importanti?

Cheguevilla
"Knuckles":
ok... ma lo so che hai ragione :) metti caso che dopo tutti i mastrussi che faccio gioco una schedina e vinco? fortuna? o i conti fatti sarebbero stati importanti?
I conti non contano.
Domanda stupida: scarteresti la combinazione 1 2 3 4 5 6? Perchè?

Knuckles1
no in quanto ha la stessa probabilità di vincere di un altra sestina.... però è anche vero che statisticamente non è mai uscita una sestina con numeri consecutivi.... e stranamente il primo numero non è mai 90... ma sempre un numero che grosso modo non supera 40-50... e stranamente l'ultimo numero non è mai 1, ma un numero che non va sotto 50-60... semplici coincidenze? siamo così sicuri che i numeri siano scelti proprio a caso? è per questo che pur sapendo che la probabilità è 1 su 622.6... ecc per tutte le sestine mi ostino a credere che tutte le sestine hanno in linea di massima uno stesso andamento... pazzo? forse però dal 97 ad oggi stranamente tutte le sestine sono simili...

Cheguevilla
e stranamente il primo numero non è mai 90... ma sempre un numero che grosso modo non supera 40-50... e stranamente l'ultimo numero non è mai 1, ma un numero che non va sotto 50-60... semplici coincidenze?
No, non è affatto una coincidenza.
Non contando l'ordine, i numeri vengono dati in ordine crescente, ma ciò non significa che siano stati estratti in questo ordine.

Il superenalotto esiste dal dicembre 1997, quindi da poco meno di 12 anni.
Consideriamo 2 estrazioni a settimana (ora sono tre, ma in principio era una), fanno $12*52*2=1248$ estrazioni.
Le estrazioni possibili sono poco più di 622 milioni.
Anche analizzando nel dettaglio le estrazioni già effettuate, che significato statistico possono avere 1300 estrazioni su 622 milioni?
Con altissima probabilità (vicina a uno), le estrazioni fatte finora saranno tutte diverse tra loro.
Quale mistico andamento dovrebbero avere le sestine estratte finora?
E soprattutto, se volessi fare una supposizione simile, dovresti basarti sulle estrazioni già effettuate, non su quelle possibili.
Infine: se non hai ancora fatto l'analisi delle estrazioni fatte finora, come fai ad ostinarti a ritenere che abbiano uno stesso andamento?

Knuckles1
ok ok.... :) scusate la testardaggine :) allora mi divertirò soltanto a programmare un pochino :) comunque visto che questa è la sezione informatica, quale istruzione è più veloce della printf?

Rispondi
Per rispondere a questa discussione devi prima effettuare il login.