/*

Questo sarebbe un programma che ho fatto a scuola... sono le funzioni di base del calcolo combinatorio ovvero: 

- Combinazioni semplici
- Combinazioni con ripetizione
- Anagrammi
- K parti di un N Insieme 

Ora non mi metto qua a spiegare cosa sono.. chi sa qualcosa di calcolo capisce :)
In ogni caso all'interno del programma c'e' qualche piccola spiegazione :) 

Scritto in java.


*/


import javax.swing.*;
    
public class Comb 
{   
    /* Metodo per il calcolo del fattoriale */
    public static long fattoriale ( long numero )
    {
        long fattoriale = 1;
        for ( long i = numero; i > 0; i-- )
            fattoriale *= i;
        return fattoriale;
    }
    
    /* Metodo per il calcolo del pedice */
    public static long pedice ( long dominio, long codominio )
    {
        long pedice = 1;
        for ( int i = 0; i < dominio; codominio--, i++ )
            pedice *= codominio;
        return pedice;
    }
    
    /* Metodo per il calcolo dell'elevazione a potenza */
    public static long elevato ( long numero, long esponente )
    {
        long elevato = 1;
        for ( int i = 0; i < esponente; i++ )
            elevato *= numero;
        return elevato;
    }
           
    public static void main ( String args[] )
    {
        int scelta = 0, codominio, dominio;
        String scelta2, nome, nome2 = "";
        char sn, k1, k2;
        long len, finale = 1, cont = 0;
        
        while ( scelta != 5 )
        {
            scelta = Integer.parseInt(JOptionPane.showInputDialog("1) Combinazioni semplici\n2) Combinazioni con ripetizione\n3) Anagrammi\n4) K parti di un N insieme\n5) Uscire\nScegli cosa vuoi fare"));
        
            switch(scelta)
            {
                case 1: JOptionPane.showMessageDialog(null, "Questa relazione conta tutte le funzioni che possiamo avere da un k-insieme a \nun n-insieme da un insieme di partenza costituito da n-elementi distinti, \nvoglio costruire le distribuzioni a k a k senza reinserimento di questi elementi\nFormula: Codominio pedice Dominio"); 
                        codominio = Integer.parseInt(JOptionPane.showInputDialog("Scrivi il codominio"));
                        dominio = Integer.parseInt(JOptionPane.showInputDialog("Scrivi il dominio"));
                        JOptionPane.showMessageDialog(null, "Il risultato e': " + pedice(dominio, codominio));   
                        break;  
                        
                case 2: JOptionPane.showMessageDialog(null, "Questa relazione conta tutte le funzioni che possiamo avere da un k-insieme a \nun n-insieme da un insieme di partenza costituito da n-elementi distinti, \nvoglio costruire le distribuzioni a k a k con ripetizioni di questi elementi\nFormula: Codominio elevato Dominio");
                        codominio = Integer.parseInt(JOptionPane.showInputDialog("Scrivi il codominio"));
                        dominio = Integer.parseInt(JOptionPane.showInputDialog("Scrivi il dominio"));
                        JOptionPane.showMessageDialog(null, "Il risultato e': " + elevato(codominio, dominio));
                        break;            
                
                case 3: JOptionPane.showMessageDialog(null, "Questa funzione conta tutte le possibilita' che abbiamo di avere parole distinte (senza reinserimento) o anche in cui si ripetono le lettere\nuguali nella stessa posizione (con reinserimento)\nFormula con reinserimento: Fattoriale della cardinalita' della parola, |Parola|!\nFormula senza reinserimento: Fattoriale della cardinalita' della parola diviso il fattoriale delle lettere che si ripetono,\n (|Parola|)! : (Lettere che si ripetono)!");
                        scelta2 = JOptionPane.showInputDialog(null, "Vuoi con ripetizione? (s/n)");
                        sn = scelta2.charAt(0);
                        switch(sn)
                        {
                            case 's': nome = JOptionPane.showInputDialog("Scrivi nome da anagrammare");
                                      JOptionPane.showMessageDialog(null, "Le possibilita' con ripetizione sono: " + fattoriale(nome.length()));
                                      break;     
                                      
                            case 'n': nome = JOptionPane.showInputDialog("Scrivi nome da anagrammare");
                                      len = nome.length();
                                      
               /* Questo ciclo calcola quante volte le singole lettere si ripetono nel nome. Una lettera gia' contata in un cilclo  *
                * non viene piu' contata in quello successivo perche' viene sostituita con un *.                                    */                  
                                       
                                      for ( int i = 0; i < len; i++ )
                                      {
                                          k1 = nome.charAt(i);
                                          if ( k1 != '*' )
                                          {
                                                for ( int j = 0; j < len; j++ )
                                                {
                                                    k2 = nome.charAt(j);
                                                    if ( k1 == k2 )
                                                    {
                                                        cont++;
                                                        nome2 += '*';
                                                    }
                                                    else
                                                        nome2 += k2;
                                                }                 
                                              
                                                finale *= fattoriale(cont);
                                              
                                                cont = 0;
                                                nome = nome2;   
                                                nome2 = "";
                                          }     
                                      }
                                                                           
                                      JOptionPane.showMessageDialog(null, "Le possibilita' senza ripetizione sono: " + fattoriale(len) / finale);       
                                      finale = 1;
                                      break;   
                        
                            default: JOptionPane.showMessageDialog(null, "Scelta non possibile");
                        
                        }
                        break;
                        
                case 4: codominio = Integer.parseInt(JOptionPane.showInputDialog("Scrivi il codominio"));
                        dominio = Integer.parseInt(JOptionPane.showInputDialog("Scrivi il dominio"));
                        JOptionPane.showMessageDialog(null, "Il risultato e': " + ( pedice(dominio, codominio) / fattoriale(dominio) ));
                        break;
                        
                case 5: JOptionPane.showMessageDialog(null, "Programma terminato"); break;
                default: JOptionPane.showMessageDialog(null, "Scelta non possibile" ); break;
            }
       }
   }
}


