
Sapete che cos'è il fattoriale? Sapete come si usa? Probabilmente si. Ciò che c'è davvero di interessante nella conoscenza e che, una volta assimilato un concetto, lo si può trasformare e/o utilizzare come lo si vuole. E una volta fatto, ci si può giocare. Ecco un esperimento divertente nato da una domanda quasi fatta per caso.
Più che come un articolo, potete pensare a questo come una sorta di flusso di coscienza, un racconto di come mi sia venuto in mente di giocare con i numeri. Stavo parlando con il nostro gio22 e mentre parlavamo mi è stata fatta una domanda: "sapresti scrivere un programma che calcoli il fattoriale inverso?"
Dunque il fattoriale è un operatore matematico che moltiplica un numero per ciascuno dei numeri che lo precedono fino all'unità. I suoi utilizzi sono molteplici e sicuramente il nostro matematico di punta, Marco Giancola, potrà illuminarvi a dovere in merito.
Per fare un esercizio di programmazione di questo tipo, però, bisogna chiarirsi bene le idee: se è fattoriale è facile da calcolare perché tutti sanno che da un certo numero in giù tutti i numeri sono definiti, non si può calcolare il fattoriale inverso di un numero che non si conosce.
Se, infatti, l'operazione di fattoriale è certamente invertibile, bisogna per forza definire un massimo, dal momento che i numeri sono infiniti, altrimenti il risultato non potrebbe che essere infinito. E dal momento che i prodotti devono essere fatti in questa maniera, il numero diventerebbe infinito molto velocemente rispetto a quanto non accadrebbe semplicemente contandoli.
Detto questo, bando alle ciance: ecco la routine implementata in cui viene calcolata l'operazione richiesta:
function [i]=inv_fact(n) %% La funzione calcola il fattoriale inverso, partendo dal numero in %% ingresso i=1; numero=n; m=0; % flag di controllo while(n>1) n=n/i; if(round(n)~=n) disp('Il numero inserito non risulta da un fattoriale!'); m=1; break; else i=i+1; end end if (m==0) i=i-1; s=horzcat(num2str(numero),' e'' il fattoriale di ', num2str(i)); disp(s); else end
onde evitare di fomentare qualsiasi forma di polemica per il fatto che il codice che ho utilizzato è stato scritto in MATLAB, questa volta mi sono messo d'impegno a dare uno sguardo a Scilab ed Octave, con buona pace di chi era rimasto molto offeso le altre volte perché non ne abbiamo parlato.
In Octave, il codice è esattamente lo stesso. Le funzioni sono tutte presenti e l'output è quello che ci aspettiamo:
24 e' il fattoriale di 4
In Scilab, invece, la cosa è un po' più complessa perchè num2str è una funziona la cui analoga è msprintf (quindi c'è un po' da lavorare sul codice). Tra l'altro questa funzione viene particolareggiata se ci sono esigenze tipo precisione e formato. num2str(a,precision) è la sintassi per avere una data precisione; sfortunatamente, però, in questo particolare caso, Scilab non propone analogie o sostitute. Se vogliamo un dato formato, invece, num2str(a,format) diventa msprintf(format,a).
Detto questo, il codice è abbastanza semplice, le operazioni sono banali ma se avete bisogno di qualunque tipo di spiegazione, sappiate che sono a disposizione nei commenti per parlarne.
Che cosa vuol dire questo articolo? Di che cosa parla in effetti? Queste sono domande molto giuste.
Scrivo per darvi un'idea: programmare significa fare o far fare, meglio, delle cose. Se uno sa che cosa deve ottenere, per quanto idealmente sembri assurdo o inutile, la programmazione ci dà la possibilità di farlo.
Una volta che l'abbiamo fatto? Adesso che abbiamo realizzato il fattoriale inverso, che ce ne facciamo?
È la stessa domanda che potreste farvi dopo aver studiato un trattato di filosofia ma la risposta non può che essere la stessa: sapete una cosa di più, vi siete esercitati, vi siete allenati, avete provato e avete ottenuto risultati.
Cosa c'è di meglio che tenersi sempre in allenamento e con la mente sveglia?

bellissimo! non avevo mai pensato al fattoriale inverso. Grazie
Articolo interessante…
In ogni caso, la nozione di invertibilità del fattoriale non va intesa nel senso dell'analisi matematica. Ad esempio, assegnata una funzione reale di una variabile reale f(x), sotto particolari condizioni detta funzione è invertibile, nel senso che data la variabile y i.e. il valore assunto dalla funzione f(x), quindi y=f(x), con la funzione inversa possiamo calcolare x=f^-1(y), dove f^-1 è appunto la funzione inversa.
Con il fattoriale la questione è differente, poichè qui abbiamo una funzione RICORSIVA. Infatti il fattoriale è definito come f(n)=n*f(n-1).
In altre parole, non è possibile determinare l'inversa simbolicamente come si fa, appunto, in analisi.
Un'ultima cosa: visto che si ha un programma ricorsivo, è bene utilizzare qualche tecnica di cashing per ridurre il carico computazionale. Ho fatto una prova in ambiente Mathematica, come in quest'articolo.
http://www.extrabyte.info/2014/08/29/programmi-ricorsivi-con-mathematica-il-teorema-di-euclide/
per ciò che riguarda il teorema di euclide
Ho provato a fare una cosa del genere con Mathematica, ma non ci sono riuscito..
Ah sì?
E che cosa hai provato a fare esattamente?
Che difficoltà hai incontrato?
Ottime osservazioni!
In effetti spiegata così era un po’ lacunosa come definizione ma noi ci eravamo intesi :))
Ho applicato il comando InverseFunction. Ma non è questa la procedura corretta. Proverò a scrivere un programma con le strutture di controllo…
…e lo presenterai qui, vero? 😉
se ci riesco, scriverei un guest post
Innanzi tutto complimenti per l’argomento, che è un piccola “sfida” matematica. Anche io sto pensando a possibili algoritmi di ricerca della soluzione. Se trovo qualcosa di interessante, lo condivido.
Vorrei, per ora, soffermarmi sul codice, in particolare sulle funzioni di visualizzazione.
Invece di creare una stringa con horzcat e le conversioni di formato e poi usare disp è possibile usare sprintf
e, senza il ; finale non serve neanche disp.
In Scilab forse è più semplice del previsto perché disp concatena (e converte in stringa i numeri), automaticamente
Un’ultima osservazione: per come è scritto la funzione restituisce sempre e comunque un valore (quello dell’indice corrente). Sarebbe più corretto usare variabili di appoggio ed asseggnare solo alla fine il valore alla variabile d’uscita.
Ad esempio, indicando con y l’uscita (e lasciando i come indice) potresti inzializzare con
alla prima riga e poi nella sezione m==0, dopo l’aggiornamento della variabile i assegnare
Anche se queste osservazioni sono irrilevanti ripetto all’algoritmo ho pensato che possono essere utili come buona prassi.
Ciao,
Gianluca
Queste accortezze fanno la differenza tra un codice che funziona ed un bel codice 😀
Ottime osservazioni!
Interessante, è confermato?
Piuttosto direi che uno bada a queste cose quando deve raffinare ciò che ha fatto e tutto funziona..
I consigli restano validi!