http://forum.ubuntu-it.org/viewtopic.php?p=4539398#p4539369
https://www.iprogrammatori.it/forum-programmazione/cplusplus/programmazione-t30534.html#p8571824
Scusa ma purtroppo non so leggere il C potresti essere così gentile di tradurre l'algoritmo di Knuth in Gambas?
void Knuth_perm(size_t size, unsigned int *pi) {
size_t i;
for (i = size; i > 1; --i) {
register unsigned int t;
size_t p = rand() % i;
t = pi[p];
pi[p] = pi[i -1];
pi[i -1] = t;
}
}
:ciao: :ciao:
La mia immancabile interpretazione personale (stavolta senza errori, vero Gian? :P :P ):
' Gambas class file
Private mazzo[52] As Byte 'mazzo da 52 carte
Public Sub Form_Open()
Dim i, j, l As Byte
For i = 0 To 51 'riempiamo il mazzo
mazzo[i] = i + 1
Next
Randomize 'inizializziamo il generatore di numeri casuali
For i = 1 To 200 '200 scambi (numero settabile a piacere)
j = Rand(51) '2 posizioni a caso nel mazzo
l = Rand(51)
Swap mazzo[j], mazzo[l] 'le scambiamo tra di loro
Next
For i = 0 To 51 'vediamo il risultato
Print mazzo[i];;
Next
End
... tradurre l'algoritmo di Knuth in Gambas?
Eccolo di seguito anche inserito in un esempio pratico:
Private Const RAND_MAX As Integer = 2147483647
Public Sub Main()
Dim ii As Integer[] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
Dim i As Integer
Knuth_perm(ii.Count, ii) ' Ritorno dei dati per "Indirizzo" '
For Each i In ii
Print i
Next
End
Private Function Knuth_perm(size As Long, _pi As Integer[]) ' Ritorno dei dati per "Indirizzo" '
Dim i, p As Long
Dim t As Integer
For i = size To 2 Step - 1
p = CInt(Rnd(0, RAND_MAX)) Mod i
t = _pi[p]
_pi[p] = _pi[i - 1]
_pi[i - 1] = t
Next
End
Per essere più filologicamente aderenti al codice, scritto in C, si sarebbe dovuto passare alla Funzione " Knuth_perm( ) " l'indirizzo di memoria della variabile vettoriale e quindi utilizzare lì una variabile di tipo "Puntatore", gestendola in lettura con le specifiche funzioni native di dereferenziazione ed in scrittura mediante i Memory Stream.
Molto interessante, geniale ampliare il rand sfruttando il resto della divisione che non potrà mai superare il divisore meno uno.
Interessante anche il ritorno dei dati per indirizzo, da me usato un sacco di volte in VBA ma completamente dimenticato.
Propongo questi due piccoli cambiamenti Gambas Like:
Private Const RAND_MAX As Integer = 2147483647
Public Sub Main()
Dim ii As Integer[] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
Dim i As Integer
Knuth_perm(ii.Count, ii) ' Ritorno dei dati per "Indirizzo" '
For Each i In ii
Print i
Next
End
Private Function Knuth_perm(size As Long, _pi As Integer[]) ' Ritorno dei dati per "Indirizzo" '
Dim i, p As Long
For i = size To 2 Step - 1
p = Rand(1, RAND_MAX) Mod i
Swap _pi[p], _pi[i - 1]
Next
End
:ciao:
' size_t Dim_size_t()
' Ritorna la quantità di memoria in byte occupata dal tipo "size_t" di C
Private Extern Dim_size_t() As Long In "/tmp/quantitas"
Public Sub Main()
Dim qnt As Byte
If System.Architecture <> "x86_64" Then Return
CreaSo()
qnt = CByte(Dim_size_t())
Print "Dimensione di\n\nC 'size_t': "; qnt; " byte"
Print "Gambas 'Long': "; SizeOf(gb.Long); " byte"
End
Private Procedure CreaSo()
File.Save("/tmp/quantitas.c", "#include <stdio.h>\n\n" &
"size_t Dim_size_t() {\n\n" &
" return sizeof(size_t);\n\n}")
Shell "gcc -o /tmp/quantitas.so /tmp/quantitas.c -shared" Wait
End