Newsgroup: it.comp.appl.access
Titolo: Anagrammi

Qualcuno sa calcolare (via VBA) quante parole di k lettere si possono
ottenere da una stringa S (k <= S)?
Per esempio quante parole (diverse) di 8 lettere si possono ottenere
da "ANATROCCOLO"?
Bruno 

 ha scritto nel messaggio 
news:4422becf$0$36926$4faf...@reader3.news.tin.it...

Credo che il problema da affrontare sia piů che altro legato al database 
delle parole di senso compiuto che bisogna avere.
Esiste un db con tutte le parole del vocabolario?
Se sě, la funzione non credo sia impossibile.. un mucchio di codice come 
sempre accade quando ci sono stringhe di mezzo..
Per appesantire il meno possibile, approccerei il problema sminuzzando e 
contando le lettere che compongono la parola data (tipo 2A 1N 1T 1R 3O 2C 
1L) e poi quererey tutte quelle che hanno la lunghezza desiderata e un 
quantitativo (per ciascuna lettera) pari o inferiore a quelle a 
disposizione.
Forse pensandoci bene, o navigando su google si trova qualcosa di meglio.
Ciao. 

 delle parole di senso compiuto che bisogna avere.
Intendevo riferirmi a TUTTE le parole ottenibile, con o senza
significato accettabile. Cioè tutte le possibili combinazioni.
E mi riferisco alla determinazione del loro numero, non alla
loro generazione. Ché generare gli anagrammi e contarli poi è
quasi un gioco da ragazzi.
Ho riempito 3 facciate di A4 per l'algoritmo che li conta.
Mi chiedevo se non fosse un'assurdità e non si potesse fare meglio.
Bruno


Dovrebbero essere disposizioni semplici:
Dn,k=n(n-1)*(n-2) .... (n-k+1)
ANATROCCOLO
N=11
K=8
Dnk=11*9*8*7*6*5*4
I miei ricordi di calcolo combinatorio sono comunque da verificare  :-)
Ciao, Simone

 I miei ricordi di calcolo combinatorio sono comunque da verificare  :-)
I tuoi calcoli sono esatti.
Se non vi fossero doppioni...
Bruno 


E se la lunghezza e pari al numero di lettere uniche?
--
ac

 E se la lunghezza e pari al numero di lettere uniche?
Se k = n allora Pn = n!
In questo caso si parla di permutazioni.
Il numero di anagrammi di 5 lettere ottenibile da AMORE
è 5! = 5*4*3*2 = 120
Bruno 


Ciao bruno.Mi sono molto mal spiegato.
Intendevo dire che da ANATROCCOLO se invece di impostare L=11 imposti 
L=8 (cioe' togliendo 1A, 1C e 2O) non dovresti avere poi secondo la 
formula delle permutazioni il numero che ti occorre?
--
ac


sorry. 11-4 = 7
--
ac

 sorry. 11-4 = 7
Come dovrei fare a ottenere anagrammi di 8 lettere da una
parola di 7 lettere?
In ogni caso P7 = 5040 non è proprio il numero giusto.
Ciao
Bruno 

 ha scritto nel messaggio

Non è chiaro se ti interessano tutte le combinazioni possibili o solo quelle 
di senso compiuto.
Nel primo caso ho un programma già fatto (fu una disputa sull'argomento che 
mi porto a realizzarlo), nel secondo caso a quello che ho fatto io bisogna 
aggiungere un correttore ortografico che escluda le parole non di senso 
compiuto.
Sib
-- 
http://www.gestionedati.com
 


Hai ragione. Ho provato con la parola MAMA ed effettivamente non va
In questo caso se non erro secondo quanto avevo pensato il risultato 
sarebbe 2 quando invece e' 6 (teorico mi sembra sia 24)
Veramente per gli anagrammi sul come fare non ci avevo pensato.
Mi sembrava che a te interessasse solo il numero di anagrammi ottenibili.
Cmq faticando un po' (il PC)  con un paio di routines ricorsive e una 
collezione  (Gestendo come Key l'anagramma e con la error resume next 
per bypassare i duplicati) si dovrebbe ottenere
--
ac

 bypassare i duplicati) si dovrebbe ottenere
Sě, ho proceduto pressapoco cosě; ma ho scritto oltre 200
righe di codice. Per generarli ce ne vuole molto meno (di righe,
ma non di tempo...)
Ciao
Bruno 

 senso compiuto.
Prova a dirmi se il tuo programma riesce a calcolare quanti sono
gli anagrammi di 8 lettere ottenibili da ANATROCCOLO.
Tutti quelli possibili, abbiano o no un senso, però al netto dei
doppioni.
Bruno

 ma non di tempo...)
uhmmm.... mi sembrano un po' (le istruzioni).
Ma alla fine della generazione non hai il numero che ti interessa?
Non ho ben capito. Ti ci vuole tanto tempo di elaborazione?
Tra l'altro di questo tipo di funzioni forse ce ne dovrebbero essere 
parecchie in rete. Credo che sia un classico per tutti quei programmi 
che tentano di "scoprire" le passwords.
--
ac

 doppioni.
Per il calcolo basta una formuletta, non c'è bisogno di algoritmo.
Ancora una cosa non è chiara, le lettere ripetute nella parola di partenza 
(le O, le A e le C del tuo esempio) vanno sonsiderate come una sola lettera 
o come lettere diverse?
Se ti interessano le permutazioni in generale (cioè la prima A è una lettera 
da considerarsi diversa dalla seconda) la formula è:
n!/(n-k)!
dove n è il numero di lettere della parola di partenza (11 nel tuo caso) 
mentre k è il numero di lettere dell'anagramma (8 nel tuo caso)
Ciao
Sib
-- 
http://www.gestionedati.com
 

 tentano di "scoprire" le passwords.
Mai vista una.
Vi sono programmi che GENERANO un esiguo numero
di anagrammi con riferimento a un proprio database (dizionario);
non ne ho visto nessuno che generi TUTTI i possibili anagrammi
e, soprattutto, che ne sappia determinare direttamente
(cioè senza doverli generare prima) il numero.
Ripreciso ad abundantiam: anagrammi di ordine k da una stringa
di n caratteri, con k <= n.
Ché se k = n il numero è n! eventualmente diviso per il prodotto
dei fattoriali degli indici di molteplicità.
Bruno 

 mentre k è il numero di lettere dell'anagramma (8 nel tuo caso)
Stai facendo un po' di confusione:
n! / (n-k)! = Cn,k sono combinazioni di n elementi diversi fra di loro
presi k a k, non sono permutazioni.
Se poi gli n elementi non sono tutti diversi fra di loro (è il nostro caso!)
il discorso si complica assai.
Bruno

 "Sib" <sedav...@SPAMtiscali.it> wrote in message

Nessuna confusione (tra l'altro non è che ti stai esprimendo in modo 
particolarmente cortese).
le COMBINAZIONI non tengono conto della posizione delle lettere, le 
DISPOSIZIONI (se vuoi essere pignolo) sì e si calcolano esattamente come ho 
detto.
L'unica riflessione da fare è quella che ti ho suggerito all'inizio e cioè 
se la prima A è diversa dalla seconda A e cioè se:
la parola AACCLOOO va considerata come unica o se le due A ad es. possano 
scambiarsi tra loro e dare luogo a una nuova disposizione così come le C e 
le O.
Se tu avessi una parola iniziale composta in pratica da lettere diverse la 
formula che ti ho dato sarebbe perfetta.
Analogamente se ti interessassero solo gli anagrammi con K=N 
(E^PERMUTAZIONI) dovresti solo calcolare n!/(r1!*r2!...) dove r1, r2, ecc 
sono le ripetizioni delle lettere (3 O, 2C, 2 A nel tuo caso)
la complicazione si ha nel caso degli anagrammi con numero di lettere minore 
del numero di partenza perchè è difficile generalizzare.
Sib
-- 
http://www.gestionedati.com
 

 minore del numero di partenza perchè è difficile generalizzare.
Poichè si tratta di un calcolo che dovrebbe tener conto di diverse 
condizioni estremamente complesse, la cosa più semplice mi sembra quella di 
generare tutte le combinazioni bossibili che sono:
n! / ((n-k)!*k!)
nel tuo caso:
11! / ((11-8)!*8!) = 165
Abbastanza gestibili, poi di queste elimini le combinazioni doppie, molto 
semplice in quanto essendo combinazioni (in cui l'ordine non conta) puoi 
ordinare ciascun elemento delle singole parole per poi eseguire un controllo 
diretto tra le combinazioni.
A questo punto di ciascuna combinazione sopravvissuta ti limiti a calcolare 
tutti gli anagrammi possibili per farne poi la somma (senza bisogno di 
generare le permutazioni):
anagrammi di ciascuna combinazione =  k! /r1!*r2!*...
dove k è nel tuo caso 8 (dato che le combinazioni che hai generato sono di 
otto elementi) mentre r1, r2, ecc sono le eventuali ripetizioni presenti 
nelle lettere.
Le alternative sono mostruose a mio avviso.
Sib
-- 
http://www.gestionedati.com
 

 controllo diretto tra le combinazioni.
Ho esattamente seguito questa via, le 165 le ho messe in una tabella
poi con una query ho eliminato le duplicazioni.
Mi trovo con 114 combinazioni di 8 caratteri l'una.
Per ciascuna calcolo le 8! (40320) permutazioni, le metto in una tabella
(114 * 40320 = 4 596 480) poi con un'altra query elimino le
duplicazioni; le conto e ottengo il numero cercato.
Si potrebbe filtrare con una collection onde evitare il passaggio
dell'ultima query di eliminazione doppioni: ho preferito non farlo perché
2 GByte di RAM possono riempirsi facilmente lavorando con fattoriali
et similia.
Il processo richiede oltre 20 minuti di elaborazione con WinXP Pro,
Pentium IV @ 3,4 Ghz, 2 Gbyte RAM.
Mi hai tacciato di scortesia.
Consentimi almeno di essere spazientito: sono 2 giorni che scrivo
che generare gli anagrammi è un gioco da ragazzi, mentre ho dovuto
scrivere oltre 200 righe di codice per contarli senza doverli generare 
prima.
E che cosa abbiamo fatto finora? Abbiamo parlato della loro generazione.
Non un'idea, non un suggerimento sulla possibilità di calcolarli
senza soverli prima generare.
Avessi parlato arabo sarei stato certamente meglio compreso.
Ciao
Bruno


 Avessi parlato arabo sarei stato certamente meglio compreso.
Scusa Bruno, ma perchè sei così pretenzioso?
Ti ricordo che questa è un'area pubblica: nulla è dovuto.
Ciao, Simone

> presenti nelle lettere.
Sib
-- 
http://www.gestionedati.com
 

>> presenti nelle lettere.
Se sei così bravo perché non me li calcoli tu gli anagrammi
di "ANATROCCOLO", di 8 lettere, tutti, anche quelli che non
hanno significato, esclusi i doppioni?
Facciamo così:
Se me li calcoli entro le 20:00 di domani 26-03-06 spiegandomene
l'algoritmo (che non deve prevedere di contarli dopo averli generati,
ché con sarebbe un algoritmo, e deve potersi applicare alla generalità
dei casi, non solo alla fattispecie), io non mi farò più vivo
in questo NG per tutto il 2006.
Diversamente sarai assente tu per tutto il 2006.
Fra gentiluomini le sfide o si accettano o si tace.
Fammi vedere di che pasta sei fatto.
Bruno
PS
Se qualcun altro vuol partecipare all'agone può farsi avanti;
sono certo che ci metteremo d'accordo sulla posta.

 "Sib" <sedav...@SPAMtiscali.it> wrote in message

Mi sembri piuttosto infantile.
non siamo qui per sfidarci o per fare sfoggio, siamo qui perchè ci aiutiamo 
l'un l'altro nel nostro lavoro.
Ad ogni modo, visto che ho il tempo ti mostrerò come si fa così potrai 
risolvere il tuo problemino, ma non credere con questo di aver convinto 
qualcuno a fare il lavoro per te, non si ripeterà.
Sib
-- 
http://www.gestionedati.com
 

Vediamo chi l'ha più grosso....!!!!
Sono curioso.
(Fosse per me pubblicherei il risultato, ma col cavolo che pubblico il
codice)...!
In ogni caso Davide ritengo tu abbia centrato il problema delle lettere
doppie
che danno di fatto origine a parole doppie pur rientrando correttamente
nella
logica delle combinazioni.
Data questa combinazione:
OOOAACCL
questa è un'altra combinazione:
OOOAACCL
e questa un'altra ancora
OOOAACCL
Le ho ottenute ruotando le O, ma come ben sapete
ne potrei ottenere ben di più....!
Per questo forse Bruno ha dovuto generarle, ma se invece di fare 45
Query
usava un DISTINCT poteva ricavare il Numero...., oppure poteva usare
una
transazione che velocizzava il calcolo, ma vincolare l'inserimento
all'assenza
del Duplicato(magari proprio usando nella Tabella la PrimaryKey e
gestendo l'errore)...!
Ora io non sò come tu abbia fatto a discriminare la parola già
presente(perchè non stiamo
parlando di Combinazione), ma i metodi per ottimizzare dei cicli sono
molti e non tutti
hanno sempre la lucidità di usarli, spesso se ci si lavora sopra da
troppo tempo.
A Bruno poi scrivere tanto codice piace....!
@Alex

 Sib
Ho visto di che pasta sei fatto.
Sto lanciando una sfida, non cerco qualcuno che faccia il
lavoro che ho già fatto.
Quando avrai creato un algoritmo che dalla sua esecuzione
con carta e matita sia traducibile in un codice più compatto di
quello che ho scritto te ne renderò merito.
Hai perso un'occasione, io le scommesse le perdo sempre.
Vado a lanciare la sfida a Baraldi
Bruno 

Il sistema si basa su una tabella Problema dove si memorizza la parola di 
partenza e la lunghezza degli anagrammi.
Quindi vi è una tabella combinazioni dove vengono conservate le combinazioni 
generate.
Quindi vi è una query che estrapola dalla tabella combinazioni solo quelle 
distinte tra loro.
La funzione Ordinalett serve a ordinare le lettere nelle combinazioni in 
modo da potere successivamente estrapolare solo quelle distinte.
Quello che segue è il codice della maschera che tramite il pulsante GenComb 
genera le combinazioni
Poi tramite il pulsante CalcAna calcola gli anagrammi.
L'unica funzione esterna a questo codice è la funzione fatt() per il calcolo 
del fattoriale che aggiungo in calce:
--------------------------------------
Option Compare Database
Private Sub GenComb_Click()
On Error GoTo Err_GenComb_Click
    If Nz(Me.LungAna, 0) = 0 Or Me.LungAna > Len(Me.Parola) Then
        MsgBox "La lunghezza anagrammi o la parola indicata non sono 
corretti, verificare.", vbCritical, "Impossibile calcolare"
        Exit Sub
    End If
    CurrentProject.Connection.Execute "DELETE * FROM Combinazioni WHERE 
IDProb=" & Me.ID
    CalComb Me.Parola, Me.LungAna, ""
    OrdinaLett
Exit_GenComb_Click:
    Exit Sub
Err_GenComb_Click:
    MsgBox Err.Description
    Resume Exit_GenComb_Click
End Sub
Private Sub OrdinaLett()
Dim rs As ADODB.Recordset
Dim st As String, st1 As String
Dim fI As Boolean
    Set rs = New ADODB.Recordset
    rs.Open "SELECT * FROM Combinazioni WHERE IDProb=" & Me.ID, 
CurrentProject.Connection, adOpenKeyset, adLockOptimistic
    Do While Not rs.EOF
        st1 = rs!Combinazione
        st = Left(st1, 1)
        For i = 2 To Len(st1)
            fI = False
            For j = 1 To Len(st)
                If Mid(st1, i, 1) < Mid(st, j, 1) Then
                    st = Left(st, j - 1) & Mid(st1, i, 1) & Right(st, 
Len(st) - j + 1)
                    fI = True
                    Exit For
                End If
            Next j
            If fI = False Then st = st & Mid(st1, i, 1)
        Next i
        rs!Combinazione = st
        rs.Update
        rs.MoveNext
    Loop
    rs.Close
    Set rs = Nothing
End Sub
Private Function CalComb(st As String, k As Integer, stPrec As String)
If k = 1 Then
    Dim rs As ADODB.Recordset
    Set rs = New ADODB.Recordset
    rs.Open "Combinazioni", CurrentProject.Connection, adOpenKeyset, 
adLockOptimistic
    For i = 1 To Len(st)
        rs.AddNew
        rs!Combinazione = stPrec & Mid(st, i, 1)
        rs!IDProb = Me.ID
        rs.Update
    Next i
    rs.Close
    Set rs = Nothing
Else
    For i = 1 To Len(st)
        CalComb Right(st, Len(st) - i), k - 1, stPrec & Mid(st, i, 1)
    Next i
End If
End Function
Private Sub CalcAna_Click()
On Error GoTo Err_CalcAna_Click
Dim rs As ADODB.Recordset
Dim st As String, st1 As String
Dim iRip(10) As Integer
Dim jRip As Long
Dim iAna As Long
    Set rs = New ADODB.Recordset
    rs.Open "SELECT * FROM CombinazioniDistinte WHERE IDProb=" & Me.ID, 
CurrentProject.Connection, adOpenKeyset, adLockOptimistic
    Do While Not rs.EOF
        st1 = rs!CombinazioneCampo
        st = Left(st1, 1)
        j = 1
        For i = 1 To 10
            iRip(i) = 1
        Next i
        For i = 2 To Len(st1)
            If st = Mid(st1, i, 1) Then
                iRip(j) = iRip(j) + 1
            Else
                st = Mid(st1, i, 1)
                If iRip(j) > 1 Then j = j + 1
            End If
        Next i
        jRip = 1
        For i = 1 To j
            jRip = jRip * Fatt(iRip(i))
        Next i
        iAna = iAna + Fatt(Len(st1)) / jRip
        rs.MoveNext
    Loop
    Me.TotAnagrammi = iAna
    rs.Close
    Set rs = Nothing
Exit_CalcAna_Click:
    Exit Sub
Err_CalcAna_Click:
    MsgBox Err.Description
    Resume Exit_CalcAna_Click
End Sub
----------------------------
Public Function Fatt(i As Integer) As Long
Dim k As Integer
    Fatt = 1
    For k = 2 To i
        Fatt = Fatt * k
    Next k
End Function
Sib
-- 
http://www.gestionedati.com

 wrote in message 
news:1143316904....@i39g2000cwa.googlegroups.com...
Vediamo chi l'ha piů grosso....!!!!
Sono curioso.
(Fosse per me pubblicherei il risultato, ma col cavolo che pubblico il
codice)...!
In ogni caso Davide ritengo tu abbia centrato il problema delle lettere
doppie
che danno di fatto origine a parole doppie pur rientrando correttamente
nella
logica delle combinazioni.
Data questa combinazione:
OOOAACCL
questa č un'altra combinazione:
OOOAACCL
e questa un'altra ancora
OOOAACCL
Le ho ottenute ruotando le O, ma come ben sapete
ne potrei ottenere ben di piů....!
Per questo forse Bruno ha dovuto generarle, ma se invece di fare 45
=====================================
Bruno le ha generate con quattro righe di programma.
Le ha generate per verificare i calcoli fatti con carta e
matita e per verificare il risultato del codice (oltre 200 righe)
scritto per tradurre in programma VBA il procedimento
eseguito con carta e matita.
Ribadisco:
Io le so calcolare senza doverne generare una mezza,
soltanto con carta e  matita; non mi serve nemmeno
la calcolatrice.
Tradurre in codice tale procedimento mi č costato 200
righe di programma.
Mi chiedevo se qualcuno fosse riuscito a farlo in maniera piů
compatta.
Evidentemente no, almeno finora.
Visto che tutti quanti si son fatti in quattro per dirmi come
dovevo generarle.
E generarle prima - in tutto o in parte - e contarle poi -
direttamente o indirettamente - č una scemenza alla portata di tutti.
Se ti descrivo il procedimento, accetti la sfida di scriverne
un codice piů compatto?
Su questo punto perň non son disposto a giocarmi molto.
E poi debbo pensarci; voglio divertirmi ancora un po'.
Bruno

 partenza e la lunghezza degli anagrammi.
[...]
Ora non ho tempo di esaminare il tuo programma; mi riprometto
di farlo durante la notte (sono un nottambulo).
Dimmi solo quanti sono gli anagrammi di 8 lettere di
 "ANATROCCOLO", al netto delle duplicazioni.
Bruno 

 ha scritto nel messaggio 
news:4425bf3e$0$29721$4faf...@reader2.news.tin.it...

356160
Sib
-- 
http://www.gestionedati.com
 

 356160
Č esatto.
Ma non č ciň per cui avevo posto il quesito.
Comunque esaminerň il tuo programma.
Cosě a occhio mi sembra quasi il doppio del mio.
Bruno 

 Bruno
Beh ma i complimenti per la velocità debbo farteli.
Sei stato un razzo, veramente.
Bruno 

 Cosě a occhio mi sembra quasi il doppio del mio.
Dici?
Non conosco il tuo codice, ma non trascurare che il mio č integrato in una 
maschera e incorpora la gestione degli errori.
Sib
-- 
http://www.gestionedati.com
 

 partenza e la lunghezza degli anagrammi.
Ritiro tutti i complimenti.
Ma come si fa a confezionare così un programma dimostrativo?
- Variabili non dichiarate
- 6 oggetti in una scheda, la metà dei quali è da indovinare
- gestione di errore che dà errore quando errore non c'è
- gestione d'errore che mostra l'Err.Description ma non ti dice
   dove si è verificato. Non è meglio lasciar fare ad Access?
- tabella Problema che non si sa cosa sia
- query o tabella CombinazioniDistinte mancante
- due pulsanti da azionare quando ne bastava uno
- 10 Me che si possono tutti omettere
- una tabella da creare (Combinazioni) per la quale occorre
  andare in giro per il codice per capire quali sono i campi
Sono inorridito.
Bruno

Ma che vogliamo fare...?
Senti Bruno, ma il nocciolo non era risolvere il problema...?
Se si fanno appunti sul codice di altri sarebbe bene farli a ragion
veduta...!
Non voglio prendere forzatamente le parti di Davide, che è in grado di
difendersi
anche se non credo sia questo il caso data l'assurdità della cosa, ma
se proprio
vogliamo parlare di codice ben scritto ci sarebbe molto da ridire anche
su quanto
tu stesso hai pubblicato nel SC
(cito la FAQ 6.134 Come contare tutti gli oggetti e tutte le righe di
codice del database corrente)
, che veramente vomita ridondanze assurde e un prolificare di cicli
decisamente poco utili...., se poi tu fossi un programmatore di C o C++
sapresti che l'uso del ME non è una pippata in quanto è un
riferimento alla classe, chi ha
imparato solo a smacchinare con un pò di VBA certe completezze non le
ha, ma questo
non significa sia più furbo...., per non parlare poi di quando volevi
ciclare un Array per duplicarlo.... ricordi vero le
cazzate che volevi sostenere addirittura dicendo che IO non sapevo
cos'era un Array
e che poi non hai nemmeno avuto il coraggio di ammettere di aver
sbrodolato sentenze
inutilmente ed aver fatto una figura del cavolo.....!!!
Bene visto il modo con cui ti rivolgi al NG volevo ricordare
pubblicamente che
di cose da inorridire ne hai dette e fatte molte anche tu, ma che
probabilmente
con un pò di esperienza hai migliorato......(spero)
Insomma Bruno, stai un pò tranquillo e non essere sempre sulla
difensiva come se
il mondo fosse contro di te....!
Ora visto che l'obiettivo non è chi scrive meglio o di contestare
l'operato di altri
e visto che tu ti sei rivolto in un'area pubblica per risolvere il
problema cerchiamo
di non fare gare stupide di chi piscia più lontano....!!!
Un saluto ed una buona domenica.
@Alex

 wrote in message 
news:1143373156.2...@j33g2000cwa.googlegroups.com...
Ma che vogliamo fare...?
Senti Bruno, ma il nocciolo non era risolvere il problema...?
Se si fanno appunti sul codice di altri sarebbe bene farli a ragion
veduta...!
=========================================
Intanto impara ad usare con criterio il tuo mailer, ché non si
debba essere costretti ad evidenziare la risposta dal testo.
La "ragion veduta" è, nella circostanza, l'opinione personale.
Scrivere codice è per me un'arte.
E mi arrogo il diritto, come chiunque altro, di inorridire davanti a
Giuseppe  Ungaretti, davanti a Luigi Nono, davanti a Piccasso
perché i miei modelli sono piuttosto Dante, Beethoven e
Raffaello rispettivamente.
Che la mia "arte" sia criticabile io l'accetto senza scompormi;
certo che non mi fa piacere, e a chi lo farebbe?
Però criticare per ripicca in occasione di una difesa che si
vuol prendere di altri è cosa che fa solo sorridere.
Fa' le tue critiche al momento opportuno e su dati di fatto
(codice alla mano).
Imbastire una serena discussione fa solo bene alla salute,
e completa, e rafforza  le proprie cognizioni in materia.
Altrettanto buona domenica
Bruno

Purtroppo rispondo con Google, e vorrà dire che sarai costretto ad
usare la tua "intelligenza" per capire....!
Visto che forse hai frainteso, ripeto che non siamo quì per criticare
l'operato di altri che ci aiutano, perchè se fosse così come ti ho
già sottolineato
tu scrivi codice discutibile(ed uso un eufemismo) come ho citato(che ti
faccia piacere o meno
sentirtelo dire), oltre che avere grosse lacune tecniche che
probabilmente
ti complessano un pò.....!
Se invece di metterti sulla difensiva imparassi a metterti in
discussione e pensare che
tecnicamente hai limiti evidenti, forse potresti imparare da chi ti dà
suggerimenti invece
che contraddirli sempre per principio, e bada che questo detto da chi
ha quasi la metà dei tui
anni dovrebbe anche farti riflettere.........
Saluti
@Alex

 wrote in message 
news:1143381907.8...@i40g2000cwc.googlegroups.com...



[Risposta]
=============================
Mi farò scrupolo di evidenziare con sollecitudine
quanto, a mio giudizio, nel tuo codice cozza contro i criteri
del buono stile e della funzionalità.
Se farai lo stesso con me cresceremo assieme.
E non ti propinerò battute di bassa lega...
Bruno

Se invece di metterti sulla difensiva imparassi a metterti in
discussione e pensare che
tecnicamente hai limiti evidenti, forse potresti imparare da chi ti dà
suggerimenti invece
che contraddirli sempre per principio, e bada che questo detto da chi
ha quasi la metà dei tui
anni dovrebbe anche farti riflettere.........
Ma come fai a sapere quanti anni ha?     ;-)
Ciao, Simone

 Sono inorridito.
Ciao Bruno.
Stiamo facendo a chi lo ha piu' grosso vedo.
Cmq pur avendo da fare mi sono cimentato anch'io nell'affare,
non il conteggio ma la generazione di anagrammi.
Il mio ha un grosso limite, fa esplodere il pc.
Ho provato fino a nove lettere poi ho rinunciato (i tempi e lo spazio)
Cmq questo e' il codice
Su otto lettere tutte diverse sul mio pc ci ha messo circa 40 sec
(su 8 lettere sono comunque il massimo ottenibile se non mi sbaglio)
E' solo per partecipare ;<)
A me piace la maesta' di Duccio, pochi fronzoli e via
Private Sub bOk_Click()
Dim oColl As New Collection
Dim oAns As New clsAnagramma
     DoCmd.Hourglass True
     tt1 = Format(Now, "hh.mm.ss")
     tt2 = ""
     DoEvents
     oAns.Generate oColl, tParola, 1, tLung
     DoCmd.Hourglass False
     tt2 = Format(Now, "hh.mm.ss")
     tNum = oColl.Count
     Set oAns = Nothing
     Set oColl = Nothing
End Sub
--
questo sta dietro un form in cui imposto i parametri e rilevo i tempi di 
esecuzione
oColl e' la collezione con gli anagrammi
tParola e' la parola da anagrammare
1 e' il livello di profondita'
tLung e' la Lunghezza di anagramma voluta
----
Option Compare Database
Option Explicit
Dim zItems As New Collection
Dim Child As New Collection
Private Sub Class_Initialize()
zItems.Add "", "Posizione"
zItems.Add "", "Valore"
End Sub
Function setChild(pp As Variant)
     Child.Add pp, pp.Valore
End Function
Function getChild(pp As String)
     Set getChild = Child(pp)
End Function
Property Let Valore(pp As String)
     zItems.Remove "Valore"
     zItems.Add pp, "Valore"
End Property
Property Get Valore() As String
     Valore = zItems("Valore")
End Property
Property Let Posizione(pp As String)
     zItems.Remove "Posizione"
     zItems.Add pp, "Posizione"
End Property
Property Get Posizione() As String
     Posizione = zItems("Posizione")
End Property
Function Generate(ByRef pCount As Long, oColl As Collection, ByRef ps As 
String, pL As Integer, pLun)
Dim ix As Integer
Dim sAna As String
Dim oL As clsAnagramma
On Error Resume Next
If pL > Len(ps) Then Exit Function
For ix = 1 To Len(ps)
     Set oL = New clsAnagramma
     oL.Valore = Valore & Mid(ps, ix, 1)
     If Len(oL.Valore) = pLun Then oColl.Add oL.Valore, oL.Valore
     oL.Posizione = Posizione & ix & "-"
     If InStr(Posizione, ix & "-") = 0 Then
         oL.Generate  oColl, ps, pL + 1, pLun
         setChild oL
     End If
Next
End Function
Cmq e' stato divertente e per favore non vi incazzate. E' PRIMAVERA!
--
ac

Conosco Bruno per motivi di scambi passati da qualche anno, mica
credevi
fossi veggente...?
;-)
@Alex

Mi farò scrupolo di evidenziare con sollecitudine
quanto, a mio giudizio, nel tuo codice cozza contro i criteri
del buono stile e della funzionalità.
Se farai lo stesso con me cresceremo assieme.
E non ti propinerò battute di bassa lega...
[RISPOSTA]
Ormai dovresti sapere che nonostante io dica quello che penso sempre e
comunque
indipendentemente dal corrispondente sono sempre disponibile per
relazionarmi tecnicamente
e credo di averti dato prova di ciò più di una volta, quindi ben
venga lo spirito critico volto
alla crescita... e bada che ho detto alla crescita e non alla sfida...!
Lungi da me le battute, quando le faccio è solo per scherzare, ma
quando non scherzo, cioè quando affronto tecnicamente una cosa
preferisco pormi sul piano puramente tecnico e non ironico.
Ciao
@Alex

 ;-)
La cosa non mi sorprenderebbe!    :-)
Ciao, Simone

 Function Generate(ByRef pCount As Long, oColl As Collection, ByRef ps As 
Function Generate( oColl As Collection, ByRef ps As
--
ac

 Sono inorridito.
Dati i tuoi commenti lo prendo per un complimento
Sembra quasi ti dia fastidio che in 25 minuti abbia risolto il tuo problema.
Sib
-- 
http://www.gestionedati.com
 

 Sib
Ti avevo fatto i complimenti per la velocità.
Io ci ho lavorato per parecchie ore prima di infilare il verso giusto.
Che non è, secondo me, la via da te seguita; la quale comunque
dà risultati corretti.
Mentre ho impiegato circa tre giorni per poterli solo "contare" nel
senso già ripetutamente enunciato.
Mi spiace che non accetti le critiche al tuo operato.
Io son disposto ad accettarne sul mio e son pronto a discuterne.
E son pronto a proporre ed accettare sfide quando mi accorgo
che alla dialettica si oppone un muro di incomunicabilità.
Ora, poiché ti ostini a sostenere di aver risolto il "mio problema"
mentre ancora non hai capito quale esso sia (il muro di incomunicabilità
di cui sopra), né hai ritenuto di dover accettare la sfida che ti
avevo proposto (giustamente, soggiungo, non avendo afferrato il
senso del bibattere), non mi resta altro da fare che catalogarti fra coloro
coi quali non riesco a comunicare e cercare di viaggiare
parallelamente alla tua via.
E non pensare voglia serbarti rancore: ho settant'anni suonati
(così soddisfo anche qualche curiosità) e ti garantisco che
né i miei sonni né le mie veglie risentono di alcun
turbamento per la tua esistenza.
Bruno 

 A me piace la maesta' di Duccio, pochi fronzoli e via
Questa sera (dovrei dire questa notte) provo il tuo programma.
Intanto qualche premessa.
Gli anagrammi di 6 lettere di "ABCDEFGHIJ" sono D10,6
(disposizioni di 10 lettere prese 6 a 6) dove
D10,6 = 10*9*8*7*6*5 = 151200.
Va da sé che D10,10 = P10 = 10! = 3628800
È sufficiente una delle tante routine per il calcolo combinatorio
che si trovano in  rete per generare tali anagrammi.
Mentre per solo contarli basta Dn,k.
Se avessinmo invece "AAAABBBCDE" dovremmo
seguire lo stesso procedimento di generazione di cui sopra
indi filtrare i doppioni con una query.
Questa mi pare la via più semplice; tanto semplice che
è addirittuta banale. Quattro righe di codice!
Una volta generati li sappiamo anche contare, è evidente!
Ma li sappiamo contare senza generarli?
Una formula del tipo Dn,k  NON ESISTE!
Questo è il problema per risolvere il quale ho impiegato
200 linee di codice e tre giorni di tempo.
Finora l'unica soluzione è la mia.
Altre non ne ho viste.
Debbo ancora vedere la tua, ma mi pare tu abbia
premesso esserti cimentato sulla generazione piuttosto
che sulla conta.
Ciao
Bruno

 turbamento per la tua esistenza.
Figurati se invece io mi turbo.
Solo che, comprendo che superata una certa età (di cui credimi ho pieno 
rispetto) si perde un po' di umiltà, ma quando si muovo critiche bisogna 
essere certi di quello che si dice.
Anch'io talvolta preso dall'impulso criticherei a vista determinate 
affermazioni, ma anche se mi sento certo mi documento prima.
Sib 

 Altre non ne ho viste.
Mah, detto così suona come una sfida: ma a che scopo?
Ciao, Simone

 La sfida l'ho già vinta.
Mi sembra di sentire Berlusconi!
Bruno 

 Mah, detto così suona come una sfida: ma a che scopo?
Lo scopo era di vedere se esisteva un metodo migliore di quello
che mi sembrava assurdamente lungo (200 righe di codice).
Pare non esista. Né migliore né peggiore.
Suona come una sfida? E allora?
A che scopo si fa una partita a scacchi per perderla?
Una partita a tennis? Una corsa ad ostacoli?
Ora che il tutto appare chiaro qualcuno si vuol cimentare?
Qualcuno vuole accettare la sfida?
O si preferisce far chiacchiere su chiacchiere?
Non dovrei parlar così con te che appari l'unico
aver inteso il problema.
Ti chiedo venia.
Ciao
Bruno

 
[cut]
Scusami non avevo visto la risposta facendo dei test mi sono accorto di 
un errore: c'e' un if malmessa
For ix = 1 To Len(ps)
     Set oL = New clsAnagramma
     oL.Valore = Valore & Mid(ps, ix, 1)
   '-----spostata
     oL.Posizione = Posizione & ix & "-"
     If InStr(Posizione, ix & "-") = 0 Then
	If Len(oL.Valore) = pLun Then oColl.Add oL.Valore, oL.Valore
         oL.Generate  oColl, ps, pL + 1, pLun
         setChild oL
     End If
Next
ho fatto inoltre una  piccola variazione qui:
Private Sub Class_Initialize()
zItems.Add "", "Posizione"
zItems.Add "", "Valore"
End Sub
Function setChild(pp As Variant)
     Child.Add pp, pp.Valore
End Function
Function getChild(pp As String)
     Set getChild = Child(pp)
End Function
avevo scritto inoltre che:
....
su 8 lettere sono comunque il massimo ottenibile se non mi sbaglio
....
solenne bischerata
cmq quelle sono meno di 200 righe e c'e anche qualcosa che non uso 
(getChild) fino n=9 l'ho provata e sembra andare  ;<)
Tra l'altro calcolare il numero degli anagrammi per k=n e k=n-1 al netto 
delle duplicazioni mi sembra si possa ottenere facilmente (e lo stesso 
dicasi per k=2) e' da k=3 a k=n-2 che e' un casino, almeno per me che 
conosco solo l'aritmetica
--
ac

 Mi sembra di sentire Berlusconi!
Sono di sinistra.
Sib
-- 
http://www.gestionedati.com
 

>> Altre non ne ho viste.
Certo bruno che sei uno che se la tira veramente alla grande.
A parte che il mio codice č lungo meno di 120 righe (e ho contato anche le 
righe bianche), non ci hai fatto neanche vedere il grande software che hai 
scritto tu di "sole" 200 righe (non ti premurare di postarlo che tanto non 
mi interessa).
il mio programma funziona benissimo, non contiene errori, lavora col massimo 
dell'efficienza (mi genera senza problemi e senza errori gli anagrammi di 12 
lettere o piů della parola "supercalifragilistichespiralidoso",
il tutto in poco piů di 100 righe di codice scritte in 25 minuti
Tutto il resto, caro bruno, č aria fritta.
Buona fortuna
Sib
-- 
http://www.gestionedati.com
 

 conosco solo l'aritmetica
Io lo so calcolare, con una semplice formula, solo per
k=n (permutazioni) e per k=1.
Per valori intermedi devo fare vari passaggi con carta e matita
e stare molto attento a non sbagliare.
Hai trovato una formula per k=n-1 e per k=2?
Per me č quasi una scoperta; me la mostreresti?
Bruno 

 conosco solo l'aritmetica
per k=n non hai altro che:
n! / (r1!*r2!*...)
dove r1, r2, ecc sono le ripetizioni delle lettere, per ANATROCCOLO hai:
11! / (2!*2!*3!) = 1.663.200 anagrammi diversi
non esiste formula per anagrammi di lunghezza minore per un semplice motivo, 
perchč non esiste formula matematica che possa tenere conto delle lettere 
che si ripetono, devi contarle tu.
O meglio, forse puoi provare a sviluppare una formula che ne tenga conto, ma 
non č certo agevole.
Se usi k=n-1 hai 11 combinazioni e diciamo che puoi agevolmente prevedere 
che ci saranno 2 corrispondenze per le a, 2 per le c e tre per le o, quindi 
avrai 7 combinazioni distinte.
A questo punto perņ devi tener conto delle ripetizioni presenti in queste 
combinazioni.
Sib 

 Ti chiedo venia.
Posto che questa sia una sfida: convieni che si tratta di una problematica
OT in un'area usenet in cui si parla di programmazione di DataBase?
Comunque se lo scopo è ottenere una formuletta ad-hoc, dubito sia possibile:
non pare formalizzabile il concetto di "doppione".
Per quanto concerne la soluzione che hai ideato tu (e l'obiettivo di
migliorarla), dovresti anzitutto postarla e vedere cosa ne pensano gli
altri.
Certo, ammesso che siano interessati ... e secondo me in quest'area siamo
OT.
Ciao, Simone

 OT.
Stricto sensu, sì.
Beh, alla prossima allora.
Ciao
Bruno 

 Per me è quasi una scoperta; me la mostreresti?
Premessa:
Quando dico che conosco solo i 4 operatori aritmetici lo dico sul serio.
Il codice che ho scritto mi "sembra" corretto, nel senso che ho
verificato a  occhio per n da 1 a 4 e poi ho fatto il calcolo n! per n=8
ed i numeri "sembrano" tornare.
Per la questione del k=2 ho "previsto" i risultati per n= 6,7,8
ed il programma me li ha riscontrati
detto 1d una duplicazione (aa) e 2d una triplicaione (aaa) and so on e
detto u il numero di lettere "utili" e detto t il totale di combinazioni
ed nd il numero di duplicazioni
ho questa strana formuletta
t = u*u-1 + nd
i.e.
se n=8 e 1d1d
t= 6*5 + 2
se n=8 e 2d
t=6 * 5 + 1
se 1d1d1d
t = 5*4 + 3
and so on
per il k=n-1 mi sono sbilanciato troppo nel senso che prima di affermare
qualcosa in modo "certo" dovrei verificarlo "moooolto" bene, tra l'altro
per k=3 fino a k=n-2 c'e' un "crivello"  molto interessante per il
momento ho "azzeccato" qualche numero
per quanto riguarda il codice:
1) dietro il form. Fondamentalmente mi serve per ricevere i parametri e
definire le strutture di base:
Private Sub bOk_Click()
Dim oColl As New Collection
Dim nCount As Long
Dim oAns As New clsAnagramma
     DoCmd.Hourglass True
     tt1 = Format(Now, "hh.mm.ss")
     tt2 = ""
     DoEvents
     oAns.Generate nCount, oColl, tParola, 1, tLung
     tt2 = Format(Now, "hh.mm.ss")
     DoEvents
     tNum = oColl.Count
     Set oAns = Nothing
     Set oColl = Nothing
     '  ce ne sono due perche' il sistema ci mette un po' a distruggere
gli oggetti (immagino oAns)
     tt2 = Format(Now, "hh.mm.ss")
     DoCmd.Hourglass False
End Sub
Parametri di chiamate "Generate"
a) nCount (non serve)
b) oColl = collezione dove vengono accumulati gli anagrammi di tLung
lunghezza
c) tParola: la parola da anagrammare
d) tLung = il k da considerare
------
2) La classe per la generazione degli anagrammi:
Option Compare Database
Option Explicit
Dim zItems As New Collection
Dim Child As New Collection
Private Sub Class_Initialize()
zItems.Add "", "Posizione"
zItems.Add "", "Valore"
End Sub
Function setChild(pp As Variant)
     Child.Add pp, pp.Valore
End Function
Function getChild(pp As String)
     Set getChild = Child(pp)
End Function
Property Let Valore(pp As String)
     zItems.Remove "Valore"
     zItems.Add pp, "Valore"
End Property
Property Get Valore() As String
     Valore = zItems("Valore")
End Property
Property Let Posizione(pp As String)
     zItems.Remove "Posizione"
     zItems.Add pp, "Posizione"
End Property
Property Get Posizione() As String
     Posizione = zItems("Posizione")
End Property
Function Generate(ByRef pCount As Long, oColl As Collection, ByRef ps As
String, pL As Integer, pLun)
Dim ix As Integer
Dim sAna As String
Dim oL As clsAnagramma
On Error Resume Next
If pL > Len(ps) Then Exit Function
For ix = 1 To Len(ps)
     Set oL = New clsAnagramma
     oL.Valore = Valore & Mid(ps, ix, 1)
     oL.Posizione = Posizione & ix & "-"
     If InStr(Posizione, ix & "-") = 0 Then
         If Len(oL.Valore) = pLun Then
             oColl.Add oL.Valore, oL.Valore
'            pCount = pCount + 1
         End If
         oL.Generate pCount, oColl, ps, pL + 1, pLun
         setChild oL
     End If
Next
End Function
ho lasciato il parametro pCount ma di fatto non serve, le tre istruzioni
sotto la for forse vanno meglio sotto la if. Se nel programma non ci
sono errori le mie "considerazioni" matematiche sono corrette
altrimenti: no ;<)
Per scrivere il codice e testarlo ci ho messo piu' di 25min (parecchio
di piu').
--
ac


Dallo sviluppo successivo immagino avresti voluto
scrivere:
t = u * (u - 1) + nd; ti sono scappate due parentesi.
Perň non capisco.
Se S = "AAABBCDE"
u = 5
1id + 2d = 3d
t = 5*4 + 3 = 23
Manca la classe della combinazione, il k, laddove
in Cn,k sta ad indicare che gli n elementi sono
presi k a k.
Non ho potuto provare il tuo programma perché mi ha dato subito
errore di variabile non dichiarata, poi di ByRef su tParola.
Io coi Class Module non ci vado a nozze, anzi ci faccio proprio a pugni,
ragion per cui ho subito abbandonato.
Comunque puoi verificare tu, ti faccio alcuni esempi:
S = "ANATROCCOLO", k = 8,  NumAnagr  356160
S = "CAMMELLO", k = 5               "        "        2040
S = "CRETINETTI", k = 6               "        "       11130
S = "MOLLA", k = 3,                      "         "            33
Ciao
Bruno

 ragion per cui ho subito abbandonato.
avevo specificato che un pezzo di codice era dietro un form.
tParola e' una textbox di form se vuoi ti mando l'mdb con anche il form
(tutti i nomi che cominciano con "t" sono textbox di form)
ok per i dati adesso vedo se mi corrispondono
--
ac

 wrote in message 
news:_3bWf.36785$nz4....@tornado.fastwebnet.it...

Ero arrivato a tt1 e tt2 soltanto...
Ti sarei grato m'inviassi l'mdb.
Il mio indirizzo, quale si desume dal NG, è corretto.
Bruno

 t = 5*4 + 3 = 23
no intendevo un'altra cosa
AAABBCDE e' di tipo 1d2d (sono 2 elementi)
t= 5*4 + 2 = 22
se fosse
AABBCCDE  tipo 1d1d1d (3 elementi)
allora : 5*4 + 3 = 23
ho riscontrato CAMMELLO e MOLLA mi tornano (gli altri sono troppo lunghi
e al momento per questioni di spaziotempo preferisco evitare)
credo invece che se mi tornano alcuni conti sarei in grado di calcolare
almeno il 50% delle combinazioni (c'e' ancora una regola che mi sfugge)
cmq a me risulta che le combinazioni k=n-1 siano uguali a quelle di n=k
	k1	k2	k3	k4	k5	k6	k7	k8
0d	8	56	336	1680	6720	20160	40320	40320
1d	7	43	228	*1044	*4045	*13314	20160	
2d	6	31	136	500	*1545	*4044	6720	
3d	5	21	73	209	500	*1044	1680	
4d	4	13	34	73	136	228	336	
5d	3	7	13	21	31	43	56	
6d	2	3	4	5	6	7	8	
7d	1	1	1	1	1	1	1	1
				1020	3720	10440		
					1520	3720		
						1020		
In questa griglia i dati sono "calcolati". Quelli marcati con * sono 
errati i valori veri sono quelli riportati in basso (1020 etc) tra 
l'altro come puoi notare c'e' una certa simmetricita'. Questo solo per 
il tipo di duplicazione od -->(n-1)d come vedi quelli che non sono 
riuscito a calcolare sono al di sopra della diagonale mediana. Non ho 
ancora affrontato le griglie con diverso tipo di duplicazione ma diamo 
tempo al tempo ;<)
			1d		1d1d
0d	40320		20160		10080
1d	20160		10080		5040
2d	6720		3360		1680
3d	1680		840		420
4d	336		168		
5d	56		28		
6d	8				
7d	1				
Questi inoltre sono i numeri calcolati (s.e. & o) per n=8 e k=7,8
a seconda delle duplicazioni
[cut]

 Ti sarei grato m'inviassi l'mdb.
fatto.
Attenzione con n=8 sul mio pc [Pentium 4, 512Mb] ci mette circa 30sec
con n=9 circa 3/4min. Non ti consiglierei di usarlo oltre poiche' tiene 
tutto in memoria. Con "ANATROCCOLO" non so proprio quanto possa metterci.
--
ac

 AAABBCDE e' di tipo 1d2d (sono 2 elementi)
[...]
Mi sono stampato tutto perché voglio studiarmi la tua teoria.
Ho provato il tuo programma il quale ha funzionato
perfettamente su una quindicina di esperimenti.
Ho provato con un n=10, k=6 ma dopo 20 minuti ho
staccato.
Non mi spiego come possa essere così lento in certe
circostanze. Il Task Manager mi dava un utilizzo di
CPU del 50% che non è nemmeno un'esagerazione e
la RAM usata era sui 300 Mbyte.
Il codice anche mi sembra molto compatto. Dico mi
sembra perché in verità non sono ancora riuscito a capirne
la logica.
Ciao
Bruno 

 la logica.
uhmmm..  se vuoi capirne la logica dovresti fare una cosa
Andare in debug e mettere un breakpoint sulla prima istruzione :
     tt2 = Format(Now, "hh.mm.ss")
e poi aprire la finestra delle variabili e aprire l'oggetto oAns e 
cominciare poi ad aprire la "scatola" Child e poi aprire anche la 
scatola oColl (di cui potrebbe non esserci bisogno se si vuole solo il 
numero). Comunque ho anche un foglio excel che ho fatto in cui ci sono 
alcune formule di calcolo che "bypassano" la necessita' di elaborare gli 
anagrammi. C'e' ancora qualche regola che non mi e' chiara ma, come dico 
spesso, "i disegni da qualche parte devono pure esserci"
Tra l'altro e' possibile implementare una routine (il nome gia' c'era 
"Evaluate") per il calcolo "contemporaneo" di tutti i totali per tutti i 
possibili k. E' una cosa di poche istruzioni ma che ho tralasciato 
proprio perche' penso che il modo di calcolarli da qualche parte c'e'.
Ah... se ti interessa il foglio excel posso mandartelo.
--
ac

 Ah... se ti interessa il foglio excel posso mandartelo.
Sì, m'interessa, grazie.
Mi sono studiato la tua teoria ma non sono riuscito ad andare oltre,
nel senso di trovare nello sviluppo degli anagrammi uniformità che
deponessero per una legge di formazione del loro numero meno
impervia di quella che ho tradotto nelle 200 righe...
Una cosa mi hai fatto notare: che Dn,n = Dn,n-1.
Infatti Dn,n contiene tutti i fattori di Dn,n-1, più 1; il che non
cambia proprio nulla (D5,5=5*4*3*2*1; D5,4=5*4*3*2).
Ho trovato un australiano (?) che con lo stesso procedimento
ha realizzato, in 50 righe di Perl, un programma che in 6o millisec
determina il numero degli anagrammi di 1,2, ...11 lettere ottenibili
da ANATROCCOLO.  Purtroppo io non so leggere il Perl.
Gli ho chiesto lumi su alcuni passaggi di traduzione dell'algoritmo
in codice; passaggi che io ho trovato alquanto complicati.
Non mi ha ancora risposto.
Tu conosci il Perl?
Bruno

 Tu conosci il Perl?
L'ho visto da lontano. Ma credo sia un linguaggio come un altro.
Per il foglio Excel. Sto aggiustando alcune cose fatto cio' te lo mando, 
cosi' come' rischia di essere poco utile perche' da quando ho postato 
l'ho incasinato un po'.
Se mi vuoi mandare il Perl posso provare a dargli un'occhiata.
--
ac

 wrote in message 
news:V8UWf.41682$nz4....@tornado.fastwebnet.it...

Eccolo qui:
=========================================
#!/usr/bin/perl
#  Calculate the number of anagrams of a word.  --  Fred Curtis 2006-03-29
use strict;
use warnings;
my $word = 'ANATROCCOLO';
my @letters = split(//, $word);
my $n_letter = scalar(@letters);
# How many of each distinct letter are there?
#   e.g. ANATROCCOLO -> OOOAACCLNTR -> 3 2 2 1 1 1 1
#
my @letter_count;
{ my %h; map { $h{$_}++ } @letters; @letter_count = values %h; }
foreach my $anag_length (1..$n_letter) {
  my $n_anag = count_anag($anag_length, [], $anag_length, $n_letter, 
\@letter_count);
  print "There are $n_anag $anag_length-letter anagrams of '$word'\n";
}
sub count_anag {
  my ($anag_length, $selected, $n_to_choose, $n_unselected, $unselected) = 
@_;
  return 0
    if ($n_to_choose < 0 || $n_to_choose > $n_unselected);
  if ($n_to_choose > 0) {
    my $total_anag = 0;
    my @new_unselected = @{$unselected};
    die("Error - empty \@new_unselected")
      if (scalar(@new_unselected) < 1);
    my $n_chosen_letter = pop(@new_unselected);
    my $new_n_unselected = $n_unselected - $n_chosen_letter;
    foreach my $n (0..$n_chosen_letter) {
      $total_anag += count_anag($anag_length, [@{$selected}, $n], 
$n_to_choose - $n, $new_n_unselected, \@new_unselected);
    }
    return $total_anag;
  }
  ##  $n_to_choose is 0 -- We chose exactly enough letters to make an 
anagram
  my $result = fac($anag_length);
  map { $result /= fac($_) } @{$selected};
  return $result;
}
sub fac {
  my($n) = @_;
  return ($n <= 1) ? 1 : $n * fac($n-1);
}
===============================================Se vuoi vedere il thread:NG: 
aus.mathematics (
news.tin.it
)Thread:        Anagrams, Bruno Campanini 
25-03-06 17:44Intervento:    Fred CurtisCiaoBruno 

Non ti sei nemmeno accorto che usa una funzione ricorsiva, ma forse non
sai cos'è la ricorsione....!!!
Pirla altrochè Pearl
@Alex

 wrote in message 
news:1143741643....@j33g2000cwa.googlegroups.com...

Pirla altrochè Pearl
@Alex
------------------------------------------------------------------
So che cos'è la ricorsività.
Per la ricorsione non so che dirti: nel dizionario della lingua
italiana non c'è.
A dire il vero non c'è nemmeno "altrochè".
Beh ma vedo che hai raffredato un po' i bollenti spiriti.
Avevo frainteso pensando non volessi più rivolgermi la parola;
meglio così, le incazzature non fanno molto bene alle coronarie.
Io comunque le critiche le accetto, obtorto collo ma le accetto
nel modo più dignitoso possibile, specie se non accompagnate
da insulti.
Comunque sono proprio contento che all'incazzatura ti sia
subentrata l'ironia, dico sul serio, non sto facendo del sarcasmo.
Vedi, sarebbe facile farsi prendere dall'incazzatura (e tre, non
sono aduso a simile linguaggio!) e rispoderti conseguentemente.
E forse qualche strumento dialettico in più l'avrei anche.
Ma a che pro?
Resta con noi (non è pluralis maiestatis, intendevo dire con me e
con Alessandro) e dacci una mano a tradurre quel Perl in VB.
Tu Alessandro che dici?
Bruno

So che cos'è la ricorsività.
Per la ricorsione non so che dirti: nel dizionario della lingua
italiana non c'è.
[Risposta]
Sai non essendo così acculturato putroppo spesso mi accade, ma
ti assicuro che se dici ad un programmatore quella parola non c'è
dubbio che capisca e perdona l'ignoranza ma non stiamo scrivendo un
tema, quindi mi prendo le licenze poetiche ...!
A dire il vero non c'è nemmeno "altrochè".
Beh ma vedo che hai raffredato un po' i bollenti spiriti.
Avevo frainteso pensando non volessi più rivolgermi la parola;
meglio così, le incazzature non fanno molto bene alle coronarie.
[Risposta]
No, non mi sono incazzato, nemmeno un pò, ho solo espresso
in modo colorito le mie considerazioni nei tuoi confronti come
programmatore.
Io comunque le critiche le accetto, obtorto collo ma le accetto
nel modo più dignitoso possibile, specie se non accompagnate
da insulti.
Comunque sono proprio contento che all'incazzatura ti sia
subentrata l'ironia, dico sul serio, non sto facendo del sarcasmo.
Vedi, sarebbe facile farsi prendere dall'incazzatura (e tre, non
sono aduso a simile linguaggio!) e rispoderti conseguentemente.
E forse qualche strumento dialettico in più l'avrei anche.
Ma a che pro?
Resta con noi (non è pluralis maiestatis, intendevo dire con me e
con Alessandro) e dacci una mano a tradurre quel Perl in VB.
[Risposta]
No, ma non perchè non voglio, perchè se non sbaglio non si può, il
Perl(ma saranno 3
anni che no lo guardo e non l'ho mai approfondito) dovrebbe supportare
nativamente la funzione per il calcolo fattoriale cosa che in VB
devi ovviamente fare tu..., quindi è certo che si perde moltissimo, se
poi
lavori in "ricorsione" lo Stack si piega, almeno il mio.
Tu Alessandro che dici?
[Risposta]
Non dico altro, lascio a voi.
Bruno 
Saluti
@Alex

 devi ovviamente fare tu..., quindi è certo che si perde moltissimo, se
uhmmm.....
sub fac {
   my($n) = @_;
   return ($n <= 1) ? 1 : $n * fac($n-1);
}
Qui calcola il fattoriale (fac = factorial?)
sub fac (pn)
  fac = iif(pn<2,1,pn * fac(pn-1))
end sub
oltre count_anag anche questa (fac) e' ricorsiva
--
ac

Si vero mi era sfuggita, proprio non l'ho vista, la funzione ricorsiva
classica per il Fattoriale
tra le altre cose è la stessa di VB.
@Alex

La funzione in Pearl fà esattamente quello che ha detto Davide.
n ! / (s1! * s2! *.... sk!) 
Ciao
@Alex