एक (पूरी तरह से नियतात्मक) छद्म आयामी बिट स्ट्रीम उत्पन्न करें


11

अपने हाथों से रैंडम से प्रेरित :


लक्ष्य

इस चुनौती का लक्ष्य एक ऐसा प्रोग्राम लिखना है जो एक छद्म आयामी बिट स्ट्रीम उत्पन्न करता है, जो कि 1s और 0s का एक तार है जो विशुद्ध रूप से यादृच्छिक प्रतीत होता है, लेकिन वास्तव में एक नियतात्मक तरीके से उत्पन्न होता है। आपके कार्यक्रम को 1 और 0s (वैकल्पिक व्हाट्सएप के साथ) का एक स्ट्रिंग आउटपुट करना चाहिए और निम्नलिखित आवश्यकताओं को पारित करना चाहिए:

  1. असीमित समय और मेमोरी को देखते हुए, आपके प्रोग्राम को 1s और 0s के एक स्ट्रिंग को हमेशा के लिए आउटपुट करना जारी रखना चाहिए
  2. आपका कार्यक्रम एक उचित मशीन पर लगभग एक मिनट में 1000 से अधिक यादृच्छिक बिट्स का उत्पादन करना चाहिए। यदि यह आवश्यकता असंभव है, तो मैं इसे कम कर दूंगा।
  3. बिट्स की स्ट्रिंग दोहरा सकती है, लेकिन रिपीटिंग सेक्शन की लंबाई 1000 बिट्स से अधिक होनी चाहिए।
  4. बिट्स की स्ट्रिंग को यथासंभव यादृच्छिकता परीक्षणों (नीचे वर्णित) से गुजरना होगा।
  5. कार्यक्रम को किसी भी बाहरी स्रोत से कोई इनपुट नहीं लेना चाहिए या किसी भी अंतर्निहित रैंड () - जैसे फ़ंक्शन का उपयोग नहीं करना चाहिए।
  6. उपरोक्त आवश्यकता के कारण, प्रोग्राम को हर बार बिट के समान सटीक स्ट्रिंग का उत्पादन करना चाहिए जो इसे चलाया जाता है।

रैंडम टेस्ट # 1

दृश्य निरीक्षण पर किसी भी स्पष्ट पैटर्न को छद्म आयामी बिट्स की स्ट्रिंग में शामिल नहीं करना चाहिए।

रैंडमनेस टेस्ट # 2 (टिप्पणियों के आधार पर परिवर्तन के अधीन)

बिट्स की स्ट्रिंग में 1s और 0s का समान वितरण होना चाहिए। इसे (और अन्य चीजों को भी) जांचने के लिए, बिट्स की धारा उन खंडों में टूट जाती है जो 3 बिट लंबे होते हैं, जैसे 101|111|001

इन सभी सेगमेंट में से, 1/8 में तीन 1s और कोई 0s नहीं होना चाहिए, उनमें से 3/8 में दो 1s और एक 0, 3/8 होने चाहिए उनमें से 1 1 और 2 0, और 1/8 होना चाहिए। उनमें से कोई 1s और तीन 0s होना चाहिए।

यादृच्छिकता टेस्ट # 3

एक "रन" को बिट्स की एक निरंतर श्रृंखला के रूप में परिभाषित किया गया है जो सभी का समान मूल्य है। स्ट्रिंग 1001001110में आकार 1 ( 1..1.....0), आकार 2 के दो रन ( .00.00....) और आकार 3 ( ......111.) का एक रन होता है । जो सूचना चलती है वह ओवरलैप नहीं होती है।

1000 यादृच्छिक बिट्स की एक स्ट्रिंग में, आकार 1 के लगभग 250 रन, आकार 2 के 125 रन, आकार 3 के 62 रन आदि होना चाहिए। सामान्य तौर पर, रन आकार R के लिए, 1000/(2**(R+1))उस आकार के लगभग रन होने चाहिए ।

यादृच्छिकता टेस्ट # 4

पहले 840 बिट्स को 420 बिट्स के दो हिस्सों में विभाजित किया गया है। पहली छमाही पर प्रत्येक बिट की तुलना दूसरी छमाही पर संबंधित बिट से की जाती है। दो बिट्स को लगभग पचास प्रतिशत समय से मेल खाना चाहिए।


यहाँ एक पर्ल प्रोग्राम का स्रोत कोड है जो 2 के माध्यम से 2 परीक्षण करता है। अब तक, यह आवश्यक है कि बिट्स के स्ट्रिंग में कोई व्हाट्सएप न हो।


उद्देश्य जीत का मानदंड समय!

विजेता वह प्रोग्राम है जो 6 आवश्यकताओं में से सभी को पास करता है और सभी यादृच्छिकता परीक्षणों को उस डिग्री तक पहुंचाता है जो यादृच्छिकता के साथ अविभाज्य है। यदि कई कार्यक्रम इसे पूरा करते हैं, तो जो सबसे लंबे समय तक दोहराता है वह जीत जाएगा। यदि कई कार्यक्रम इसे पूरा करते हैं, तो मुझे टाई-ब्रेकर के रूप में कार्य करने के लिए अधिक यादृच्छिकता परीक्षण ढूंढना पड़ सकता है।


# 2 और # 3 यादृच्छिकता के लिए वास्तव में बहुत अच्छे मापदंड नहीं हैं। # 2 के लिए विशेष रूप से, एक यादृच्छिक नमूना शायद इस विशेषता को प्रदर्शित नहीं करेगा। शायद आप एक बड़ा नमूना आकार कर सकते हैं? मैं 100 और 300 के बीच कुछ सुझाऊंगा।
जोएल कॉर्नेट

एक बेहतर माप पद्धति एक चलती औसत होगी, क्योंकि बिटस्ट्रीम पर एक बड़ी खिड़की का मतलब ज्यादा नहीं बदलेगा (और लगभग 0.5 होना चाहिए)
जोएल कॉर्नेट

@JoelCornett सलाह के लिए धन्यवाद। मैं यादृच्छिकता परीक्षण के बारे में ज्यादा नहीं जानता। मैं # 2 को कुछ और में बदलूंगा, और मैं चलती औसत के बारे में पढ़ रहा हूं।
PhiNotPi

1
कोई दिक्कत नहीं है। रैंडम सीक्वेंस टकराते हैं और समान रूप से वितरित नहीं होते हैं, यह एक तथ्य है जो कभी-कभी धोखाधड़ी का पता लगाने के लिए लेखांकन में उपयोग किया जाता है। (धोखाधड़ी संख्याओं को अक्सर समान रूप से वितरित किया जाएगा, क्योंकि लोग उन्हें यादृच्छिकता के लिए एकरूपता का आविष्कार करते हैं)
जोएल कॉर्नेट

क्या मैं अंतर्निहित क्रिप्टो कार्यों (जैसे एईएस या एसएचए -2) का उपयोग कर सकता हूं?
कोडइन्चोस

जवाबों:


8

सी, 61

main(s,n){for(n=1u<<31;putchar((s%=n)/(n/2)&1|48);s*=65539);}

हाँ, मुझे पता है कि यह कोड गोल्फ नहीं है। यह स्पष्ट रूप से बल्कि एक विरोधी समाधान है ... लेकिन यह सुनिश्चित करता है कि आपके मानदंडों को पूरा करता है।

बाहर | हेड -c840
$ ./a.out | हेड -c840 | perl tester.pl
टेस्ट 2: 1 (1) 2.93333333333333 (3) 3.1 (3) 0.966666666666667 (1)
टेस्ट 3: 214 99 71 24 7 5 1 1 2 2
टेस्ट 4: 0.495238095238095

अवधि की लंबाई 2 length है।


6
यह दिखाने के लिए कि किसी चीज़ से यादृच्छिकता को बताना कितना कठिन है, जिसे व्यापक रूप से अस्तित्व में सबसे खराब यादृच्छिक संख्या जनरेटर में से एक माना जाता है। +1।
PhiNotPi

8

गणितज्ञ 78 53 वर्ण

पाई के द्विआधारी प्रतिनिधित्व के अंक ऐसा प्रतीत होता है मानो वे अव्यवस्थित रूप से निर्मित हैं हालांकि यह अप्रमाणित है।

निम्नलिखित साधारण दिनचर्या dदशमलव स्ट्रिंग के बजाए पीआई के द्विआधारी अंकों को एक स्ट्रिंग के रूप में निर्धारित करती है :

f[d_]:=ToString@FromDigits@RealDigits[N[Pi,d],2][[1]]

प्रयोग

यदि हम पाई के 301 दशमलव अंकों के समकक्ष का अनुरोध करते हैं, तो हम 1000 द्विआधारी अंक प्राप्त करते हैं।

f[301]
StringLength[%]

(* out *)
1100100100001111110110101010001000100001011010001100001000110100110001001100011001100010100010111000000011011100000111001101000100101001000000100100111000001000100010100110011111001100011101000000001000001011101111101010011000111011000100111001101100100010010100010100101000001000011110011000111000110100000001001101110111101111100101010001100110110011110011010011101001000011000110110011000000101011000010100110110111110010010111110001010000110111010011111110000100110101011011010110110101010001110000100100010111100100100001011011010101110110011000100101111001111110110001101111010001001100010000101110100110100110001101111110110101101011000010111111111101011100101101101111010000000110101101111110110111101110001110000110101111111011010110101000100110011111101001011010111010011111001001000001000101111100010010110001111111100110010010010010100001100110010100011110110011100100010110110011110111000010000000000111110010111000101000010110001110111111000001011001100011011010010010000011011000011100011

1000 (* characters *)

क्योंकि पाई एक अपरिमेय संख्या है, कोई अवधि नहीं है। हालाँकि, हार्डवेयर के चलने के कारण व्यावहारिक बाधाएँ होंगी।

टेस्ट 1 मुझे अच्छा लग रहा है।

परीक्षण २

d=301;
Partition[RealDigits[N[Pi,d],2][[1]],{3}];
Tally[%]
(* out *)
{{{1,1,0},35},{{0,1,0},45},{{0,0,0},41},{{1,1,1},40},
{{0,1,1},50},{{1,0,1},32},{{1,0,0},43},{{0,0,1},47}}

अधिक गहन जाँच करें:

d=10^6;
Partition[RealDigits[N[Pi,d],2][[1]],{3}];
Tally[%]

{{{1,1,0},138565},{{0,1,0},138146},{{0,0,0},138260},{{1,1,1},138427},
{{0,1,1},139119}, {{1,0,1},138404},{{1,0,0},137926},{{0,0,1},138462}}

टेस्ट 3: दौड़ता है

d=10^6;
res3=SortBy[Tally@Split@RealDigits[N[Pi,d],2][[1]],Last]/.{a_,b_}:> {Length[a],b}
ListPlot[res3 ,AxesLabel-> {"Run Length","Runs"},AxesOrigin->{0,0}]

मैंने रन के वितरण को व्यवस्थित रूप से जांचने के लिए बड़ी संख्या में मामले चलाए। लगभग 3 मिलियन बाइनरी अंकों में, 1 के 830k रन, 2 के 416k रन, 3 के 208k रन, 4 के 104k रन, आदि थे।

2 रन टेस्ट 4: डेटा के पहले और दूसरे छमाही का मिलान

मैच 0 और 2 के 212 मामले हैं; बेमेल 208 मामले हैं जहां संबंधित अंकों का योग 1 है।

d=301;
Tally[Plus@@Partition[Take[RealDigits[N[Pi,d],2][[1]],840],420]]

(* out *)
{{1,208},{0,108},{2,104}}

समय

3321928 बाइनरी अंकों (10 ^ 6 दशमलव अंकों के अनुरूप) की गणना करने में दो सेकंड लगते हैं।

(r=f[10^6]);//AbsoluteTiming
StringLength[r]

(*out*)
{1.785928,Null}    
3321928

1
मुझे पता था कि कोई ऐसा करेगा ...
को बंद करना

1
कम लटका हुआ फल, है ना?
डेविड

आप एक बाइट को बचाने के eबजाय उपयोग नहीं कर सकते pi?
पिपरी

है eअस्त व्यस्त वितरित?
डेविड डिक

3

पायथन, 90

g=[19]
print(''.join("01"[(g.append((11*g[-1]+13)%1024)or g[-1])>512]for i in range(1000)))

gबीज मूल्य है। यादृच्छिक नमूनाकरण एक उल्लेखनीय सामान्य वितरण प्रदर्शित करता है दोहराया नमूना के यादृच्छिक नमूने का मतलब है 0.506और .0473( मानक आकार 1000 का नमूना) का एक मतलब उपज है । दुर्भाग्य से, यादृच्छिकता प्रारंभिक बीज के प्रति अत्यधिक संवेदनशील है। उपरोक्त कोड में बीज ने मुझे सबसे अच्छा यादृच्छिकता दिया: पी

अपडेट करें

आइए देखें कि यह कोड ओपी के परीक्षणों के लिए कैसा है:

टेस्ट # 1

यह थोड़ा व्यक्तिपरक है ... लेकिन यह मुझे बहुत अनियमित लगता है।

टेस्ट # 2

तीन 1 का: 0.141
दो 1 का: 0.371
एक 1: 0.353
शून्य 1 का: 0.135

टेस्ट # 3

आकार द्वारा चलाता है:

8: 11
7: 3
6: 7
5: 13
4: 32
3: 67
2: 119
1: 216

टेस्ट # 4

समानता का अनुपात: 0.94 यह एक टाइपो है। जल्द ही सही नंबर के साथ अपडेट होगा।


1
आप 'के लिए' से पहले व्हॉट्सएप को हटा सकते हैं।
डेनिएरो

2

हास्केल 74 58

main=print$iterate(read.take 9.show.(^3))7>>=show.(`mod`2)

सरलीकरण के लिए शियोना का धन्यवाद । परिणाम:

/ छद्म आयामी | हेड -c 1000

./pseudorandom | हेड -c 1000 | perl test.pl

टेस्ट 2: 0.96666666666666667 (1) 2.4 (3) 3.3 (3) 1.333333333333 (1)

टेस्ट 3: 260 108 66 33 15 11 5 2

टेस्ट 4: 0.495238095238095

यह एक भयानक छद्म यादृच्छिक जनरेटर (वॉन-न्यूमन द्वारा उपयोग किए जाने वाले समान) भी है। उन लोगों के लिए जो जागरूक नहीं थे concatMap == (=<<) == flip . (>>=)(सूचियों के लिए)


आप बदल सकते हैं \x->if odd x then"1"else"0"के साथ show.(`mod`2)
शियोना

1

सवाल अनिवार्य रूप से "एक धारा सिफर लागू करने के लिए" के बराबर है। इसलिए मैं RC4 को लागू करता हूं, क्योंकि यह अपेक्षाकृत सरल है।

मैं कोई कुंजी का उपयोग नहीं करता हूं, और पहले 100000 बिट्स को छोड़ देता हूं, क्योंकि आरसी 4 की शुरुआत थोड़ा पक्षपाती है, खासकर जब से मैंने कुंजी शेड्यूल को छोड़ दिया है। लेकिन मुझे उम्मीद है कि इसके बिना भी आपकी परीक्षा पास होगी (कोड के 20 वर्णों की बचत)।

आम तौर पर प्रति चक्र में एक पूर्ण बाइट का उत्पादन होता है, लेकिन बाइनरी में परिवर्तित करना सी # में बदसूरत होता है, इसलिए मैं बस कम से कम महत्वपूर्ण बिट को छोड़कर सब कुछ त्याग देता हूं।

var s=Enumerable.Range(0,256).ToArray();
byte i=0,j=0;
for(int k=0;;k++)
{
    i++;
    j+=(byte)s[i];
    var t=s[i];s[i]=s[j];s[j]=t;
    if(k>99999)
        Console.Write(s[i]+s[j]&1);
}

या रिक्त स्थान के बिना:

var s=Enumerable.Range(0,256).ToArray();byte i=0,j=0;for(int k=0;;k++){i++;j+=(byte)s[i];var t=s[i];s[i]=s[j];s[j]=t;if(k>99999)Console.Write(s[i]+s[j]&1);}

लाइन #, 156 वर्ण, लाइनक्पैड के स्टेटमेंट मोड में काम करता है। एक पूर्ण सी # कार्यक्रम के लिए सामान्य बॉयलरप्लेट जोड़ें।


हम क्रिप्टो प्राइमेटिव्स (चीटर सॉल्यूशन) में निर्मित का भी उपयोग कर सकते हैं:

var h=SHA256.Create();for(BigInteger i=0;;i++){Console.Write(h.ComputeHash(i.ToByteArray())[0]%2);}

(C #, 99 chars, LinqPad के स्टेटमेंट मोड में काम करता है। सामान्य C # कंपाइलर के लिए आपको थोड़ा सा बॉयलरप्लेट जोड़ना होगा)

क्रिप्टोग्राफ़िक हैश फ़ंक्शंस का आउटपुट यादृच्छिक डेटा से अप्रभेद्य होने के लिए डिज़ाइन किया गया है, इसलिए मुझे उम्मीद है कि आप सभी यादृच्छिकता परीक्षणों (कठिन मरो, ...) को पास करेंगे, लेकिन मैं परीक्षण के लिए बहुत आलसी हूं।


1

C, 52 वर्ण

main(a){for(a=1;putchar(48+a%2);a=a/2^-(a%2)&576);}

यह 10 बिट LFSR है, परीक्षा परिणाम:

$ ./a.out |head -c 1000 | perl randtest.pl
Test 2: 1.13333333333333 (1) 2.86666666666667 (3) 3.16666666666667 (3) 0.833333333333333 (1)
Test 3:  251 122 64 32 16 8 4 2  1
Test 4: 0.466666666666667

a1 के रूप में शुरू होना चाहिए (यह मानते हुए कि इसे बिना किसी तर्क के कहा जाता है)। इसके अलावा, आप a=बीच में छड़ी कर सकते हैं , जैसे कुछ a=a/2^-!putchar(49-a%2)%576(एल्गोरिथ्म के साथ कुछ स्वतंत्रता लेना)
1

@walpen: मेरा आरंभिक कार्यान्वयन सेट नहीं हुआ a, मैंने इसे " The program must not take any input from any external sources" के कारण बदल दिया
हस्त्कर्ण

1

साधु / अजगर

यह प्रोग्राम सबसे सही बाइनरी अंकों को प्रिंट करता है जो फॉर्म 3 3 3 3 के प्रत्येक पर्याप्त रूप से लम्बे घातांक टॉवर के लिए सामान्य हैं । उन सभी के लिए जो कभी भी संभवत: उत्पन्न हो सकते हैं, ये ग्राहम की संख्या के सबसे सही द्विआधारी अंक हैं । अंक अनुक्रम अनंत है, और आवधिक नहीं है।

m = 1; x = 3; last = 0
while True:
    m *= 2; x = pow(3,x,m); l = len(bin(x))
    print '1' if l > last else '0',
    last = l

1000 अंकों के लिए, यह 2 सेकंड से कम समय लेता है; हालाँकि, समय अंकों की संख्या में रैखिक रूप से बहुत तेजी से बढ़ेगा।

ओपी के कार्यक्रम का उपयोग कर परीक्षण के परिणाम हैं

Test 2: 1.26666666666667 (1) 3.16666666666667 (3) 2.8 (3) 0.766666666666667 (1)
Test 3:  268 126 61 30 20 7 2  1 1
Test 4: 0.466666666666667

(देखें 32000 से अधिक अंकों और अतिरिक्त सांख्यिकीय परीक्षणों के लिए जी यादृच्छिक के सबसे सही अंक हैं ।)


1

जावा, 371 317

128 बिट LFSR पर आधारित (बिट टैप xilinx ऐप नोट 52 से हैं )

संपादित करें: मैं BigInteger का उपयोग करने से संतुष्ट नहीं था इसलिए यह संस्करण नहीं है। कुछ पात्रों को बचाया। आउटपुट थोड़ा कम यादृच्छिक हो सकता है क्योंकि मैं एक अच्छी 'सीडिंग' विधि के बारे में नहीं सोच सकता था।

नया कोड: तर्क: BITS_TO_PRINT

class R{public static void main(String[]a){int L=65536;int[]v={0,128,126,101,99};int[]b=new int[L];for(int x=0;x<L;x++)b[x]=(x*x)&1;for(int i=0;i<Integer.parseInt(a[0])+L;i++){if(1!=(b[v[1]]^b[v[2]]^b[v[3]]^b[v[4]]))b[v[0]]=1;else b[v[0]]=0;if(i>L)System.out.print(b[v[0]]);for(int j=0;j<5;j++)v[j]=(v[j]-1)&(L-1);}}}

पुराना संस्करण: तर्क: बीज, BITS_TO_PRINT

import java.math.BigInteger;class R{public static void main(String[]a){BigInteger v=new BigInteger(a[0]);BigInteger m=new BigInteger("ffffffffffffffffffffffffffffffff",16);for(int i=Integer.parseInt(a[1]);i>0;i--){v=v.shiftLeft(1);if(!(v.testBit(128)^v.testBit(126)^v.testBit(101)^v.testBit(99))){v=v.setBit(0);}v=v.and(m);java.lang.System.out.print(v.testBit(0)?1:0);}}}

नया संस्करण: उदाहरण आउटपुट, बिट्स = 100:

011001100111000110010100100111011100100111000111001111110110001001100000100111111010111001100100011

1
BTW, मुझे लगता है कि इस पोस्ट से दोनों नूह खाते एक ही व्यक्ति हैं। यदि ऐसा है, तो आप एक मॉडरेटर से उन्हें meta.codegolf.stackexchange.com
पीटर टेलर

0

जावास्क्रिप्ट - 1000 सेंटी-यादृच्छिक बिट्स के लिए 1ms से 2ms (100000 बिट्स के लिए 139ms से 153ms)

यह समाधान इस तथ्य का उपयोग करता है कि वर्गमूल तर्कहीन हैं, और इस प्रकार बहुत अधिक यादृच्छिक हैं। मूल रूप से, इसे शुरू करने के लिए 2 का वर्गमूल लगता है, इसे बाइनरी में परिवर्तित करता है, पिछली जड़ से मेल खाने वाले प्रमुख भाग को बाहर निकालता है, यादृच्छिक स्ट्रिंग से अपील करता है कि अगली उच्च संख्या (या 2 से पीछे की ओर दोहराएं यदि संख्या दोहराई जाती है और कम से कम 30 बिट लंबा) था, और यह काफी लंबा होने के बाद यादृच्छिक स्ट्रिंग लौटाता है।

var getDeterministicPseudoRandString = function(length){
    var randString = '';

    var i = 2;
    var prevRand = '';

    outerLoop:
    while(randString.length < length){
        var nextRand, nextFullRand = Math.sqrt(i++).toString(2).substring(1).replace('.', '');
        nextRand = nextFullRand;
        for(var j = prevRand.length; j > 0; j--){
            var replaceString = prevRand.substring(0, j);

            nextRand = nextFullRand;

            if(nextFullRand.indexOf(replaceString) == 0){
                if(j == prevRand.length && j > 30){
                    //start i over at 2
                    console.log('max i reached: ' + i);

                    i = 2;
                    continue outerLoop;
                } else {
                    nextRand = nextFullRand.replace(replaceString, '');
                }

                break;
            }
        }
        prevRand = nextFullRand;

        randString += nextRand;
    }

    return randString.substring(0, length);//Return the substring with the appropriate length
};

मैंने इसे अभी तक परीक्षणों के माध्यम से नहीं चलाया है, लेकिन मुझे लगता है कि यह उन पर अच्छा करेगा। यहाँ एक बेला है ताकि आप इसे एक्शन में देख सकें। अपने समय के लिए, मैंने बस कई बार कार्यक्रम चलाया और सबसे तेज़ और सबसे धीमे मान लिए।



0

पर्ल, 44 बाइट्स

मुझे पता है कि यह कोड गोल्फ नहीं है, लेकिन मैं हमेशा एक साधारण द्विघात फ़ंक्शन के निम्न क्रम बिट्स लेने का प्रशंसक रहा हूं, जैसे:

$x=1/7;print substr($x*=4-4*$x,9,1)%2while 1

अवधि 3 बिलियन से अधिक है, लेकिन मैं अधिक गणना करने के लिए डिस्क स्थान से बाहर चला गया हूं।


1
आप सांख्यिक स्थिरांक और खोजशब्दों को $x=1/7;print substr($x*=4-4*$x,9,1)%2while 1
जुक्सपैप करके
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.