Newsgroup: it.comp.lang.visual-basic
Titolo: domandona VB

ciao a tutti,
Es.
Costruire un quadrato 5x5 caselle sapendo:
-ogni lato e ogni diagonale = 65
-utilizzare numeri da 1 a 25 senza ripeterli.
Questo è il gioco, in sintesi:
come posso dire a VB
di trovarmi quei numeri provando tutte le combinazioni  possibili ?? oltre a
formattare ogni casella per un num. tra 1 e 25 e differente da ognuno??
postatemi in casella.
Grazie.

T. Diego chiede

di postarlo in casella non se ne parla proprio, sorry :)
Prima di tutto diamo un occhiata alle dimensioni del problema:
le possibili permutazioni di 25 numeri, a prescindere dalla difficoltà
dell'algoritmo che le genera, sono 25! (! è il simbolo per il fattoriale, ma
in questo caso è anche un vero esclamativo: 25 fattoriale!! è un numero con
15 zeri!!).
Quindi, niente ricerca esaustiva, almeno per i quadrati magici di ordine 5
(btw: la letteratura in rete sui q.m. è sterminata, dai un'occhiata con
google).
Bisognerebbe esplorare l'albero delle permutazioni 'potando' i rami
sicuramente secchi. Per esempio, se già la prima riga non ha la somma
giusta, è inutile accanirsi.
Quindi quello che suggerisco è un algoritmo basato sulla tecnica di
backtrack: vai avanti finché non ti ficchi in un vicolo cieco, poi torna
indietro di un passo e prova un'altra strada. La maniera più naturale di
implementare questo tipo di esplorazione dell'albero delle permutazioni fa
uso della ricorsione. Ecco una traccia di procedura, devi implementare le
strutture dati e le funzioni Aggiungi, Togli, Possibile, e forse cambiare la
For Each se non usi oggetti che la supportano. Io per esempio ho
implementato al volo tutto con semplici stringhe, e funziona.
Sub Avanti(NumeriInseriti, NumeriRimasti, NumeroDaInserire)
    If NumeriRimasti = NessunNumero Then
      Print Soluzione
    Else
      m_NumeriInseriti = Aggiungi(NumeriInseriti, NumeroDaInserire)
      For Each m_NumeroDaInserire In NumeriRimasti
        If Not Impossibile(m_NumeriInseriti, m_NumeroDaInserire) Then
            m_NumeriRimasti = Togli(NumeriRimasti, m_NumeroDaInserire)
            Avanti m_NumeriInseriti, m_NumeriRimasti, m_NumeroDaInserire
        End If
      Next m_NumeroDaInserire
    End If
End Sub
La funzione va chiamata con:
Call Avanti (NessunNumero, ListaCompleta, NessunNumero)
con i tre parametri che dipendono dalle strutture scelte. Ci sarebbe molto
da dire, ad esempio sull'opportunità di portarsi dietro lo stato del sistema
come parametro anziché usare (orrore!) una variabile globale gestendo il
ripristino dello stato dopo ogni tentativo, e così via. La funzione cruciale
comunque resta la Possibile(): prima si accorge del vicolo cieco, meglio è.
Io con questo approccio basato sul backtrack ho ottenuto risultati davvero
notevoli su it.hobby.enigmi.
Ciao, Silv:o)

 tutte le combinazioni  possibili ?? ...
Questo, a mio avviso, e' l' unico vero problema: TUTTE
le combinazioni possibili di 25 oggetti (nel tuo caso
numeri) sono un po' tante, piu' di 1.5... * 10 ^ 25 !!!
Se ti puoi accontentare di qualche oggetto in meno, ti
segnalo il mio progetto CalcComb presente sul Sito
Comune: usa le Permutazioni.
Ciao, per ora ed a risentirci.
Franco
Web: 
http://www.flanguasco.org