Rand5 () ke Rand7 () [ditutup]

29

Anda diberi fungsi Rand5 (). Fungsi ini mengembalikan bilangan bulat acak (distribusi yang sama) antara 1 dan 5.

Berikan fungsi Rand7 (), yang menggunakan Rand5 () untuk menghasilkan bilangan bulat acak sempurna antara 1 dan 7.

Dan McGrath
sumber
3
Duplikat pertanyaan
Mateen Ulhaq
8
Wajib xkcd: xkcd.com/221
Steven Rumbalski
1 dan 5 inklusif? yaitu dari himpunan {1,2,3,4,5}?
Aaron McDaid
1
Kriteria apa yang menentukan pemenang tunggal?
kojiro
Momen ketika Anda menyadari ini sebenarnya adalah pertanyaan lama.
nyuszika7h

Jawaban:

11

Jawa - 61 karakter

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

Driver penguji untuk validasi:

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

}

Hasil

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>
corsiKa
sumber
10
Poin ekstra untuk "masuk ke operator"
Steve P
mencukur char? int rand7 () {for (int s = 0, c = 7; c -> 0; s + = rand5 ()); return s% 7 + 1;}
Ron
3
Jawaban ini tidak benar: probabilitas fungsi ini mengembalikan nilai dari 1 hingga 7 masing-masing adalah 0,1430656, 0,1430016, 0,1428224, 0,1426432, 0,1426432, 0,1428224 dan 0,1430016. Ya, perbedaan antara probabilitas minimum dan maksimum kurang dari 0,0005, tetapi tetap saja, pertanyaan yang ditentukan "bilangan bulat sempurna acak".
Ilmari Karonen
@ilmari Anda benar - Saya baru saja menjalankan tes dan sepertinya distribusinya bahkan tidak ... biarkan saya berpikir tentang itu ...
corsiKa
1
@ penggunaunknown: Ya, probabilitas yang saya posting sebenarnya bukan perkiraan, mereka tepat (0,1430656 = 11177/78125, dll.) dengan asumsi acak sempurna rand5. Saya menghitungnya di Maple menggunakan aljabar matriks sederhana, tetapi Anda bisa melakukannya dengan pensil dan kertas dalam beberapa menit jika Anda mau. Lagi pula, ternyata Omar sudah memposting angka yang sama (tanpa faktor normalisasi) dalam komentar untuk jawaban lain beberapa hari sebelumnya. (Juga ps., Anda hanya dapat @memberitahu satu pengguna per komentar, meskipun penulis posting selalu diberitahu.)
Ilmari Karonen
7

Perl - 47 (dulu 52) karakter

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

Plus saya bisa menggunakan operator ternary DAN rekursi. Hari terbaik yang pernah ada!

OK, 47 karakter jika Anda menggunakan mod, bukan div:

sub rand7{($x=5*&rand5+&rand5)<27?$x%7+1:&rand7} 
barrycarter
sumber
Jadi tutup ... ganti 30 dengan 27 (= 6 + 21) dan Anda akan mendapatkan distribusi yang sangat seragam. Oh, dan Anda dapat menjatuhkan dua &tanda terakhir untuk membuatnya menjadi 46 karakter (termasuk ruang, yang menempatkan versi Anda saat ini di 48).
Ilmari Karonen
7

JavaScript, 42

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

Bonus ES5:

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

Ruby - 54 karakter (berdasarkan solusi Dan McGrath, menggunakan loop)

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

Ruby - 45 karakter (solusi yang sama, menggunakan rekursi)

def rand7;x=rand5+5*rand5-5;x>7 ?rand7: x;end
Eskat0n
sumber
Dapat dipersingkat dengan 1 char dengan menggunakan (x=rand5+5*rand5-5)>7?.
Lars Haugseth
5

Dengan Python:

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

Dalam Common Lisp 70 karakter:

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

Tanda kurung mengambil lebih banyak ruang daripada yang saya inginkan.

Jonathan Sternberg
sumber
Bagus. Anda dapat memeras dua karakter lagi dengan membuat variabel global:(defun rand7()(setq n(-(+(rand5)(* 5(rand5)))5))(if(> n 7)(rand7)n))
Dr. Pain
Bahkan lebih baik:(defun rand7()(if(>(setq n(-(+(rand5)(* 5(rand5)))5))7)(rand7)n))
Dr. Pain
4

Dalam c / c ++ menggunakan rejection sampling

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

62 karakter.

Dan McGrath
sumber
@ barrycarter: Syaratnya adalah while(x>7), jadi itu hanya akan dipenuhi oleh angka dalam rentang yang valid.
mellamokb
Salahku. Menghapus komentar bodoh saya.
barrycarter
@ Barry Dan kemudian Anda meninggalkan yang lain. ;)
Mateen Ulhaq
Butuh beberapa menit bagi saya untuk menyadari bagaimana matematika di sini menghasilkan distribusi acak seragam yang dapat digunakan untuk sampel penolakan.
Daniel
3

Terjemahan ke PHP, dari jawaban yang diposting ny Dan McGrath.

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

67 karakter.

Marc-François
sumber
Bukankah ini harus diawali dengan kata "fungsi" (dan spasi)?
jtjacques
Ya ... dan sekarang 67 karakter ...
Marc-François
3

R, 34 karakter

Dalam R (bahasa yang dibangun untuk perhitungan statistik), solusi yang sengaja dibuat curang:

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

Berkat evaluasi argumen yang malas, saya menghilangkan titik koma dan kawat gigi.

Output lebih dari 10 ^ 6 replikasi:

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

histogram hasil

Ari B. Friedman
sumber
2
Jika Anda akan menjadi curang, Anda mungkin juga menjadi curang yang terbaik:Rand7=function(){r=Rand5();sample(7)[r]}
Spacedman
Jika Anda akan melakukan itu, mengapa repot-repot dengan penyimpanan perantara? Rand7=function(){sample(7)[Rand5()]}
Brian Diggs
@BrianDiggs Path-dependency in action .... :-)
Ari B. Friedman
3

scala, 47, 40 59 karakter:

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

dengan 2 input dari rand5:

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

Saya kalikan yang pertama-1 dengan 5, dan tambahkan yang kedua. Sebagian besar hasil diabaikan, dan mengarah ke perhitungan baru. Hasilnya harus berupa distribusi nilai yang sama dari 1-25, dari mana saya hanya memilih 7 yang pertama. Saya bisa menerima 21 pertama dengan membangun modulo, tetapi ini akan menyebabkan kode lebih lama.

kode bersejarah yang gagal, tetapi tidak terlalu jelas. Terima kasih kepada Ilmari Karonen karena menunjukkannya:

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

Terima kasih kepada Yoshiteru Takeshita, untuk pendekatan scala-2.8.0 yang menjadikan 'jumlah' ini begitu mudah. Solusi saya sebelumnya:

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

Rand5:

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

Pengguna tidak diketahui
sumber
Pengguna Yoshiteru Takeshita mengusulkan pengurangan hingga 40 karakter untuk Scala 2.8.0 atau yang lebih barudef rand7=(1 to 7).map(_=>rand5).sum%7+1
Peter Taylor
Solusi ini juga tidak benar, lihat komentar untuk jawaban glowcoder .
Ilmari Karonen
@IlmariKaronen: Anda benar - saya mengerjakan ulang solusi saya.
pengguna tidak diketahui
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)

Golf

int Rand4(){int r=Rand5();return r>4?Rand4():r;}int Rand7(){int r=Rand4()-1<<2+Rand4();return r>7?Rand7():r;}
Mateen Ulhaq
sumber
Saya tidak benar-benar berpikir Anda dapat menyebutnya "satu liner" karena titik koma mendefinisikan baris kode dalam C ++.
Peter Olson
@ Peter Oh well, itu bahkan tidak membutuhkan satu kalimat lagi.
Mateen Ulhaq
Ini mengembalikan nomor dari 1 hingga 8.
jimmy23013
2

Terjemahan ke Javascript, dari jawaban yang diposting oleh Dan McGrath.

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

62 karakter

Clyde Lobo
sumber
1
function Rand7(){for(x=8;x>7;x=rand5()+5*rand5()-5);return x}sedikit lebih pendek: 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()}

Saya tahu ada jawaban yang lebih pendek, tetapi saya ingin menunjukkan tes teka-teki ini. Ternyata hanya jawaban Clyde Lobo yang menggunakan sampel penolakan Dan McGrath yang benar (di antara jawaban JS).

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

Distribusi angka (1000000 bilangan bulat):

142935 142751 142652 143299 142969 142691 142703

Jumlah rata-rata panggilan ke Rand5 () per setiap bilangan bulat yang dihasilkan adalah sekitar 2,2 (2 hingga 10+).

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

Di Jawa (atau C / C ++ saya kira)

  • menggunakan formula generasi oleh Alexandru, dalam 65 karakter:

    int rand7(){int x=rand5()*5+rand5()-6;return x>20?rand7():x/3+1;}
    
  • menggunakan formula generasi oleh Dan McGrath, dalam 60 karakter

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

Clojure - 58 karakter

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

Python, 56 37 karakter

Solusi lain yang mungkin salah, dengan Python:

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

Ini tampaknya terlalu sederhana, tetapi ketika saya mencoba:

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

Saya mendapatkan distribusi yang cukup merata (semuanya antara 14000 dan 14500).

Oke, sekarang ketika seseorang memberikan suara untuk posting ini: Apakah solusi ini memang benar? Saya lebih banyak memposting ini di sini untuk membuat orang mengkritiknya. Nah, jika itu benar, versi golf saya adalah:

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

yang keluar untuk 37 karakter.

cemper93
sumber
Solusi Anda tidak benar: Anda mendasarkan keputusan Anda pada 7 gulungan dadu bersisi 5 yang adil, yang berarti ada hasil yang dapat diperbandingkan. Karena ini bukan kelipatan dari 7, Anda tidak dapat mengembalikan 7 hasil yang dapat disempurnakan. Saya tidak berpikir ada formula yang mudah untuk apa yang Anda kembali; Anda dapat dengan paksa memaksa perhitungan atau mengerjakannya dengan tangan pada angka yang lebih kecil (flip 3 koin (H = 1, T = 2) dan jumlah hasilnya).
Gilles 'SANGAT berhenti menjadi jahat'
1
Wow, distribusi yang Anda hasilkan, meskipun tidak seragam, sangat dekat: proporsi pasti dari probabilitas masing-masing angka adalah {1: 11177, 2: 11172, 3: 11158, 4: 11144, 5: 11144, 6: 11158, 7: 11172}
Omar
1

Jawa, 65 karakter:

int rand7(){int r;do{r=rand5()+5*rand5()-5;}while(r>7);return r;}
Hans-Peter Störr
sumber
1

Python, 70 karakter

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

tetapi sepenuhnya benar berdasarkan alasan di sini .

Michael Foukarakis
sumber
1

Perl, 43 karakter, pengambilan sampel penolakan berulang

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

Ini memberi peringatan tentang Ambiguous use of -rand5 resolved as -&rand5(), tetapi berfungsi dengan benar. Membutuhkan &juga rand5panggilan kedua untuk memperbaikinya dengan biaya satu pukulan. (Sebaliknya, yang lain &juga bisa dihapus jika rand5 sudah didefinisikan dengan a() prototipe.)

Ps. Versi 46-char berikut sekitar tiga kali lebih cepat:

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

Java - 66 karakter

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

Lebih lama dari rutinitas sebelumnya, tapi saya pikir yang ini mengembalikan angka yang terdistribusi secara seragam dalam waktu yang lebih singkat.

David Gonzales
sumber
1

PostScript (46)

Ini menggunakan pengkodean token biner, oleh karena itu, inilah 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

Untuk mencobanya, Anda juga dapat mengunduhnya .

Berikut adalah kode yang tidak ditandai dan dikomentari, bersama dengan kode pengujian.

% 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
Thomas W.
sumber
-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;
Platon
sumber
2
Ini tidak akan memberikan distribusi yang seragam. Lihatlah distribusi rand (5) + rand (5) lebih dari 10.000 iterasi untuk melihat alasannya
gnibbler
hasilnya dapat berupa angka dari 1 hingga 8 dalam kode Anda ...
Omar
Plus, seperti yang dikatakan gnibbler, distribusinya tidak seragam: (rand (5) + rand (5))% 2 bias terhadap 0, ia menghasilkan 0 13 kali untuk setiap 12 kali ia menghasilkan 1; yaitu, probabilitas sebanding dengan {0: 13, 1: 12}. Dengan notasi itu, probabilitas untuk fungsi Anda sebanding dengan {1: 62748517, 2: 405451956, 3: 1122790032, 4: 1727369280, 5: 1594494720, 6: 883104768, 7: 271724544, 8: 35831808} (cukup condong ke arah jumlah yang lebih besar). Atau, memperbaiki loop agar berjalan 6 kali, {1: 4826809, 2: 26733096, 3: 61691760, 4: 75928320, 5: 52565760, 6: 19408896, 7: 2985984}
Omar
-1

R (30 karakter)

Tentukan rand7:

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

Karena R ditulis dengan analisis statistik dalam pikiran, tugas ini sepele, dan saya menggunakan fungsi bawaan sample bawaan dengan penggantian diatur ke TRUE.

Output sampel:

> 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
Andrie
sumber
1
Itu mengatakan Anda harus menggunakan Rand5. Tidak mengatakan bagaimana, tetapi Anda harus menggunakannya ...
Spacedman
@Spacedman Ya, saya secara eksplisit mengabaikannya. Itu digunakan oleh non-referensi.
Andrie
-1

Asyik

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

contoh distribusi lebih dari 35.000 iterasi:

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

Apakah buruk kalau itu stateful?

Armand
sumber
-1

Mathematica, 30

Rand7=Rand5[]~Sum~{7}~Mod~7+1&
Tuan Wisaya
sumber
-1

Bagaimana dengan ini?

int Rand7()
{
    return Rand5()+ Rand5()/2;
}
sree
sumber
Bahasa apa pun itu, apakah /operatornya melakukan bilangan bulat matematika? Apa yang terjadi pada hasil Anda jika itu desimal, floating-point, atau bilangan bulat matematika?
kojiro
Dengan asumsi pembagian integer, fungsi ini memiliki pembagian sebagai berikut: [2/25, 4/25, 5/25, 5/25, 5/25, 3/25, 1/25]. Tidak persis seragam.
primo
Primo benar. menambahkan angka acak umumnya akan condongkan probabilitas ke arah nilai tengah.
gnibbler
-1

Jawa - 54

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

Tes distribusi: [1000915, 999689, 999169, 998227, 1001653, 1000419, 999928]

Algoritma:

  • Pertahankan variabel global
  • kalikan dengan 5, jadi dapatkan 5 tempat gratis di akhir paling tidak signifikan
  • Potong sedikit tanda untuk membuatnya positif (tidak perlu jika nomor yang tidak ditandai didukung)
  • Modulo 7 adalah jawabannya

> Angka-angka tidak saling tidak berhubungan lagi, tetapi secara individual sangat acak.

Mark Jeronimus
sumber
-1

Ruby (43 byte)

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

solusi cemper93 porting ke Ruby adalah tiga byte lebih pendek;) (34 byte)

def rand7;eval("+rand5"*7)%7+1;end
AlexRath
sumber
-3

Kode C / C ++ kode inti hanya memiliki satu baris!

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

The srand7 () adalah benih rand7, harus memanggil fungsi ini sebelum rand7, sama seperti panggilan srand sebelum rand di C.

Ini sangat bagus, karena memanggil rand () hanya satu kali, dan tidak ada perulangan, tidak ada memori tambahan yang dikeluarkan.

Mari saya jelaskan: pertimbangkan array integer dengan ukuran 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

Jadi kami mendapatkan TABEL, masing-masing 1-7 muncul 5 kali di dalamnya, dan memiliki semua 35 angka, sehingga probabilitas setiap angka adalah 5/35 = 1/7. Dan lain kali,

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

Setelah cukup waktu, kita bisa mendapatkan distribusi seragam 1-7.

Jadi, kita bisa mengalokasikan array untuk mengembalikan lima elemen 1-7 dengan loop-kiri-shift, dan mendapatkan satu angka dari array setiap kali dengan rand5. Sebagai gantinya, kita dapat menghasilkan ketujuh array sebelumnya, dan menggunakannya secara melingkar. Kodenya juga sederhana, sudah banyak kode pendek yang bisa melakukan ini.

Tapi, kita bisa menggunakan properti% operasi, sehingga tabel 1-7 baris setara dengan (rand5 + i)% 7, yaitu: a = rand ()% 5 + 1 adalah rand5 dalam bahasa C, b = gi ++ % 7 menghasilkan semua permutasi pada tabel di atas, dan 0 - 6 ganti 1 - 7 c = (a + b)% 7 + 1, menghasilkan 1 - 7 secara seragam. Akhirnya, kami mendapat kode ini:

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

Tapi, kita tidak bisa mendapatkan 6 dan 7 pada panggilan pertama, jadi kita perlu sebuah seed, beberapa seperti srand untuk rand di C / C ++, untuk mengatur permutasi untuk panggilan formal pertama.

Berikut ini kode lengkap untuk pengujian:

#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);
}
Sean
sumber
Itu 'lulus' tes ', tetapi itu tidak berarti ini adalah fungsi acak yang baik. Bisakah saya mendapatkan 6atau 7meneleponnya sekali ?
JiminP
Tapi ada jenis yang baik dan jenis perkiraan yang buruk. Dan kode ini buruk - karena tidak memberikan distribusi yang seragam ketika dipanggil hanya sekali. Jika seseorang menulis sesuatu seperti int main(){if(rand7()==6) printf("Hello, world!");}, perkiraan menggunakan loop akan mencetak 'Halo, dunia!' 1 dalam 7 kali, tetapi kode Anda tidak.
JiminP
@JiminP terima kasih! Anda tepat untuk 6,7 pada saat pertama. saya butuh seed untuk disarrange sebelum memanggil rand7, seed seperti srand di C / C ++. saya memperbaiki kode saya, dan terima kasih lagi !!!
Sean
hm .... srand10 tidak berfungsi, 3 angka terakhir tidak bisa di posisi 10, 20, 30 .... maaf @ JiminP, tetapi bagaimana memodifikasinya? Saya pikir ini adalah cara yang penuh harapan.
Sean
2
Panggilan yang berbeda untuk fungsi ini tidak saling tergantung satu sama lain. Spesifikasi di sini tidak memerlukan ini, tetapi itu biasanya diharapkan dari generator bilangan acak. Kalau tidak, bisa dibilang, kembalikan nomor seragam acak yang pertama kali dan untuk panggilan mendatang kembalilah (sebelumnya + 1)% 7 ...
Omar