आपको एक फ़ंक्शन Rand5 () प्रदान किया जाता है। यह फ़ंक्शन 1 और 5 के बीच पूरी तरह से यादृच्छिक (समान वितरण) पूर्णांक देता है।
फ़ंक्शन Rand7 () प्रदान करें, जो 1 और 7 के बीच पूरी तरह से यादृच्छिक पूर्णांक बनाने के लिए Rand5 () का उपयोग करता है।
आपको एक फ़ंक्शन Rand5 () प्रदान किया जाता है। यह फ़ंक्शन 1 और 5 के बीच पूरी तरह से यादृच्छिक (समान वितरण) पूर्णांक देता है।
फ़ंक्शन Rand7 () प्रदान करें, जो 1 और 7 के बीच पूरी तरह से यादृच्छिक पूर्णांक बनाने के लिए Rand5 () का उपयोग करता है।
जवाबों:
जावा - 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>
rand5
। मैंने सरल मैट्रिक्स बीजगणित का उपयोग करके मेपल में उनकी गणना की, लेकिन आप चाहें तो इसे कुछ ही मिनटों में पेंसिल और पेपर के साथ कर सकते हैं। वैसे भी, यह पता चला है कि उमर ने कुछ दिनों पहले ही एक और जवाब के लिए एक ही आंकड़े (sans normalizing factor) को एक टिप्पणी में पोस्ट किया था। (इसके अलावा पी.एस., आप प्रति टिप्पणी केवल एक उपयोगकर्ता को सूचित नहीं कर सकते हैं, हालांकि पोस्ट के लेखक को किसी भी मामले में हमेशा सूचित किया जाता है।)
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}
&
संकेतों को नीचे गिराकर इसे 46 चार्ट तक ले जा सकते हैं (अंतरिक्ष सहित, जो आपके वर्तमान संस्करण को 48 पर रखता है)।
रूबी - 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
(x=rand5+5*rand5-5)>7?
।
पायथन में:
def Rand7():
while True:
x = (Rand5() - 1) * 5 + (Rand5() - 1)
if x < 21: return x/3 + 1
आम लिस्प में 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))
अस्वीकृति के नमूने का उपयोग करते हुए c / c ++ में
int rand7(){int x=8;while(x>7)x=rand5()+5*rand5()-5;return x;}
62 अक्षर।
while(x>7)
, कि केवल मान्य सीमा में संख्याओं से संतुष्ट हो।
PHP से अनुवाद, उत्तर से ny दान मैकग्राथ पोस्ट किया गया।
function Rand7(){$x=8;while($x>7)$x=rand5()+5*rand5()-5;return $x;}
67 अक्षर।
आर में (सांख्यिकीय गणना के लिए बनाई गई भाषा), एक जानबूझकर धोखेबाज़ समाधान:
# 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)
Rand7=function(){r=Rand5();sample(7)[r]}
Rand7=function(){sample(7)[Rand5()]}
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
def rand7=(1 to 7).map(_=>rand5).sum%7+1
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;
}
int Rand4(){int r=Rand5();return r>4?Rand4():r;}int Rand7(){int r=Rand4()-1<<2+Rand4();return r>7?Rand7():r;}
दान मैकग्राथ द्वारा पोस्ट किए गए उत्तर से जावास्क्रिप्ट का अनुवाद।
function Rand7(){x=8;while(x>7)x=rand5()+5*rand5()-5;return x}
62 चरस
function Rand7(){for(x=8;x>7;x=rand5()+5*rand5()-5);return x}
थोड़ा छोटा है: P
function Rand7(){for(x=0,i=1;i<8;x^=i*((k=Rand5())%2),i*=1+(k<5));return x?x:Rand7()}
मुझे पता है कि इसका छोटा जवाब है, लेकिन मैं इस पहेली का परीक्षण दिखाना चाहता था । यह पता चला है कि डैन मैकग्रा के अस्वीकृति नमूने का उपयोग करके केवल क्लाइड लोबो का जवाब सही है (जेएस उत्तरों के बीच)।
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
एक और उपाय जो गलत हो सकता है, वह पायथन में:
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 वर्णों तक आता है।
जावा, 65 वर्ण:
int rand7(){int r;do{r=rand5()+5*rand5()-5;}while(r>7);return r;}
def rand7():
while True:
n=5*(rand5()-1)+(rand5()-1)
if n<21:return n%7+1
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}
int rand7(){int s;while((s=rand5()*5+rand5())<10);return(s%7+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
int result = 0;
for (int i = 0; i++; i<7)
if (((rand(5) + rand(5)) % 2) //check if odd
result += 1;
return result + 1;
रैंड 7 को परिभाषित करें:
rand7=function(n)sample(7,n,T)
क्योंकि R को सांख्यिकीय विश्लेषण को ध्यान में रखते हुए लिखा गया था, यह कार्य तुच्छ है, और मैं sample
TRUE में प्रतिस्थापन के साथ अंतर्निहित फ़ंक्शन का उपयोग करता हूं ।
नमूना उत्पादन:
> 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
इस बारे में कैसा है?
int Rand7()
{
return Rand5()+ Rand5()/2;
}
/
ऑपरेटर पूर्णांक गणित करता है? यदि यह दशमलव, फ़्लोटिंग-पॉइंट या पूर्णांक गणित करता है तो आपके परिणामों का क्या होता है?
[2/25, 4/25, 5/25, 5/25, 5/25, 3/25, 1/25]
:। बिल्कुल समान नहीं।
int m=0;int rand7(){return(m=m*5&-1>>>1|rand5())%7+1;}
वितरण परीक्षण:
[1000915, 999689, 999169, 998227, 1001653, 1000419, 999928]
कलन विधि:
> संख्या अब परस्पर असंबद्ध नहीं हैं, लेकिन व्यक्तिगत रूप से पूरी तरह यादृच्छिक हैं।
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
यह फोन करके एक बार ?
int main(){if(rand7()==6) printf("Hello, world!");}
, तो लूप का उपयोग करते हुए सन्निकटन 'हैलो, दुनिया!' 7 बार में 1, लेकिन आपका कोड नहीं है।