Perl 28/13 ≈ 2.15
sub r{$s^=~($s^=$s/7215)<<8}
Logdatei hier
Perl 29/13 ≈ 2.23
sub r{$s^=~($s^=$s<<8)/60757}
Logdatei hier
Dies ist eine Art Variation einer Xorshift-Funktion , bei der anstelle einer Rechtsverschiebung eine Gleitkommadivision verwendet wird. Beide haben 13 von 15 Tests bestanden und nur die Tests 6 und 7 nicht bestanden.
Ich bin mir nicht ganz sicher , wie lange der Zyklus ist, sondern weil der folgende Code in keiner kurzen Zeit nicht beenden, ist es wahrscheinlich die volle 2 32 :
$start = r();
$i++ while $start != r();
print $i;
Perl 39/10 = 3,9
$s=$^T;sub r{~($s=$s*$s%4294969373)||r}
Hinweis: Wenn Sie nach einem Blum-Blum-Shub-ähnlichen PRNG suchen, ist die Lösung von Keith Randall weitaus besser als jede dieser Lösungen .
Wie bei meiner ursprünglichen Lösung unten handelt es sich auch hier um eine Implementierung von Blum Blum Shub, mit einem großen Unterschied. Ich verwende ein Modul, das etwas größer als 2 32 ist ( M = 50971 • 84263 ). Wenn ein Wert gefunden wird, der keine gültige 32-Bit-Ganzzahl ist ( dh größer als 2 32 ), wird der nächste Wert in der zurückgegeben Rotation statt. Im Wesentlichen werden diese Werte herausgeschnitten, so dass der Rest der Rotation ungestört bleibt, was zu einer nahezu gleichmäßigen Verteilung führt.
Es scheint geholfen zu haben. Er besteht nicht nur die gleichen 9 Tests wie zuvor, sondern besteht jetzt auch überzeugend den Mindestabstandstest. Eine Beispielprotokolldatei finden Sie hier .
Perl 33/9 ≈ 3.67 (Ungültig?)
$s=$^T;sub r{$s=$s*$s%4294951589}
Hinweis: Diese Lösung kann als ungültig angesehen werden, da die obersten 0,00037% des Bereichs niemals eingehalten werden.
Eine schnelle und schmutzige Implementierung des Blum Blum Shub . Ich behaupte die folgenden Ergebnisse:
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
Eine Beispielprotokolldatei finden Sie hier. Sie können die Ergebnisse jederzeit beanstanden. Die Datei für diehard kann auf folgende Weise generiert werden:
print pack('N', r()) for 1..4194304
und dann die Ausgabe in eine Datei umleiten. Der Mindestabstand scheint verstrichen zu sein, aber wenn Sie ihn mehrmals ausführen, liegt er immer nahe bei 1,0 , was auf einen Fehler hinweist.
Einzelheiten
Im Allgemeinen ist der Blum Blum Shub ein schrecklicher PRNG, aber seine Leistung kann durch Auswahl eines guten Moduls verbessert werden. Das von mir gewählte M ist 7027 • 611207 . Beide Primfaktoren, p und q , haben den modularen Rest 3 (mod 4) und gcd (p (p-1), φ (q-1)) = 2 , was so niedrig wie möglich ist.
Obwohl dies die einzigen Kriterien sind, die auf der Wiki-Seite aufgelistet sind, scheint es nicht genug zu sein. Fast das gesamte Modulo, das ich ausprobiert habe, ist bei jedem Test durchgefallen. Aber es gibt eine Handvoll, die einige der Tests bestehen wird, und die, die ich ausgewählt habe, scheint aus irgendeinem Grund außergewöhnlich gut zu sein.
Als letzte Anmerkung scheint Test 5 für sich genommen ein ziemlich guter Indikator dafür zu sein, wie gut der PRNG ist. Wenn es Test 5 nicht fast besteht , wird es den Rest von ihnen spektakulär verfehlen.
BONUS: Perl 62/14 ≈ 4,43
$t=$^T;sub r{$t|=(($s=$s/2|$t%2<<31)^($t/=2))<<31for 1..37;$t}
Nur für Geekery ist dies eine 32-Bit-Version des PRNG, das im ursprünglichen Tetris für NES verwendet wird. Erstaunlicherweise besteht es 14 der 15 Tests!
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
Beispielprotokolldatei kann vorher hier stehen .
Zugegeben, das 1..37
Bit ist keine exakte Transkription. In der ursprünglichen Version wird die Entropieroutine 60 Mal pro Sekunde aktualisiert und dann in zufälligen Intervallen abgefragt, was weitgehend von Benutzereingaben abhängt. Für alle, die den ROM zerlegen möchten, beginnt die Entropieroutine bei 0xAB47
.
Python-artiger Pseudocode:
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