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.
code-challenge
math
random
Dan McGrath
sumber
sumber
Jawaban:
Jawa - 61 karakter
Driver penguji untuk validasi:
Hasil
sumber
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.)Perl - 47 (dulu 52) karakter
Plus saya bisa menggunakan operator ternary DAN rekursi. Hari terbaik yang pernah ada!
OK, 47 karakter jika Anda menggunakan mod, bukan div:
sumber
&
tanda terakhir untuk membuatnya menjadi 46 karakter (termasuk ruang, yang menempatkan versi Anda saat ini di 48).JavaScript, 42
Bonus ES5:
sumber
Ruby - 54 karakter (berdasarkan solusi Dan McGrath, menggunakan loop)
Ruby - 45 karakter (solusi yang sama, menggunakan rekursi)
sumber
(x=rand5+5*rand5-5)>7?
.Dengan Python:
sumber
Dalam Common Lisp 70 karakter:
Tanda kurung mengambil lebih banyak ruang daripada yang saya inginkan.
sumber
(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))
Dalam c / c ++ menggunakan rejection sampling
62 karakter.
sumber
while(x>7)
, jadi itu hanya akan dipenuhi oleh angka dalam rentang yang valid.Terjemahan ke PHP, dari jawaban yang diposting ny Dan McGrath.
67 karakter.
sumber
R, 34 karakter
Dalam R (bahasa yang dibangun untuk perhitungan statistik), solusi yang sengaja dibuat curang:
Berkat evaluasi argumen yang malas, saya menghilangkan titik koma dan kawat gigi.
Output lebih dari 10 ^ 6 replikasi:
sumber
Rand7=function(){r=Rand5();sample(7)[r]}
Rand7=function(){sample(7)[Rand5()]}
scala,
47, 4059 karakter:dengan 2 input dari rand5:
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:
Terima kasih kepada Yoshiteru Takeshita, untuk pendekatan scala-2.8.0 yang menjadikan 'jumlah' ini begitu mudah. Solusi saya sebelumnya:
Rand5:
sumber
def rand7=(1 to 7).map(_=>rand5).sum%7+1
C ++
C ++ (109)
Golf
sumber
Terjemahan ke Javascript, dari jawaban yang diposting oleh Dan McGrath.
62 karakter
sumber
function Rand7(){for(x=8;x>7;x=rand5()+5*rand5()-5);return x}
sedikit lebih pendek: PJavaScript, 85
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).
sumber
С ++
Distribusi angka (1000000 bilangan bulat):
Jumlah rata-rata panggilan ke Rand5 () per setiap bilangan bulat yang dihasilkan adalah sekitar 2,2 (2 hingga 10+).
sumber
Di Jawa (atau C / C ++ saya kira)
menggunakan formula generasi oleh Alexandru, dalam 65 karakter:
menggunakan formula generasi oleh Dan McGrath, dalam 60 karakter
sumber
Clojure - 58 karakter
sumber
Python,
5637 karakterSolusi lain yang mungkin salah, dengan Python:
Ini tampaknya terlalu sederhana, tetapi ketika saya mencoba:
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:
yang keluar untuk 37 karakter.
sumber
Jawa, 65 karakter:
sumber
Python, 70 karakter
tetapi sepenuhnya benar berdasarkan alasan di sini .
sumber
Perl, 43 karakter, pengambilan sampel penolakan berulang
Ini memberi peringatan tentang
Ambiguous use of -rand5 resolved as -&rand5()
, tetapi berfungsi dengan benar. Membutuhkan&
jugarand5
panggilan kedua untuk memperbaikinya dengan biaya satu pukulan. (Sebaliknya, yang lain&
juga bisa dihapus jikarand5
sudah didefinisikan dengan a()
prototipe.)Ps. Versi 46-char berikut sekitar tiga kali lebih cepat:
sumber
Java - 66 karakter
Lebih lama dari rutinitas sebelumnya, tapi saya pikir yang ini mengembalikan angka yang terdistribusi secara seragam dalam waktu yang lebih singkat.
sumber
PostScript (46)
Ini menggunakan pengkodean token biner, oleh karena itu, inilah hexdump:
Untuk mencobanya, Anda juga dapat mengunduhnya .
Berikut adalah kode yang tidak ditandai dan dikomentari, bersama dengan kode pengujian.
sumber
sumber
R (30 karakter)
Tentukan rand7:
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:
sumber
Asyik
contoh distribusi lebih dari 35.000 iterasi:
Apakah buruk kalau itu stateful?
sumber
Mathematica, 30
sumber
Bagaimana dengan ini?
sumber
/
operatornya melakukan bilangan bulat matematika? Apa yang terjadi pada hasil Anda jika itu desimal, floating-point, atau bilangan bulat matematika?[2/25, 4/25, 5/25, 5/25, 5/25, 3/25, 1/25]
. Tidak persis seragam.Jawa - 54
Tes distribusi:
[1000915, 999689, 999169, 998227, 1001653, 1000419, 999928]
Algoritma:
> Angka-angka tidak saling tidak berhubungan lagi, tetapi secara individual sangat acak.
sumber
Ruby (43 byte)
solusi cemper93 porting ke Ruby adalah tiga byte lebih pendek;) (34 byte)
sumber
Kode C / C ++ kode inti hanya memiliki satu baris!
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:
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,
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:
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:
sumber
6
atau7
meneleponnya sekali ?int main(){if(rand7()==6) printf("Hello, world!");}
, perkiraan menggunakan loop akan mencetak 'Halo, dunia!' 1 dalam 7 kali, tetapi kode Anda tidak.