Rand5 () đến Rand7 () [đã đóng]


29

Bạn được cung cấp một hàm Rand5 (). Hàm này trả về các số nguyên hoàn toàn ngẫu nhiên (phân phối bằng nhau) từ 1 đến 5.

Cung cấp hàm Rand7 (), sử dụng Rand5 () để tạo ra các số nguyên hoàn toàn ngẫu nhiên trong khoảng từ 1 đến 7.




Bao gồm 1 và 5? tức là từ tập {1,2,3,4,5}?
Aaron McDaid

1
Tiêu chí nào quyết định một người chiến thắng?
kojiro

Khoảnh khắc đó khi bạn nhận ra đây thực sự là một câu hỏi cũ.
nyuszika7h

Câu trả lời:


11

Java - 61 ký tự

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

Kiểm tra trình điều khiển để xác nhận:

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ác kết quả

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
Thêm điểm cho "đi đến nhà điều hành"
Steve P

cạo một char? int rand7 () {for (int s = 0, c = 7; c -> 0; s + = rand5 ()); trả về s% 7 + 1;}
Ron

3
Câu trả lời này không chính xác: xác suất của hàm này trả về các giá trị từ 1 đến 7 lần lượt là 0.1430656, 0.1430016, 0.1428224, 0.1426432, 0.1426432, 0.1428224 và 0.1430016. Có, sự khác biệt giữa xác suất tối thiểu và tối đa là 0,0005, nhưng vẫn là câu hỏi được chỉ định "số nguyên hoàn toàn ngẫu nhiên".
Ilmari Karonen

@ilmari Bạn nói đúng - Tôi chỉ cần chạy một kiểm tra và có vẻ như sự phân bố không phải là thậm chí ... hãy để tôi nghĩ về điều đó ...
corsiKa

1
@userunknown: Có, xác suất tôi đã đăng thực sự không phải là xấp xỉ, chúng chính xác (0,1430656 = 11177/78125, v.v.) giả sử hoàn toàn ngẫu nhiên rand5. Tôi đã tính toán chúng trong Maple bằng cách sử dụng đại số ma trận đơn giản, nhưng bạn có thể làm điều đó bằng bút chì và giấy trong vài phút nếu bạn muốn. Dù sao, hóa ra Omar đã đăng những con số tương tự (yếu tố bình thường hóa) trong một bình luận cho một câu trả lời khác vài ngày trước đó. (Ngoài ra ps., Bạn chỉ có thể @notify một người dùng cho mỗi bình luận, mặc dù tác giả của bài đăng luôn được thông báo trong mọi trường hợp.)
Ilmari Karonen

7

Perl - 47 (là 52) ký tự

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

Thêm vào đó tôi có thể sử dụng toán tử ternary VÀ đệ quy. Tốt nhất ... ngày ... bao giờ!

OK, 47 ký tự nếu bạn sử dụng mod thay vì div:

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

Rất gần ... thay thế 30 bằng 27 (= 6 + 21) và bạn sẽ có được phân phối đồng đều hoàn hảo. Ồ, và bạn có thể bỏ hai &dấu hiệu cuối cùng để giảm xuống 46 ký tự (bao gồm cả khoảng trắng, đặt phiên bản hiện tại của bạn ở mức 48).
Ilmari Karonen

7

JavaScript, 42

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

Phần thưởng ES5:

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

6

Ruby - 54 ký tự (dựa trên giải pháp Dan McGrath, sử dụng vòng lặp)

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

Ruby - 45 ký tự (cùng một giải pháp, sử dụng đệ quy)

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

Có thể rút ngắn 1 char bằng cách sử dụng (x=rand5+5*rand5-5)>7?.
Lars Haugseth

5

Trong Python:

def Rand7():
  while True:
    x = (Rand5() - 1) * 5 + (Rand5() - 1)
    if x < 21: return x/3 + 1

4

Trong Common Lisp 70 ký tự:

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

Dấu ngoặc đơn chiếm nhiều không gian hơn tôi muốn.


Tốt đẹp. Bạn có thể vắt kiệt thêm hai nhân vật bằng cách biến na toàn cầu:(defun rand7()(setq n(-(+(rand5)(* 5(rand5)))5))(if(> n 7)(rand7)n))
Tiến sĩ Pain

Thậm chí tốt hơn:(defun rand7()(if(>(setq n(-(+(rand5)(* 5(rand5)))5))7)(rand7)n))
Bác sĩ Pain

4

Trong c / c ++ sử dụng lấy mẫu từ chối

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

62 ký tự.


@barrycarter: Điều kiện là while(x>7), do đó sẽ chỉ được thỏa mãn bởi các số trong phạm vi hợp lệ.
mellamokb

Lỗi của tôi. Xóa bình luận ngu ngốc của tôi.
barrycarter

@barry Và sau đó bạn để lại một cái khác. ;)
Mateen Ulhaq

Phải mất vài phút tôi mới nhận ra toán học ở đây tạo ra phân phối ngẫu nhiên đồng đều có thể được sử dụng để lấy mẫu từ chối như thế nào.
Daniel

3

Dịch sang PHP, từ câu trả lời được đăng ny Dan McGrath.

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

67 ký tự.


Điều này không nên được tiền tố bởi từ "chức năng" (và một khoảng trắng)?
jtjacques

Vâng ... và bây giờ là 67 ký tự ...
Marc-François

3

R, 34 ký tự

Trong R (một ngôn ngữ được xây dựng để tính toán thống kê), một giải pháp gian lận có chủ ý:

# 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()]

Nhờ lười đánh giá các lập luận, tôi đã loại bỏ dấu chấm phẩy và niềng răng.

Đầu ra trên 10 ^ 6 lần lặp lại:

> 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)

biểu đồ kết quả


2
Nếu bạn sẽ gian lận, bạn cũng có thể là người lừa đảo tốt nhất bạn có thể:Rand7=function(){r=Rand5();sample(7)[r]}
Spainedman

Nếu bạn sẽ làm điều đó, tại sao phải bận tâm với việc lưu trữ trung gian? Rand7=function(){sample(7)[Rand5()]}
Brian Diggs

@BrianDiggs Sự phụ thuộc vào đường dẫn trong hành động .... :-)
Ari B. Friedman

3

scala, 47, 40 59 ký tự:

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

với 2 đầu vào từ rand5:

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

Tôi nhân số 1 với 5 và thêm số thứ hai. Hầu hết các kết quả được bỏ qua, và dẫn đến một tính toán mới. Kết quả phải là một phân phối giá trị bằng nhau từ 1-25, từ đó tôi chỉ chọn 7 giá trị đầu tiên. Tôi có thể chấp nhận 21 đầu tiên với việc xây dựng một modulo, nhưng điều này sẽ dẫn đến mã dài hơn.

mã lịch sử đã thất bại, nhưng không rõ ràng lắm. Cảm ơn Ilmari Karonen đã chỉ ra:

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

Cảm ơn Yoshiteru Takeshita, vì cách tiếp cận scala-2.8.0 này đã khiến cho 'tổng' trở nên dễ dàng. Giải pháp của tôi trước đây:

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

rand5:

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


Người dùng Yoshiteru Takeshita đề xuất giảm xuống 40 ký tự cho Scala 2.8.0 trở lên làdef rand7=(1 to 7).map(_=>rand5).sum%7+1
Peter Taylor

Giải pháp này cũng không đúng, xem các bình luận để trả lời của Glowcoder .
Ilmari Karonen

@IlmariKaronen: Bạn nói đúng - Tôi đã làm lại giải pháp của mình.
người dùng không xác định

3

C ++

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;
}

C ++ (109)

Chơi gôn

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

Tôi thực sự không nghĩ rằng bạn có thể gọi đó là "một lớp lót" bởi vì dấu chấm phẩy xác định một dòng mã trong C ++.
Peter Olson

@Peter Oh tốt, nó thậm chí không yêu cầu một lớp nữa.
Mateen Ulhaq

Nó trả về một số từ 1 đến 8.
jimmy23013

2

Dịch sang Javascript, từ câu trả lời được đăng bởi Dan McGrath.

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

62 ký tự


1
function Rand7(){for(x=8;x>7;x=rand5()+5*rand5()-5);return x}ngắn hơn một chút: P
JiminP

2

JavaScript, 85

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

Tôi biết có câu trả lời ngắn hơn, nhưng tôi muốn thể hiện bài kiểm tra của câu đố này. Hóa ra chỉ có câu trả lời của Clyde Lobo khi sử dụng mẫu từ chối của Dan McGrath là chính xác (giữa các câu trả lời của JS).


2

C ++

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);
}

Phân phối số (1000000 số nguyên):

142935 142751 142652 143299 142969 142691 142703

Số lượng cuộc gọi trung bình đến Rand5 () trên mỗi số nguyên được tạo là khoảng 2,2 (2 đến 10+).

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

2

Trong Java (hoặc C / C ++ tôi cho rằng)

  • sử dụng công thức thế hệ của Alexandru, trong 65 ký tự:

    int rand7(){int x=rand5()*5+rand5()-6;return x>20?rand7():x/3+1;}
    
  • sử dụng công thức thế hệ của Dan McGrath, với 60 ký tự

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

1

Clojure - 58 ký tự

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

1

Python, 56 37 ký tự

Một giải pháp khác có thể sai, trong Python:

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

Điều này có vẻ quá đơn giản, nhưng khi tôi thử:

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

Tôi nhận được một phân phối hợp lý thậm chí (tất cả trong khoảng từ 14000 đến 14500).

Được rồi, bây giờ như ai đó đã bình chọn cho bài đăng này: Giải pháp này có thực sự đúng không? Tôi nhiều hơn đăng này ở đây để làm cho mọi người chỉ trích nó. Chà, nếu nó đúng, phiên bản chơi gôn của tôi sẽ là:

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

mà đi ra đến 37 ký tự.


Giải pháp của bạn là không chính xác: bạn đưa ra quyết định của mình dựa trên 7 cuộn chết 5 mặt công bằng, điều đó có nghĩa là có kết quả có thể trang bị được 5 ^ 7 (5 đến 7). Vì đây không phải là bội số của 7, nên bạn không thể trả về 7 kết quả có thể trang bị. Tôi không nghĩ rằng có một công thức dễ dàng cho những gì bạn trở lại; bạn có thể bắt buộc tính toán hoặc xử lý nó bằng tay với số lượng nhỏ hơn (lật 3 đồng xu (H = 1, T = 2) và tính tổng kết quả).
Gilles 'SO- ngừng trở nên xấu xa'

1
Ồ, phân phối bạn tạo, mặc dù không đồng nhất, rất gần: tỷ lệ chính xác của xác suất của mỗi số là {1: 11177, 2: 11172, 3: 11158, 4: 11144, 5: 11144, 6: 11158, 7: 11172}
Omar


1

Con trăn, 70 ký tự

def rand7():
 while True:
  n=5*(rand5()-1)+(rand5()-1)
  if n<21:return n%7+1

nhưng hoàn toàn chính xác dựa trên lý luận ở đây .


1

Perl, 43 ký tự, lấy mẫu từ chối lặp

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

Điều này đưa ra một cảnh báo về Ambiguous use of -rand5 resolved as -&rand5(), nhưng hoạt động chính xác. Chuẩn bị một cuộc gọi &thứ hai cũng rand5sửa nó với chi phí của một đột quỵ. (Ngược lại, cái khác &cũng có thể được gỡ bỏ nếu rand5 đã được xác định bằng một ()nguyên mẫu.)

Thi thiên Phiên bản 46 char sau đây nhanh hơn khoảng ba lần:

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

1

Java - 66 ký tự

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

Lâu hơn so với thói quen trước đây, nhưng tôi nghĩ rằng điều này trả về số lượng phân phối đồng đều trong thời gian ít hơn.


1

PostScript (46)

Điều này sử dụng mã hóa mã thông báo nhị phân, do đó, đây là một hexdump:

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

Để dùng thử, bạn cũng có thể tải xuống .

Đây là mã không được nhận xét và nhận xét, cùng với mã kiểm tra.

% 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
Điều này sẽ không cung cấp một phân phối thống nhất. Nhìn vào sự phân phối của rand (5) + rand (5) trên 10000 lần lặp để xem tại sao
gnibbler

kết quả có thể là bất kỳ số nào từ 1 đến 8 trong mã của bạn ...
Omar

Thêm vào đó, như gnibbler đã nói, phân phối không đồng nhất: (rand (5) + rand (5))% 2 được thiên về 0, nó tạo ra 0 13 lần cho mỗi 12 lần nó tạo ra 1; tức là, xác suất tỷ lệ thuận với {0: 13, 1: 12}. Với ký hiệu đó, sự cân bằng cho chức năng của bạn tỷ lệ thuận với {1: 62748517, 2: 405451956, 3: 1122790032, 4: 1727369280, 5: 1594494720, 6: 88 3104768, 7: 271724544, 8: số lượng lớn hơn). Hoặc, sửa vòng lặp để chạy 6 lần, {1: 4826809, 2: 26733096, 3: 61691760, 4: 75928320, 5: 52565760, 6: 19408896, 7: 2985984}
Omar

-1

R (30 ký tự)

Xác định rand7:

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

Vì R được viết với phân tích thống kê trong đầu, nên nhiệm vụ này không đáng kể và tôi sử dụng hàm tích samplehợp với bộ thay thế thành TRUE.

Đầu ra mẫu:

> 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
Nó nói bạn phải sử dụng Rand5. Không nói như thế nào, nhưng bạn phải sử dụng nó ...
Spacesman

@Spacesman Có, tôi rõ ràng bỏ qua nó. Đó là sử dụng bởi không tham khảo.
Andrie

-1

Groovy

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

phân phối ví dụ trên 35.000 lần lặp:

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

Nó có tệ không?



-1

Còn cái này thì sao?

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

Dù đó là ngôn ngữ nào, /toán tử của nó có làm toán nguyên không? Điều gì xảy ra với kết quả của bạn nếu nó thực hiện phép toán thập phân, dấu phẩy động hoặc số nguyên?
kojiro

Giả sử phân chia số nguyên, hàm này có phân phối sau : [2/25, 4/25, 5/25, 5/25, 5/25, 3/25, 1/25]. Không chính xác thống nhất.
primo

Primo là đúng. việc thêm các số ngẫu nhiên thường sẽ làm lệch các xác suất đối với các giá trị trung bình.
gnibbler

-1

Java - 54

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

Kiểm tra phân phối: [1000915, 999689, 999169, 998227, 1001653, 1000419, 999928]

Thuật toán:

  • Giữ một biến toàn cầu
  • nhân với 5, do đó, có được 5 vị trí miễn phí ở mức thấp nhất
  • Cắt bớt bit dấu để làm cho nó dương (không cần thiết nếu số không dấu được hỗ trợ)
  • Modulo 7 là câu trả lời

> Các con số không bị loại bỏ lẫn nhau nữa, nhưng cá nhân hoàn toàn ngẫu nhiên.


-1

Ruby (43 byte)

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

Giải pháp của cemper93 được chuyển sang Ruby ngắn hơn ba byte;) (34 byte)

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

-3

Mã C / C ++ mã lõi chỉ có một dòng!

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 () là hạt giống của rand7, phải gọi hàm này trước rand7, giống như gọi srand trước rand trong C.

Đây là một thứ rất tốt, vì nó chỉ gọi rand () một lần duy nhất và không có điều lặp, không có thêm ký ức.

Hãy để tôi giải thích nó: xem xét một mảng số nguyên với kích thước 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

Vì vậy, chúng tôi đã có BẢNG, mỗi một trong số 1-7 xuất hiện 5 lần trong đó và có tất cả 35 số, vì vậy xác suất của mỗi số là 5/35 = 1/7. Và lần sau,

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

Sau khi đủ thời gian, chúng ta có thể nhận được phân phối đồng đều từ 1-7.

Vì vậy, chúng ta có thể phân bổ một mảng để khôi phục năm phần tử của 1-7 bằng vòng lặp trái-shift và nhận một số từ mảng mỗi lần bằng rand5. Thay vào đó, chúng ta có thể tạo ra tất cả bảy mảng trước đó và sử dụng chúng theo vòng tròn. Mã cũng đơn giản, có nhiều mã ngắn có thể làm điều này.

Nhưng, chúng ta có thể sử dụng các thuộc tính của% hoạt động, do đó, các hàng 1-7 của bảng tương đương với (rand5 + i)% 7, nghĩa là: a = rand ()% 5 + 1 là rand5 trong ngôn ngữ C, b = gi ++ % 7 tạo ra tất cả các hoán vị trong bảng trên và 0 - 6 thay thế 1 - 7 c = (a + b)% 7 + 1, tạo 1 - 7 đồng đều. Cuối cùng, chúng tôi đã nhận được mã này:

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

Nhưng, chúng tôi không thể nhận được 6 và 7 ở lần gọi đầu tiên, vì vậy chúng tôi cần một hạt giống, một số giống như srand cho rand trong C / C ++, để làm xáo trộn hoán vị cho cuộc gọi chính thức đầu tiên.

Đây là mã đầy đủ để thử nghiệm:

#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);
}

Nó 'vượt qua' thử nghiệm ', nhưng điều đó không có nghĩa đây là một chức năng ngẫu nhiên tốt. Tôi có thể nhận được 6hoặc 7bằng cách gọi nó một lần ?
JiminP

Nhưng có loại tốt và loại xấp xỉ xấu. Và mã này là xấu - bởi vì nó không phân phối đồng đều khi chỉ được gọi một lần. Nếu một người viết một cái gì đó như int main(){if(rand7()==6) printf("Hello, world!");}, xấp xỉ bằng vòng lặp sẽ in 'Xin chào, thế giới!' 1 trong 7 lần, nhưng mã của bạn thì không.
JiminP

cảm ơn bạn @JiminP! bạn đúng 6,7 lần đầu tiên Tôi cần một hạt giống để xáo trộn trước khi gọi rand7, hạt giống giống như srand trong C / C ++. tôi đã sửa mã của mình và cảm ơn bạn lần nữa !!!
Sean

hm .... srand10 không hoạt động, 3 số cuối không thể có được ở các vị trí 10, 20, 30 .... xin lỗi @JiminP, nhưng làm thế nào để sửa đổi nó? Tôi nghĩ rằng đây là cách hy vọng.
Sean

2
Các cuộc gọi khác nhau cho chức năng này không độc lập với nhau. Thông số kỹ thuật ở đây không yêu cầu điều này, nhưng đó thường là expecetd của các trình tạo số ngẫu nhiên. Mặt khác, bạn có thể nói, trả lại số đồng phục ngẫu nhiên lần đầu tiên và trong các cuộc gọi trong tương lai, chỉ cần trả lại (trước + 1)% 7 ...
Omar
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.