Perl 28/13 ≈ 2,15
sub r{$s^=~($s^=$s/7215)<<8}
buraya günlük dosyası
Perl 29/13, 2.23
sub r{$s^=~($s^=$s<<8)/60757}
buraya günlük dosyası
Bunlar bir Xorshift'te , sağa kayma yerine kayan nokta bölmesini kullanan bir çeşitliliktir . Her ikisi de 15 testten 13'ünü geçiyor, sadece 6 ve 7 testlerini geçemiyor.
Ben döngüdür tam olarak ne kadar emin değilim, ancak aşağıdaki kod herhangi bir zaman kısa sürede sonlandırmak değil, bunun nedeni büyük olasılıkla dolu 2 32 :
$start = r();
$i++ while $start != r();
print $i;
Perl 39/10 = 3,9
$s=$^T;sub r{~($s=$s*$s%4294969373)||r}
Not: Bir Blum-Blum-Shub-esque PRNG arıyorsanız, Keith Randall'ın çözümü her ikisinden de çok daha iyi.
Aşağıdaki orijinal çözümümde olduğu gibi, bu da Blum Blum Shub'ın bir büyük fark yaratan uygulamasıdır. 2 32'den biraz daha büyük bir modül kullanıyorum ( M = 50971 • 84263 ) ve ne zaman bir değerin geçerli bir 32 bit tam sayı olmadığı (yani, 2 32'den büyük ) olmadığında bir sonraki değeri döndürür. bunun yerine döndürme. Esasında, bu değerler budanarak, rotasyonun geri kalanını rahatsız etmeden bırakarak neredeyse tekdüze bir dağılıma yol açar.
Yardım etmiş gibi görünüyor. Daha önce olduğu gibi aynı 9 testi geçmenin yanı sıra, şimdi inandırıcı bir şekilde Minimum Mesafe testini de geçiyor. Örnek bir günlük dosyası burada bulunabilir .
Perl 33/9 ≈ 3.67 (Geçersiz?)
$s=$^T;sub r{$s=$s*$s%4294951589}
Not: Bu çözüm geçersiz sayılabilir, çünkü aralığın en yüksek% 0.00037'si asla gözlenmez.
Blum Blum Shub'ın hızlı ve kirli bir uygulaması . Aşağıdaki sonuçları talep ediyorum:
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
Örnek bir günlük dosyası bulunabilir burada , sonuçların herhangi anlaşmazlığı çekinmeyin. Diehard dosyası aşağıdaki şekilde oluşturulabilir:
print pack('N', r()) for 1..4194304
ve ardından çıktının bir dosyaya aktarılması. Minimum Mesafe geçti gibi gözüküyor, ancak birden çok kez çalıştırırsanız her zaman 1.0'a çok yakındır , bu da başarısızlığı gösterir.
ayrıntılar
Genel olarak, Blum Blum Shub, korkunç bir PRNG'dir, ancak iyi bir modül seçerek performansı arttırılabilir. M benim seçimim olduğunu 611207 • 7027 . Bu asal faktörlerin her ikisi de, p ve q , modüler kalıntı 3 (mod 4) ve gcd (φ (p-1), φ (q-1)) = 2 olabilir;
Bunlar wiki sayfasında listelenen tek kriter olmasına rağmen, yeterli görünmüyor. Neredeyse denedim modulo her testi başarısız oldu. Ancak bazı testlerden geçecek bir avuç var ve seçtiğim sınavın ne sebeple olursa olsun son derece iyi olduğu görülüyor.
Son bir not olarak, Test 5 kendi başına PRNG'nin ne kadar iyi olduğunun oldukça iyi bir göstergesi gibi görünüyor. O olmazsa neredeyse Testi 5 geçmesi, bu olağanüstü geride kalanlarını başarısız olur.
BONUS: Perl 62/14, 4.43
$t=$^T;sub r{$t|=(($s=$s/2|$t%2<<31)^($t/=2))<<31for 1..37;$t}
Sadece geekery için, bu NES için orijinal Tetris'te kullanılan PRNG'nin 32-bit bir versiyonudur. Şaşırtıcı bir şekilde, 15 testten 14'ünü geçiyor!
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
Örnek günlük dosyası önce can burada .
Kuşkusuz, 1..37
bit kesin bir transkripsiyon değildir. Orijinal versiyonda, entropi rutini saniyede 60 kez güncellenir ve daha sonra büyük ölçüde kullanıcı girdisine bağlı olarak rasgele aralıklarla sorgulanır. ROM'u sökmeyi önemseyen herkes için entropi rutini başlar 0xAB47
.
Python tarzı sahte kod:
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