Rand5 () से Rand7 () [बंद]


29

आपको एक फ़ंक्शन Rand5 () प्रदान किया जाता है। यह फ़ंक्शन 1 और 5 के बीच पूरी तरह से यादृच्छिक (समान वितरण) पूर्णांक देता है।

फ़ंक्शन Rand7 () प्रदान करें, जो 1 और 7 के बीच पूरी तरह से यादृच्छिक पूर्णांक बनाने के लिए Rand5 () का उपयोग करता है।




1 और 5 समावेशी? सेट {1,2,3,4,5} से?
एरॉन मैकडैड 22

1
एकल विजेता कौन से मापदंड निर्धारित करता है?
कोजीरो

वह क्षण जब आपको एहसास होता है कि यह वास्तव में एक पुराना प्रश्न है।
nyuszika7h

जवाबों:


11

जावा - 61 वर्ण

int rand7(){int s=0,c=7;while(c-->0)s+=rand5();return s%7+1;}

सत्यापन के लिए टेस्ट ड्राइवर:

class Rand {

    public static void main(String[] args) {
        int[] nums = new int[7];
        // get a lot of numbers
        for(int i = 0; i < 10000000; i++) nums[rand7()-1]++;
        // print the results
        for(int i = 0; i < 7; i++) System.out.println((i+1) + ": " + nums[i]);
    }

    // just for rand5()
    static java.util.Random r = new java.util.Random();

    static int rand5() {
        return r.nextInt(5)+1; // Random.nextInt(n) returns 0..n-1, so add 1
    }

    static int rand7(){int s=0,c=7;while(c-->0)s+=rand5();return s%7+1;}

}

परिणाम

C:\Documents and Settings\glowcoder\My Documents>java Rand
1: 1429828
2: 1429347
3: 1428328
4: 1426486
5: 1426784
6: 1429853
7: 1429374

C:\Documents and Settings\glowcoder\My Documents>

10
"ऑपरेटर को जाता है" के लिए अतिरिक्त अंक
स्टीव पी

शेव करो? int rand7 () {के लिए (int s = 0, c = 7; c -> 0; s + = rand7 ()); वापसी s% 7 + 1;}
Ron

3
यह उत्तर सही नहीं है: 1 से 7 तक मान लौटाने वाले इस फ़ंक्शन की संभावनाएं क्रमशः 0.1430656, 0.1430016, 0.1428224, 0.1426432, 0.1426432, 0.1428224 और 0.1430016 हैं। हां, न्यूनतम और अधिकतम संभावनाओं के बीच का अंतर कम है कि 0.0005, लेकिन फिर भी, प्रश्न "पूरी तरह से यादृच्छिक पूर्णांक" निर्दिष्ट करता है।
इल्मरी करोनें

@ilmari आप सही कह रहे हैं - मैंने सिर्फ एक परीक्षा चलाई है और ऐसा लगता है कि वितरण भी नहीं है ... मुझे उस पर सोचने दें ...
corsiKa

1
@userunknown: हां, मैंने जो संभावनाएं पोस्ट की हैं, वे वास्तव में अनुमानित नहीं हैं, वे सटीक (0.1430656 = 11177/78125, आदि) बिल्कुल यादृच्छिक मानते हैं rand5। मैंने सरल मैट्रिक्स बीजगणित का उपयोग करके मेपल में उनकी गणना की, लेकिन आप चाहें तो इसे कुछ ही मिनटों में पेंसिल और पेपर के साथ कर सकते हैं। वैसे भी, यह पता चला है कि उमर ने कुछ दिनों पहले ही एक और जवाब के लिए एक ही आंकड़े (sans normalizing factor) को एक टिप्पणी में पोस्ट किया था। (इसके अलावा पी.एस., आप प्रति टिप्पणी केवल एक उपयोगकर्ता को सूचित नहीं कर सकते हैं, हालांकि पोस्ट के लेखक को किसी भी मामले में हमेशा सूचित किया जाता है।)
इल्मरी करोनें

7

पर्ल - ४ 47 (५२) वर्ण था

sub rand7{($x=5*&rand5+&rand5-3)<24?int($x/3):&rand7} 

साथ ही मुझे टर्नरी ऑपरेटर और रिकर्सन का उपयोग करने के लिए मिलता है। सबसे अच्छा दिन!

यदि आप div के बजाय mod का उपयोग करते हैं तो ठीक है, 47 char:

sub rand7{($x=5*&rand5+&rand5)<27?$x%7+1:&rand7} 

इतना करीब ... 30 को 27 (= 6 + 21) से बदलें और आपको पूरी तरह से समान वितरण मिलेगा। ओह, और आप अंतिम दो &संकेतों को नीचे गिराकर इसे 46 चार्ट तक ले जा सकते हैं (अंतरिक्ष सहित, जो आपके वर्तमान संस्करण को 48 पर रखता है)।
इल्मरी करोनें

7

जावास्क्रिप्ट, 42

Rand7=f=_=>(x=Rand5()+Rand5()*5-5)>7?f():x

बोनस ES5 बात:

Rand7=eval.bind(0,'for(;x=Rand5()+Rand5()*5-5,x>7;);x')

6

रूबी - 54 चार्ट (डैन मैकग्राथ समाधान पर आधारित, लूप का उपयोग करके)

def rand7;x=8;while x>7 do x=rand5+5*rand5-5 end;x;end

रूबी - 45 वर्ण (पुनरावृत्ति का उपयोग करके एक ही समाधान)

def rand7;x=rand5+5*rand5-5;x>7 ?rand7: x;end

का उपयोग करके 1 चर से छोटा किया जा सकता है (x=rand5+5*rand5-5)>7?
लार्स हागेथ


4

आम लिस्प में 70 अक्षर:

(defun rand7()(let((n(-(+(rand5)(* 5(rand5)))5)))(if(> n 7)(rand7)n)))

कोष्ठक मैं जितना चाहूंगा, उससे अधिक स्थान लेगा।


अच्छा लगा। आप ना ग्लोबल वैरिएबल बनाकर दो और पात्रों को निचोड़ सकते हैं:(defun rand7()(setq n(-(+(rand5)(* 5(rand5)))5))(if(> n 7)(rand7)n))
डॉ। दर्द

इससे भी बेहतर:(defun rand7()(if(>(setq n(-(+(rand5)(* 5(rand5)))5))7)(rand7)n))
डॉ। दर्द

4

अस्वीकृति के नमूने का उपयोग करते हुए c / c ++ में

int rand7(){int x=8;while(x>7)x=rand5()+5*rand5()-5;return x;}

62 अक्षर।


@barrycarter: शर्त यह है while(x>7), कि केवल मान्य सीमा में संख्याओं से संतुष्ट हो।
मेलमोकब

मेरी गलती। मेरी गूंगी टिप्पणी को हटा दिया।
बैरीकेटर

@barry और फिर आपने एक और छोड़ दिया। ;)
मतीन उलहाक

मुझे यह महसूस करने में कुछ मिनट लगे कि यहाँ का गणित एक समान यादृच्छिक वितरण कैसे उत्पन्न करता है जिसका उपयोग अस्वीकृति के नमूने के लिए किया जा सकता है।
डैनियल

3

PHP से अनुवाद, उत्तर से ny दान मैकग्राथ पोस्ट किया गया।

function Rand7(){$x=8;while($x>7)$x=rand5()+5*rand5()-5;return $x;}

67 अक्षर।


यह "फ़ंक्शन" (और एक स्थान) शब्द से उपसर्ग नहीं होना चाहिए?
jtjacques

हाँ ... और अब यह 67 अक्षर है ...
मार्क-फ्रांस्वा

3

आर, 34 अक्षर

आर में (सांख्यिकीय गणना के लिए बनाई गई भाषा), एक जानबूझकर धोखेबाज़ समाधान:

# Construct a Rand5 function
Rand5 <- function() sample(seq(5),1)
# And the golf
Rand7=function(r=Rand5())sample(1:(r/r+6),1)
# Or (same character count)
Rand7=function(r=Rand5())sample.int(r/r+6,1)
# Or even shorter(thanks to @Spacedman)
Rand7=function()sample(7)[Rand5()]

तर्कों के आलसी मूल्यांकन के लिए धन्यवाद, मैंने अर्धविराम और ब्रेसिज़ को समाप्त कर दिया।

10 ^ 6 से अधिक प्रतिकृति

> test <- replicate(10^6,Rand7())
> table(test)
test
     1      2      3      4      5      6      7 
142987 142547 143133 142719 142897 142869 142848 

library(ggplot2)
qplot(test)

परिणामों का हिस्टोग्राम


2
यदि आप धोखेबाज़ होने जा रहे हैं, तो आप सबसे अच्छे धोखेबाज़ हो सकते हैं:Rand7=function(){r=Rand5();sample(7)[r]}
Spacedman

यदि आप ऐसा करने जा रहे हैं, तो इंटरमीडिएट स्टोरेज से परेशान क्यों हैं? Rand7=function(){sample(7)[Rand5()]}
ब्रायन डिग्स

@BrianDiggs कार्रवाई में पथ-निर्भरता .... :-)
अरी बी। फ्रीडमैन

3

स्काला, 47, 40 59 वर्ण:

def rand7:Int={val r=5*(rand5-1)+rand5
if(r<8)r else rand7}

rand5 से 2 इनपुट के साथ:

\ 1 2 3 4 5 
1 1 2 3 4 5  
2 6 7 8 ..
3 11 ..
4 ..
5

मैं पहले 1 को 5 से गुणा करता हूं, और दूसरे को जोड़ता हूं। अधिकांश परिणामों को नजरअंदाज किया जाता है, और एक नई गणना के लिए नेतृत्व किया जाता है। परिणाम 1-25 से मूल्यों का समान वितरण होना चाहिए, जिसमें से मैं केवल पहले 7 को चुनता हूं। मैं एक मॉडुलो के निर्माण के साथ पहले 21 को स्वीकार कर सकता था, लेकिन इससे लंबा कोड होगा।

ऐतिहासिक कोड जो विफल रहा, लेकिन बहुत स्पष्ट रूप से नहीं। इसे इंगित करने के लिए इल्मारी करोनन का धन्यवाद:

def rand7=(1 to 7).map(_=>rand5).sum%7+1

इस scala-2.8.0-दृष्टिकोण के लिए योशेरु ताकेशिता के लिए धन्यवाद, जिसने 'योग' को इतना आसान बना दिया। इससे पहले मेरा समाधान:

def rand7=((0/:(1 to 7))((a,_)=>a+rand5-1))%7+1

rand5:

val rnd = util.Random 
def rand5 = rnd.nextInt (5) + 1


उपयोगकर्ता योशेरु ताकेशिता ने स्काला 2.8.0 या बाद के लिए 40 चार्ट में कमी करने का प्रस्ताव रखाdef rand7=(1 to 7).map(_=>rand5).sum%7+1
पीटर टेलर

यह समाधान भी सही नहीं है, टिप्पणियों को ग्लोकोडर के उत्तर में देखें
इल्मरी करोनें

@ इल्मारिकारोन: आप सही कह रहे हैं - मैंने अपना समाधान फिर से तैयार किया।
उपयोगकर्ता अज्ञात

3

सी ++

int Rand4()
{
    int r = Rand5();
    return r > 4 ? Rand4() : r;
}

inline int Rand8()
{    
    return (Rand4() - 1) << 2 + Rand4();
}

int Rand7()
{
    int r = Rand8();
    return r > 7 ? Rand7() : r;
}

सी ++ (109)

golfed

int Rand4(){int r=Rand5();return r>4?Rand4():r;}int Rand7(){int r=Rand4()-1<<2+Rand4();return r>7?Rand7():r;}

मुझे नहीं लगता कि आप कह सकते हैं कि "एक लाइनर" क्योंकि सेमीकोल सी ++ में कोड की एक पंक्ति को परिभाषित करता है।
पीटर ओल्सन

@ अच्छी तरह से ओह, यह भी अब एक लाइनर की आवश्यकता नहीं है।
मतीन उल्हाक

इसने 1 से 8. तक एक नंबर लौटाया
jimmy23013

2

दान मैकग्राथ द्वारा पोस्ट किए गए उत्तर से जावास्क्रिप्ट का अनुवाद।

function Rand7(){x=8;while(x>7)x=rand5()+5*rand5()-5;return x}

62 चरस


1
function Rand7(){for(x=8;x>7;x=rand5()+5*rand5()-5);return x}थोड़ा छोटा है: P
JiminP

2

जावास्क्रिप्ट, 85

function Rand7(){for(x=0,i=1;i<8;x^=i*((k=Rand5())%2),i*=1+(k<5));return x?x:Rand7()}

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


2

С ++

int Rand7()
{
    int r = Rand5();
    int n = 5;
    do {
        r = (r - 1) * 5 + Rand5();
        int m = n * 5 / 7 * 7;
        if (r <= m) {
            return r % 7 + 1;
        }
        r -= m;
        n = n * 5 - m;
    } while (1);
}

संख्या वितरण (1000000 पूर्णांक):

142935 142751 142652 143299 142969 142691 142703

Rand5 () पर हर जेनरेट किए गए पूर्णांक पर कॉल की औसत संख्या लगभग 2.2 (2 से 10+) है।

1 2      3      4     5    6   7 8  9 10
0 840180 112222 44433 2212 886 0 60 6 1

2

जावा (या C / C ++ में)

  • अलेक्जेंड्रू द्वारा 65 वर्णों में पीढ़ी के सूत्र का उपयोग:

    int rand7(){int x=rand5()*5+rand5()-6;return x>20?rand7():x/3+1;}
    
  • 60 अक्षरों में डैन मैकग्राथ द्वारा पीढ़ी के सूत्र का उपयोग करना

    int rand7(){int x=rand5()+5*rand5()-5;return x>7?rand7():x;}
    

1

क्लोजर - 58 वर्ण

(defn rand7[](#(if(<% 8)%(rand7))(+(rand5)(*(rand5)5)-5)))

1

पायथन, 56 37 वर्ण

एक और उपाय जो गलत हो सकता है, वह पायथन में:

rand7 = lambda: sum(rand5() for i in range(7)) % 7 + 1

यह बहुत आसान लगता है, लेकिन जब मैं कोशिश करता हूं:

counter = [0] * 7
for i in range(100000):
     counter[rand7()] += 1

मुझे एक समान रूप से वितरण मिलता है (सभी 14000 और 14500 के बीच)।

ठीक है, अब जैसे किसी ने इस पद के लिए मतदान किया है: क्या यह समाधान वास्तव में सही है? लोगों की आलोचना करने के लिए मैंने इसे यहां पोस्ट किया। ठीक है, अगर यह सही है, तो मेरा गोल्फ संस्करण होगा:

rand7=lambda:eval("+rand5()"*7)%7+1

जो 37 वर्णों तक आता है।


आपका समाधान सही नहीं है: आप अपने निर्णय को एक निष्पक्ष 5-पक्षीय मरने के 7 रोल पर आधारित करते हैं, जिसका अर्थ है कि 5 ^ 7 (5 से 7 वीं शक्ति) के परिवर्तनीय परिणाम हैं। चूंकि यह 7 का एक से अधिक नहीं है, आप 7 परिवर्तनीय परिणाम वापस नहीं कर सकते। मुझे नहीं लगता कि आप जो लौटाते हैं उसका एक आसान सूत्र है; आप संगणना को कम-से-कम कर सकते हैं या इसे छोटी संख्याओं पर हाथ से निकाल सकते हैं (3 सिक्के (H = 1, T = 2) और परिणाम जोड़ सकते हैं)।
गिल्स एसओ- बुराई को रोकना '

1
वाह, आप जो वितरण करते हैं, हालांकि, समान नहीं है, उल्लेखनीय रूप से करीब है: प्रत्येक संख्या की संभावनाओं का सटीक अनुपात {1: 11177, 2: 11172, 3: 11158, 4: 11144, 5: 11174, 6: 11158, है। 7: 11172}
उमर



1

पर्ल, 43 वर्ण, पुनरावृत्ति अस्वीकृति नमूना

sub rand7{1while($_=5*&rand5-rand5)>6;$_+1}

यह एक चेतावनी देता है Ambiguous use of -rand5 resolved as -&rand5(), लेकिन सही तरीके से काम करता है। &दूसरी rand5कॉल को भी प्रीपेंडिंग करना एक स्ट्रोक की कीमत पर इसे ठीक करता है। (इसके विपरीत, यदि प्रोटोटाइप के साथ परिभाषित किया गया &है तो दूसरे को भी हटाया जा सकता है ।)rand5()

Ps। निम्नलिखित 46-चार संस्करण लगभग तीन गुना तेज है:

sub rand7{1while($_=5*&rand5-rand5)>20;$_%7+1}

1

जावा - 66 वर्ण

int rand7(){int s;while((s=rand5()*5+rand5())<10);return(s%7+1);}

पिछली दिनचर्या की तुलना में लंबा है, लेकिन मुझे लगता है कि यह कम समय में समान रूप से वितरित संख्या देता है।


1

पोस्टस्क्रिप्ट (46)

यह बाइनरी टोकन एन्कोडिंग का उपयोग करता है, इसलिए, यहां एक हेक्सडंप है:

00000000  2f 72 61 6e 64 37 7b 38  7b 92 38 37 92 61 7b 92  |/rand7{8{.87.a{.|
00000010  40 7d 69 66 92 75 32 7b  72 61 6e 64 35 7d 92 83  |@}if.u2{rand5}..|
00000020  35 92 6c 92 01 35 92 a9  7d 92 65 7d 92 33        |5.l..5..}.e}.3|
0000002e

इसे आज़माने के लिए, आप इसे डाउनलोड भी कर सकते हैं ।

यहाँ परीक्षण कोड के साथ असंगठित और टिप्पणी कोड है।

% This is the actual rand7 procedure.
/rand7{
  8{                      % potentialResult
    % only if the random number is less than or equal to 7, we're done
    dup 7 le{             % result
      exit                % result
    }if                   % potentialResult
    pop                   % -/-
    2{rand5}repeat        % randomNumber1 randomNumber2
    5 mul add 5 sub       % randomNumber1 + 5*randomNumber2 - 5 = potentialResult
  }loop
}def

%Now, some testing code.

% For testing, we use the built-in rand operator; 
% Doesn't really give a 100% even distribution as it returns numbers
% from 0 to 2^31-1, which is of course not divisible by 5.
/rand5 {
  rand 5 mod 1 add
}def

% For testing, we initialize a dict that counts the number of times any number
% has been returned. Of course, we start the count at 0 for every number.
<<1 1 7{0}for>>begin

% Now we're calling the function quite a number of times 
% and increment the counters accordingly.
1000000 {
  rand7 dup load 1 add def
}repeat

% Print the results
currentdict{
  2 array astore ==
}forall

-1
int result = 0;

for (int i = 0; i++; i<7)
    if (((rand(5) + rand(5)) % 2) //check if odd
        result += 1;

return result + 1;

2
यह एक समान वितरण नहीं देगा। रैंड के वितरण पर देखो (5) + रैंड (5) 10000 से अधिक पुनरावृत्तियों को देखने के लिए क्यों
gnibbler

परिणाम आपके कोड में 1 से 8 तक कोई भी संख्या हो सकती है ...
उमर

इसके अलावा, जैसा कि gnibbler ने कहा, वितरण समान नहीं है: (रैंड (5) + रैंड (5))% 2 0 की ओर से पक्षपाती है, यह 1 उत्पादन करने वाले प्रत्येक 12 बार के लिए 0 13 बार उत्पादन करता है; यानी, संभाव्यताएं {0: 13, 1: 12} के समानुपाती हैं। उस अंकन के साथ, आपके कार्य के लिए प्रबलताएँ {1: 62748517, 2: 405451956, 3: 1122790032, 4: 1727369280, 5: 1594494720, 6: 883104768, 7: 271724544, 8: 35831808} (आनुपातिक अनुपात) हैं। बड़ी संख्या)। या, 6 बार चलाने के लिए लूप को ठीक करना, {1: 4826809, 2: 26733096, 3: 61691760, 4: 75928320, 5: 52565760, 6: 19408896, 7, 2985984}
उमर

-1

आर (30 अक्षर)

रैंड 7 को परिभाषित करें:

rand7=function(n)sample(7,n,T)

क्योंकि R को सांख्यिकीय विश्लेषण को ध्यान में रखते हुए लिखा गया था, यह कार्य तुच्छ है, और मैं sampleTRUE में प्रतिस्थापन के साथ अंतर्निहित फ़ंक्शन का उपयोग करता हूं ।

नमूना उत्पादन:

> rand7(20)
 [1] 4 3 6 1 2 4 3 2 3 2 5 1 4 6 4 2 4 6 6 1
> rand7(20)
 [1] 1 2 5 2 6 4 6 1 7 1 1 3 7 6 4 7 4 2 1 2
> rand7(20)
 [1] 6 7 1 3 3 1 5 4 3 4 2 1 5 4 4 4 7 7 1 5

1
यह कहता है कि आपको Rand5 का उपयोग करना होगा। कैसे नहीं कहता है, लेकिन आपको इसका उपयोग करना होगा ...
Spacedman 18

@Spacedman हां, मैंने स्पष्ट रूप से इसे नजरअंदाज कर दिया था। यह गैर-संदर्भ द्वारा उपयोग किया जाता है।
एंड्री

-1

ग्रूवी

rand7={if(b==null)b=rand5();(b=(rand5()+b)%7+1)}

35,000 पुनरावृत्तियों पर उदाहरण वितरण:

[1:5030, 2:4909, 3:5017, 4:4942, 5:5118, 6:4956, 7:5028]

क्या यह बुरा है कि यह राज्य है?



-1

इस बारे में कैसा है?

int Rand7()
{
    return Rand5()+ Rand5()/2;
}

जो भी भाषा है, क्या उसका /ऑपरेटर पूर्णांक गणित करता है? यदि यह दशमलव, फ़्लोटिंग-पॉइंट या पूर्णांक गणित करता है तो आपके परिणामों का क्या होता है?
कोजीरो

पूर्णांक विभाजन मानते हुए, इस फ़ंक्शन का निम्न वितरण है [2/25, 4/25, 5/25, 5/25, 5/25, 3/25, 1/25]:। बिल्कुल समान नहीं।
प्रिमो

प्राइमो सही है। यादृच्छिक संख्याओं को जोड़ना आम तौर पर मध्य मूल्यों की ओर संभावनाओं को तिरछा करना है।
सूक्ति

-1

जावा - ५४

int m=0;int rand7(){return(m=m*5&-1>>>1|rand5())%7+1;}

वितरण परीक्षण: [1000915, 999689, 999169, 998227, 1001653, 1000419, 999928]

कलन विधि:

  • एक वैश्विक चर रखें
  • 5 से गुणा करें, ताकि कम से कम महत्वपूर्ण अंत में 5 स्थान मुफ्त मिलें
  • इसे सकारात्मक बनाने के लिए साइन बिट को काटें (यदि आवश्यक संख्याओं का समर्थन किया गया हो तो आवश्यक नहीं)
  • मोडुलो 7 जवाब है

> संख्या अब परस्पर असंबद्ध नहीं हैं, लेकिन व्यक्तिगत रूप से पूरी तरह यादृच्छिक हैं।


-1

रूबी (43 बाइट्स)

def rand7;(0..7).reduce{|i|i+rand5}%7+1;end

रूबी के लिए रखी गई cemper93 का घोल तीन बाइट्स छोटा है;) (34 बाइट्स)

def rand7;eval("+rand5"*7)%7+1;end

-3

C / C ++ कोड में कोर कोड की एक ही लाइन होती है!

static unsigned int gi = 0;

int rand7()
{
    return (((rand() % 5 + 1) + (gi++ % 7)) % 7) + 1;
}

//call this seed before rand7
//maybe it's not best seed, if yo have any good idea tell me please
//and thanks JiminP again, he remind me to do this
void srand7()
{
    int i, n = time(0);
    for (i = 0; i < n % 7; i++)
        rand7();
}

Srand7 () रैंड 7 का बीज है, रैंड 7 से पहले इस फ़ंक्शन को कॉल करना चाहिए, जैसे C में रैंड से पहले कॉल srand।

यह एक बहुत अच्छा है, क्योंकि यह रैंड () को केवल एक बार कॉल करता है, और कोई लूप चीज नहीं है, कोई अतिरिक्त यादों का विस्तार नहीं करता है।

मुझे इसे समझाने दें: 5 के आकार के साथ एक पूर्णांक सरणी पर विचार करें:

1st get one number from 1 2 3 4 5 by rand5
2nd get one number from 2 3 4 5 6
3rd get one number from 3 4 5 6 7
4th get one number from 4 5 6 7 1
5th get one number from 5 6 7 1 2
5th get one number from 6 7 1 2 3
7th get one number from 7 1 2 3 4

तो हमें TABLE मिला, प्रत्येक 1-7 में से एक इसमें 5 बार दिखाई देता है, और इसमें सभी 35 नंबर हैं, इसलिए प्रत्येक नंबर की संभावना 5/35 = 1/7 है। और अगली बार,

8th get one number from 1 2 3 4 5
9th get one number from 2 3 4 5 6
......

पर्याप्त समय के बाद, हम 1-7 का समान वितरण प्राप्त कर सकते हैं।

तो, हम लूप-लेफ्ट-शिफ्ट द्वारा 1-7 के पांच तत्वों को पुनर्स्थापित करने के लिए एक सरणी आवंटित कर सकते हैं, और rand5 द्वारा हर बार सरणी से एक नंबर प्राप्त कर सकते हैं। इसके बजाय, हम पहले सभी सात सरणियों को उत्पन्न कर सकते हैं, और उन्हें परिपत्र रूप से उपयोग कर सकते हैं। कोड सरल भी है, कई छोटे कोड ऐसा कर सकते हैं।

लेकिन, हम% संचालन के गुणों का उपयोग कर सकते हैं, इसलिए तालिका 1-7 पंक्तियाँ (rand5 + i)% 7 के बराबर हैं, अर्थात: a = rand ()% 5 + 1 C भाषा में rand5 है, b = gi ++ % 7 ऊपर की तालिका में सभी क्रमपरिवर्तन उत्पन्न करता है, और 0 - 6 1 - 7 सी = (ए + बी)% 7 + 1 को प्रतिस्थापित करता है, समान रूप से 1 - 7 उत्पन्न करता है। अंत में, हमें यह कोड मिला:

(((rand() % 5 + 1) + (gi++ % 7)) % 7) + 1 

लेकिन, हमें पहली कॉल पर 6 और 7 नहीं मिल सकते हैं, इसलिए हमें सी / सी ++ में रैंड के लिए कुछ बीज की जरूरत है, पहले औपचारिक कॉल के लिए परमिट की व्यवस्था करने के लिए।

यहाँ परीक्षण के लिए पूर्ण कोड है:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

static unsigned int gi = 0;

//a = rand() % 5 + 1 is rand5 in C language,
//b = gi++ % 7 generates all permutations,
//c = (a + b) % 7 + 1, generates 1 - 7 uniformly.
//Dont forget call srand7 before rand7
int rand7()
{
   return (((rand() % 5 + 1) + (gi++ % 7)) % 7) + 1;
}

//call this seed before rand7
//maybe it's not best seed, if yo have any good idea tell me please
//and thanks JiminP again, he remind me to do this
void srand7()
{
    int i, n = time(0);
    for (i = 0; i < n % 7; i++)
        rand7();
}

void main(void)
{
    unsigned int result[10] = {0};
    int k;

    srand((unsigned int)time(0)); //initialize the seed for rand
    srand7() //initialize the rand7

    for (k = 0; k < 100000; k++)
        result[rand7() - 1]++;

    for (k = 0; k < 7; k++)
        printf("%d : %.05f\n", k + 1, (float)result[k]/100000);
}

यह 'परीक्षण' पास करता है, लेकिन इसका मतलब यह नहीं है कि यह एक अच्छा यादृच्छिक कार्य है। मैं प्राप्त कर सकते हैं 6या 7यह फोन करके एक बार ?
13

लेकिन अच्छे प्रकार और खराब प्रकार के अनुमान हैं। और यह कोड खराब है - क्योंकि यह केवल एक बार कॉल करने पर समान वितरण नहीं देता है। अगर किसी ने कुछ लिखा है int main(){if(rand7()==6) printf("Hello, world!");}, तो लूप का उपयोग करते हुए सन्निकटन 'हैलो, दुनिया!' 7 बार में 1, लेकिन आपका कोड नहीं है।
14

शुक्रिया @JiminP! आप पहली बार में 6,7 के लिए सही हैं। मुझे कॉल करने से पहले बीज को व्यवस्थित करने की आवश्यकता है रैंड 7, सी / सी ++ में सरंड की तरह ही बीज। मैंने अपना कोड तय किया, और फिर से शुक्रिया !!!
शॉन

एचएम .... srand10 काम नहीं करता है, अंतिम 3 नंबर 10, 20, 30 ... पदों पर नहीं मिल सकता है। क्षमा करें @JiminP, लेकिन इसे कैसे संशोधित किया जाए? मुझे लगता है कि यह उम्मीद भरा तरीका है।
शॉन

2
इस फ़ंक्शन के लिए अलग-अलग कॉल एक-दूसरे से स्वतंत्र नहीं हैं। यहाँ कल्पना के लिए इसकी आवश्यकता नहीं है, लेकिन यह आमतौर पर यादृच्छिक संख्या जनरेटर का जोखिम है। अन्यथा, आप कह सकते हैं, पहली बार एक यादृच्छिक वर्दी संख्या लौटाएं और भविष्य में कॉल करें बस वापस (पिछले + 1)% 7 ...
उमर
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.