Per esempio quante parole (diverse) di 8 lettere si possono ottenere
da "ANATROCCOLO"?
Bruno
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.
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
> 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 :-)
I tuoi calcoli sono esatti.
Se non vi fossero doppioni...
Bruno
> 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
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
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
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
[...]
> Veramente per gli anagrammi sul come fare non ci avevo pensato.
> Mi sembrava che a te interessasse solo il numero di anagrammi ottenibili.
Mi interessa vedere altro programma che calcoli il numero degli
anagrammi ottenibili.
Ne calcoli il numero, non li generi.
Generarli č molto semplice: č solo una questione di spazio e di tempo.
> 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
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
> Non è chiaro se ti interessano tutte le combinazioni possibili o solo
> quelle di senso compiuto.
Mi interessano tutte le combinazioni possibili, al netto dei doppioni.
Come ho già detto mi interessa l'algoritmo che ne calcola il numero.
Vorrei confrontarlo col mio che è risultato complicatissimo.
Non mi interessa generare gli anagrammi; mi interessa determinarne
il numero (senza doverli generare prima, ovviamente).
> 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.
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
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
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
Certamente. Una volte generate che ci vuole contarle?
> Non ho ben capito. Ti ci vuole tanto tempo di elaborazione?
Se devi GENERARE qualche milione di stringhe un po' di tempo
ci vuole. Ce ne vuole anche per qualche centinaio di migliaia.
Ma io non voglio GENERARLE, le voglio solo contare senza
doverle generare.
La qual cosa è molto più veloce ma molto più complicata in
termini di codice.
> 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.
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
> Per il calcolo basta una formuletta, non c'è bisogno di algoritmo.
Se basta una formuletta perché non mi dici quanti sono gli
anagrammi di 8 lettere ottenibili da ANATROCCOLO?
> 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?
Non capisco il senso della richiesta.
Comunque OOOAACCL è uno degli anagrammi di 8 lettere
di ANATROCCOLO, diverso da OOOAACLC.
> 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)
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
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
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
> "Sib" <sedav...@SPAMtiscali.it> ha scritto nel messaggio
> CUT
>> la complicazione si ha nel caso degli anagrammi con numero di lettere
>> 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.
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
> 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.
Scusa Bruno, ma perchè sei così pretenzioso?
Ti ricordo che questa è un'area pubblica: nulla è dovuto.
Ciao, Simone
Lo so benissimo.
Pretenderei soltanto di non dover dir le cose tante volte.
Il mio primo post:
"""
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"?
"""
Non presentava alcuna ambiguità; poteva giustificarsi, ad abundantiam,
la domanda se per parole diverse dovessero intendersi quelle con
senso linguistico compiuto. Precisato ciò in senso negativo il
problema era perfettamente determinato.
A questo punto non avrebbe dovuto esserci alcuna risposta.
Visto che nessuno qui conosce la soluzione.
E la cosa non mi stupisce: l'ho chiesto in it.scienza,matematica,
free.it.programmazione.visulbasic e finora nessun intervento.
Proverò anche con microsoft.public.it.office.excel e con
aus.mathematics: quest'ultimo è un NG che non brilla certo per attività
ma vi sono alcuni poster veramente fuori del comune.
Ti ringrazio comunque della partecipazione.
Alla prossima.
Bruno
>
> Ciao, Simone
>
>
Hai generato gli anagrammi?
Perchè mai hai fatto una cosa simile?
Non avevi detto che ti serviva solo sapere quanti fossero?
> 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.
A pagamento ci sono diverse persone qui che possono aiutarti a tempo pieno.
> 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.
Io non ho parlato della loro generazione, devi generare solo le 165
combinazioni, gli anagrammi poi li devi CALCOLARE.
Rileggi un po' qui sotto che mi pare ti sia sfuggito...
>> 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.
Sib
--
http://www.gestionedati.com
> A pagamento ci sono diverse persone qui che possono aiutarti a tempo
> pieno.
>
>> 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.
>
> Io non ho parlato della loro generazione, devi generare solo le 165
> combinazioni, gli anagrammi poi li devi CALCOLARE.
>
> Rileggi un po' qui sotto che mi pare ti sia sfuggito...
>
>>> 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.
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.
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
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
> 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
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
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
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
> Il sistema si basa su una tabella Problema dove si memorizza la parola di
> 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
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
Beh ma i complimenti per la velocità debbo farteli.
Sei stato un razzo, veramente.
Bruno
Veramente avevi chiesto un metodo per calcolare quanti anagrammi potevi fare
e questo, a mio avviso, č il metodo migliore.
> Comunque esaminerň il tuo programma.
> 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
> Il sistema si basa su una tabella Problema dove si memorizza la parola di
> 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
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
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
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
[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
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
;-)
@Alex
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
Per fortuna non ho bisogno dei complimenti di nessuno.
> Ma come si fa a confezionare così un programma dimostrativo?
>
> - Variabili non dichiarate
Secondo te dovevo dichiarare gli integer? Ma non avevi premura di avere una
risposta?
> - 6 oggetti in una scheda, la metà dei quali è da indovinare
Quali oggetti? Cos'è una scheda?
Guarda che se vai a ben leggere si capisce tutto dato che uso nomi
estremamente significativi.
> - gestione di errore che dà errore quando errore non c'è
Di questo dovresti darmi una dimostrazione
> - gestione d'errore che mostra l'Err.Description ma non ti dice
> dove si è verificato. Non è meglio lasciar fare ad Access?
?
Pensavo che dovessi sapere che si lascia fare ad access quando fai il debug
mentre lo gestisci quando bug non ce n'è.
> - tabella Problema che non si sa cosa sia
Cito il mio post:
"Il sistema si basa su una tabella Problema dove si memorizza la parola di
partenza e la lunghezza degli anagrammi."
Ti do un aiutino:
c'è un campo Parola, che come è facilmente intuibile è testo
c'è un campo LungAna (il nome lo capisci dal codice), che come intuisci
facilmente è un numerico
c'è un campo ID (anche questo nome lo capisci dal codice)
> - query o tabella CombinazioniDistinte mancante
SELECT DISTINCT Combinazioni AS CombinazioneCampo FROM Combinazioni
Ma credevo che tu ci fossi riuscito a fare questa query, ma forse ho letto
male il tuo post
> - due pulsanti da azionare quando ne bastava uno
Ti vengono i crampi al dito a fare due click?
> - 10 Me che si possono tutti omettere
io non ometto mai i Me (ma come non ti lamentavi delle variabili implicite?)
Aiutano nella scittura evitando errori di sintassi dei nomi
esplicitano che l'oggetto appartiene alla maschera
Migliora la leggibilità del codice
Mi sta simpatico.
> - una tabella da creare (Combinazioni) per la quale occorre
> andare in giro per il codice per capire quali sono i campi
E mi raccomando di fare attenzione alla complicatissima struttura:
ID
IDProp
Combinazione
>
> 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
> Sembra quasi ti dia fastidio che in 25 minuti abbia risolto il tuo
> problema.
>
> 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
Mi piacerebbe poter fare a chi ce l'ha più duro...
> 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
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
Ci mancherebbe
> 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.
In cosa consisterebbe l'errore?
Generi le combinazioni
Conti i doppioni
Calcoli gli anagrammi.
Non ci sono strade migliori.
> 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.
Le accetto quando hanno senso, le tue hanno solo il senso del tuo sconforto
> 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à.
La sfida l'ho già vinta.
Ma non me ne frega niente, non ci voleva molto.
> 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.
Ma benedetto amico mio, te l'ho detto prima di realizzare la mia
applicazione per il calcolo che il miglior modo di calcolare gli anagrammi
era di generare le combinazioni.
Ti ricordo inoltre che tu hai posto il problema di come calcolare i tuoi
anagrammi senza porre condizioni.
Cito:
"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"?"
> 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.
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
> 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!
Quello che però mi lascia perplesso è lo scopo di questo Thread.
Voglio dire: se tu fossi stato meno parco di dettagli fin dall'inizio,
spiegando specificamente i tuoi scopi e i problemi incontrati (come hai
fatto in questo post), non ci sarebbero stati equivoci.
E non avresti avuto alcuna riposta, dato che una formula per ottenere il
numero di queste particolari Disposizioni, senza generarle, 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.
Mah, detto così suona come una sfida: ma a che scopo?
Ciao, Simone
> In cosa consisterebbe l'errore?
> Generi le combinazioni
> Conti i doppioni
> Calcoli gli anagrammi.
>
> Non ci sono strade migliori.
Non hai ancora capito il problema.
[...]
> La sfida l'ho già vinta.
Mi sembra di sentire Berlusconi!
Bruno
> Quello che però mi lascia perplesso è lo scopo di questo Thread.
>
> Voglio dire: se tu fossi stato meno parco di dettagli fin dall'inizio,
> spiegando specificamente i tuoi scopi e i problemi incontrati (come hai
> fatto in questo post), non ci sarebbero stati equivoci.
Parco forse il mio primo post.
Il secondo, a richiesta di Sib, spiegava già tutto.
> E non avresti avuto alcuna riposta, dato che una formula per ottenere il
> numero di queste particolari Disposizioni, senza generarle, 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.
>
>
> 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
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
A me sembrava di averlo capito benissimo (il "sembrava" è un modo di dire,
in realtà lo so con certezza e, come ripeto, ti avevo detto prima di
iniziare quale strada avrei percorso).
> [...]
>> La sfida l'ho già vinta.
>
> Mi sembra di sentire Berlusconi!
Sono di sinistra.
Sib
--
http://www.gestionedati.com
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
> Scusami non avevo visto la risposta facendo dei test mi sono accorto di un
> errore: c'e' un if malmessa
>
> ho fatto inoltre una piccola variazione qui:
>
[...]
Per quanto concerne il codice forse č meglio se lo ritrasmetti
per intero nella forma riveduta e corretta.
Cosě non corro il rischio di confondermi
> 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
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
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
> > 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.
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
> 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.
Stricto sensu, sì.
Beh, alla prossima allora.
Ciao
Bruno
> Hai trovato una formula per k=n-1 e per k=2?
> 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
> Bruno Campanini wrote:
> [cut]
> Visto che Simone dice che siamo OT mettiamocelo
> 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
>
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
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
Ero arrivato a tt1 e tt2 soltanto...
Ti sarei grato m'inviassi l'mdb.
Il mio indirizzo, quale si desume dal NG, è corretto.
Bruno
>
> Però non capisco.
> Se S = "AAABBCDE"
> u = 5
> 1id + 2d = 3d
> 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]
> Ero arrivato a tt1 e tt2 soltanto...
> 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
> no intendevo un'altra cosa
>
> 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
>
> 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 problema e' che si gira tutte le possibili combinazioni. Non fa
filtraggi particolari. Sicuramente per le performance puo' essere
ottimizzato ma non e' stato quello il mio scopo primario.
Inizialmente erano le 200 righe di codice che mi "perplimevano".
Qualche riga potrei anche toglierla (le Propery) ma diventerebbe meno
leggibile. Il cuore stretto diciamo che potrebbe essere contenuto in una
quarantina di righe.
> Il codice anche mi sembra molto compatto. Dico mi
> sembra perché in verità non sono ancora riuscito a capirne
> 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
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
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
Pirla altrochè Pearl
@Alex
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
[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
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
@Alex
n ! / (s1! * s2! *.... sk!)
Ciao
@Alex