Perl 28/13≈2.15
sub r{$s^=~($s^=$s/7215)<<8}
ログファイルはこちら
Perl 29/13≈2.23
sub r{$s^=~($s^=$s<<8)/60757}
ログファイルはこちら
これらは、右シフトの代わりに浮動小数点除算を使用するXorshiftのバリエーションです。両方とも15のテストのうち13に合格し、テスト6と7のみに失敗します。
サイクルの長さは正確にはわかりませんが、次のコードは短期間で終了しないため、おそらく完全な2 32になります。
$start = r();
$i++ while $start != r();
print $i;
Perl 39/10 = 3.9
$s=$^T;sub r{~($s=$s*$s%4294969373)||r}
注:Blum-Blum-Shub風のPRNGを探している場合、Keith Randallのソリューションはこれらのいずれよりもはるかに優れています。
以下の元のソリューションと同様に、これはBlum Blum Shubの実装でもありますが、大きな違いが1つあります。私は2 32よりわずかに大きいモジュラス(M = 50971•84263)を使用し、値が有効な32ビット整数でない(つまり、2 32より大きい)場合は、次の値を返します代わりに回転。本質的に、これらの値は取り除かれ、残りの回転はそのままにされ、ほぼ均一な分布が得られます。
助けたようです。以前と同じ9つのテストに合格することに加えて、最小距離テストにも確実に合格しました。サンプルログファイルはこちらにあります。
Perl 33/9≈3.67(無効ですか?)
$s=$^T;sub r{$s=$s*$s%4294951589}
注:範囲の最上位0.00037%は決して観察されないため、このソリューションは無効と見なされる場合があります。
Blum Blum Shubの迅速で汚れた実装。私は次の結果を主張しています:
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
サンプルログファイルはこちらにあります。結果については、お気軽にご相談ください。diehardのファイルは、次の方法で生成できます。
print pack('N', r()) for 1..4194304
そして、出力をファイルにパイプします。最小距離は通過したように見えますが、複数回実行すると、常に1.0に非常に近くなり、失敗を示します。
詳細
一般に、Blum Blum ShubはひどいPRNGですが、適切なモジュラスを選択することでパフォーマンスを改善できます。M Iは、選択した7027•611207。これらの素因数pとqは両方ともモジュラー剰余3(mod 4)であり、gcd(φ(p-1)、φ(q-1))= 2であり、可能な限り低くなっています。
これらはwikiページにリストされている唯一の基準ですが、それだけでは十分ではないようです。私が試したほとんどすべてのモジュロは、すべてのテストに失敗しました。しかし、いくつかのテストに合格する少数のテストがあり、私が選択したテストは、何らかの理由で非常に優れているようです。
最後の注意として、テスト5自体はPRNGがどれだけ優れているかのかなり良い指標であるようです。テスト5にほとんど合格しない場合、残りのテストは見事に失敗します。
ボーナス:Perl 62/14≈4.43
$t=$^T;sub r{$t|=(($s=$s/2|$t%2<<31)^($t/=2))<<31for 1..37;$t}
おたくだけのために、これは元のTetris for NESで使用されているPRNGの32ビットバージョンです。驚いたことに、15のテストのうち14をパスしています!
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
サンプルログファイルはここより前にできます。
確かに、この1..37
ビットは正確な転写ではありません。元のバージョンでは、エントロピールーチンは1秒間に60回更新され、ユーザー入力に大きく依存してランダムな間隔でクエリされます。ROMを分解したい人のために、エントロピールーチンはから始まります0xAB47
。
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