Perl 28/13 ≈ 2.15
sub r{$s^=~($s^=$s/7215)<<8}
file di registro qui
Perl 29/13 ≈ 2.23
sub r{$s^=~($s^=$s<<8)/60757}
file di registro qui
Queste sono una specie di variazione su uno Xorshift , usando la divisione in virgola mobile anziché uno spostamento a destra. Entrambi superano 13 test su 15, fallendo solo i test 6 e 7.
Non sono esattamente sicuro di quanto sia lungo il ciclo, ma poiché il seguente codice non termina in un breve periodo di tempo, è probabilmente l'intero 2 32 :
$start = r();
$i++ while $start != r();
print $i;
Perl 39/10 = 3.9
$s=$^T;sub r{~($s=$s*$s%4294969373)||r}
Nota: se stai cercando un PRNG Blum-Blum-Shub-esque, la soluzione di Keith Randall è di gran lunga migliore di una di queste.
Come per la mia soluzione originale di seguito, anche questa è un'implementazione del Blum Blum Shub, con una grande differenza. I usa un modulo leggermente più grande di 2 32 ( M = 50971 • 84263 ) e ogni volta che si incontra un valore che non è un intero valido a 32 bit (ovvero maggiore di 2 32 ), restituisce il valore successivo nella rotazione invece. In sostanza, questi valori vengono eliminati, lasciando indisturbato il resto della rotazione, determinando una distribuzione quasi uniforme.
Sembra aver aiutato. Oltre a superare gli stessi 9 test di prima, ora supera anche in modo convincente il test della distanza minima. Un file di registro di esempio è disponibile qui .
Perl 33/9 ≈ 3.67 (Non valido?)
$s=$^T;sub r{$s=$s*$s%4294951589}
Nota: questa soluzione potrebbe essere considerata non valida, poiché lo 0.00037% più alto dell'intervallo non verrà mai osservato.
Un'implementazione rapida e sporca di Blum Blum Shub . Dichiaro i seguenti risultati:
1. passed - Birthday Spacings
2. FAILED - Overlapping Permutations
3. passed - Ranks of 31x31 and 32x32 Matrices
4. passed - Ranks of 6x8 Matrices
5. FAILED - Monkey Tests on 20-bit Words
6. FAILED - Monkey Tests OPSO, OQSO, DNA
7. FAILED - Count the 1s in a Stream of Bytes
8. passed - Count the 1s for Specific Bytes
9. passed - Parking Lot Test
10. FAILED - Minimum Distance Test
11. passed - Random Spheres Test
12. FAILED - The Squeeze Test
13. passed - Overlapping Sums Test
14. passed - Runs Test
15. passed - The Craps Test
Un file di registro di esempio può essere trovato qui , non esitate a contestare qualsiasi risultato. Il file per diehard può essere generato nel modo seguente:
print pack('N', r()) for 1..4194304
e quindi reindirizzare l'output in un file. La distanza minima sembra che potrebbe essere passata, ma se la esegui più volte è sempre molto vicina alla 1.0 , che indica un errore.
Dettagli
In generale, il Blum Blum Shub è un PRNG terribile, ma le sue prestazioni possono essere migliorate scegliendo un buon modulo. La M che ho scelto è 7027 • 611207 . Entrambi questi fattori primi, p e q , hanno residuo modulare 3 (mod 4) e gcd (φ (p-1), φ (q-1)) = 2 , che è il più basso possibile.
Sebbene questi siano gli unici criteri elencati nella pagina wiki, non sembra essere sufficiente. Quasi tutto il modulo che ho provato ha fallito ogni test. Ma c'è una manciata che supererà alcuni dei test e quello che ho scelto sembra essere eccezionalmente buono, per qualsiasi motivo.
Come nota finale, il Test 5 da solo sembra essere un buon indicatore di quanto sia buono il PRNG. Se non supera quasi il Test 5, fallirà in modo spettacolare il resto di essi.
BONUS: Perl 62/14 ≈ 4.43
$t=$^T;sub r{$t|=(($s=$s/2|$t%2<<31)^($t/=2))<<31for 1..37;$t}
Solo per i geek, questa è una versione a 32 bit del PRNG utilizzata nel Tetris originale per NES. Sorprendentemente, supera 14 dei 15 test!
1. passed - Birthday Spacings
2. passed - Overlapping Permutations
3. passed - Ranks of 31x31 and 32x32 Matrices
4. passed - Ranks for 6x8 Matrices
5. passed - Monkey Tests on 20-bit Words
6. passed - Monkey Tests OPSO, OQSO, DNA
7. FAILED - Count the 1s in a Stream of Bytes
8. passed - Count the 1s for Specific Bytes
9. passed - Parking Lot Test
10. passed - Minimum Distance Test
11. passed - Random Spheres Test
12. passed - The Squeeze Test
13. passed - Overlapping Sums Test
14. passed - Runs Test
15. passed - The Craps Test
Il file di registro di esempio può prima qui .
Certo, il 1..37
bit non è una trascrizione esatta. Nella versione originale, la routine entropica viene aggiornata 60 volte al secondo e quindi interrogata a intervalli casuali, in gran parte dipendente dall'input dell'utente. Per chiunque si preoccupi di smontare la ROM, inizia la routine dell'entropia 0xAB47
.
Pseudo-codice in stile Python:
carry = entropy_1 & 1
entropy_1 >>= 1
entropy_2 = (entropy_2 >> 1) | (carry << 31)
carry = (entropy_1 & 1) ^ (entropy_2 & 1)
entropy_1 |= carry << 31