Tentang Seri
Pertama, Anda dapat memperlakukan ini seperti tantangan golf kode lainnya, dan menjawabnya tanpa khawatir tentang seri sama sekali. Namun, ada papan peringkat di semua tantangan. Anda dapat menemukan leaderboard bersama dengan beberapa informasi lebih lanjut tentang seri di posting pertama .
Meskipun saya memiliki banyak ide untuk seri ini, tantangan di masa depan belum ditetapkan. Jika Anda memiliki saran, beri tahu saya di pos kotak pasir yang relevan .
Lubang 2: Angka dari Distribusi Normal
Saya tidak percaya ini belum dilakukan! Anda akan menghasilkan angka acak, menggambar dari distribusi normal . Beberapa aturan (mayoritas dari mereka mungkin secara otomatis tercakup oleh sebagian besar penyerahan, tetapi beberapa dari mereka ada untuk memastikan konsistensi hasil antara bahasa yang sangat berbeda):
Anda harus mengambil dua bilangan bulat non-negatif sebagai input : satu seed
S
dan jumlahN
angka yang akan dikembalikan. Outputnya harus berupa daftarN
angka floating point, diambil dari distribusi normal dengan rata - rata 0 dan varians 1 . Setiap kali kiriman Anda diberikan benih yang sama,S
ia harus menghasilkan nomor yang sama. Secara khusus, jika itu dipanggil sekali dengan dan sekali dengan , entri pertama dari dua output harus identik. Selain itu, setidaknya 2 16 nilai yang berbeda harus menghasilkan urutan yang berbeda.(S, N1)
(S, N2)
min(N1, N2)
S
Anda dapat menggunakan penghasil bilangan acak bawaan apa pun yang didokumentasikan untuk menarik bilangan dari distribusi seragam (kira-kira) , asalkan Anda dapat meneruskannya
S
dan mendukung setidaknya 16 16 benih yang berbeda. Jika ya, RNG harus dapat mengembalikan setidaknya 20 nilai yang berbeda untuk setiap nomor yang Anda minta darinya.- Jika seragam RNG Anda yang tersedia memiliki rentang yang lebih kecil, tidak dapat diunggulkan, atau mendukung terlalu sedikit benih, Anda harus terlebih dahulu membangun RNG seragam dengan rentang yang cukup besar di atas bawaan atau Anda harus menerapkan RNG Anda sendiri menggunakan biji. Halaman ini mungkin bermanfaat untuk itu.
- Jika Anda tidak menerapkan algoritma yang ditetapkan untuk menghasilkan distribusi normal, harap sertakan bukti kebenaran. Dalam kedua kasus tersebut, algoritma yang Anda pilih harus menghasilkan distribusi normal yang tepat secara teoritis (kecuali pembatasan PRNG yang mendasari atau tipe data presisi terbatas).
- Implementasi Anda harus menggunakan dan mengembalikan angka floating-point (lebar minimal 32 bit) atau angka fixed-point (setidaknya lebar 24 bit) dan semua operasi aritmatika harus menggunakan lebar penuh dari tipe yang dipilih.
- Anda tidak boleh menggunakan fungsi bawaan apa pun yang terkait langsung dengan distribusi normal atau integral Gaussian, seperti fungsi Galat atau kebalikannya.
Anda dapat menulis program atau fungsi lengkap dan mengambil input melalui STDIN, argumen baris perintah, argumen fungsi atau prompt dan menghasilkan output melalui nilai balik atau dengan mencetak ke STDOUT (atau alternatif terdekat).
S
dan N
akan menjadi bilangan bulat non-negatif, masing-masing kurang dari 20 . Output mungkin dalam format string atau daftar yang mudah, tidak ambigu.
Ini adalah kode golf, jadi pengiriman terpendek (dalam byte) menang. Dan tentu saja, pengiriman terpendek per pengguna juga akan masuk ke papan peringkat keseluruhan seri.
Papan peringkat
Posting pertama dari seri menghasilkan leaderboard.
Untuk memastikan jawaban Anda muncul, mulailah setiap jawaban dengan tajuk utama, menggunakan templat Penurunan harga berikut:
# Language Name, N bytes
di mana N
ukuran kiriman Anda. Jika Anda meningkatkan skor Anda, Anda dapat menyimpan skor lama di headline, dengan mencoretnya. Contohnya:
# Ruby, <s>104</s> <s>101</s> 96 bytes
(Bahasa saat ini tidak ditampilkan, tetapi cuplikan memang membutuhkan dan menguraikannya, dan saya dapat menambahkan leaderboard berdasarkan bahasa di masa mendatang.)
Jawaban:
Dyalog APL, 33 byte
{(.5*⍨¯2×⍟?0)×1○○2×?0}¨⍳⎕⊣⎕rl←1+⎕
Kotak-muller :
sumber
⎕rl
menjadiS+1
karena⎕rl←0
memiliki makna khusus.+1
, semua dikatakan bahwa Anda perlu mendukung setidaknya 2 ^ 16 nilai yang berbeda. Jadi bekerja dengan benar dalam kisaran [1..2 ^ 16] harus OK.R, 68 byte
Ini menggunakan
runif()
fungsi, yang menghasilkan penyimpangan acak dari distribusi yang seragam. Benih untuk pembuatan angka acak ditentukan menggunakanset.seed()
, yang secara default menggunakan algoritma Mersenne-Twister dengan periode 2 ^ 19937-1.Hasilnya adalah vektor R dengan panjang N yang berisi standar penyimpangan normal yang dihitung.
Ini menggunakan metode Box-Muller: Untuk dua variabel acak seragam independen U dan V,
sumber
f=
(fungsi tidak perlu dinamai, jika fungsi yang tidak disebutkan namanya adalah sesuatu dalam bahasa Anda).Error: unexpected '}' in "f=fu...
, apakah Anda yakin mendapat nomor pertama yang sama jika Anda meneleponf(0,1)
danf(0,2)
?Dyalog APL,
4234Ini adalah fungsi yang mengambil
S
argumen kiri danN
argumen kanannya.Ini merupakan implementasi dari transformasi Box-Muller, menggunakan operator acak
?
bawaan Dyalog APL , yang secara default adalah twister Mersenne yang mengembalikan nilai 64-bit, yang seharusnya cukup.Penjelasan:
⎕RL←⍺
: setel benih acak ke⍺
.?⍵2⍴0
: menghasilkan⍵
pasangan angka acak antara 0 dan 1.{
...}/
: terapkan fungsi berikut untuk setiap pasangan:(.5*⍨¯2×⍟⍺)×1○⍵×○2
: hitungZ0
nilainya (sqrt(-2 ln ⍺)×cos(2π⍵)
).sumber
?0
mengembalikan angka floating point antara 0 dan 1.Perl, 67
Box-Muller seperti pada entri lainnya.
f
mengambil parameter secara berurutanS, N
.Menggunakan:
sumber
Java,
164161 byteIni menerima input melalui fungsi dan output melalui stdout. Ini menggunakan metode Box-Muller.
sumber
s=0;s++<n;
->;n-->0;
?Commodore 64 Basic,
767063 byteKarena rangkaian karakter PETSCII berisi beberapa simbol yang tidak ada di Unicode, saya telah membuat pergantian:
/
=SHIFT+N
,┌
=SHIFT+O
,●
=SHIFT+Q
,╮
=SHIFT+I
,─
=SHIFT+E
Ini mengimplementasikan transformasi Box-Muller standar untuk menghasilkan angka; Saya memilih dosa (x) setengah dari transformasi karena Commodore 64 Basic memiliki pintasan dua karakter untuk
sin()
, tetapi tidak untukcos()
.Meskipun manual menyatakan sebaliknya, nilai argumen untuk
RND
melakukan hal penting: jika angka negatif dilewatkan, generator nomor acak tidak hanya diunggulkan kembali, tetapi diunggulkan kembali dengan nomor itu . Ini membuat penyemaian jauh lebih sederhana: daripada perlu kePOKE
lima lokasi memori, saya hanya perlu membuat panggilan do-nothingRND
, yang mengurangi kode dari dua baris / 121 byte menjadi 1 baris / 76 byte.Sunting: Memotong enam byte off dengan menyadari bahwa saya dapat menggabungkan dua
INPUT
pernyataan, dan bahwa ruang setelahnyaTO
adalah opsional.Sunting: Dipotong tujuh lagi: Commodore Basic, pada kenyataannya, memiliki Pi sebagai konstanta bawaan, dan bahkan dapat diketik pada keyboard modern (
SHIFT+PgDn
, jika Anda bertanya-tanya).sumber
80386 kode mesin, 72 byte
Hexdump kode:
Berikut adalah kode sumbernya (dapat dikompilasi oleh Visual Studio):
Di sini saya menggunakan generator bilangan acak Lehmer . Ini menggunakan algoritma berikut:
Di sini 4294967291 adalah bilangan prima besar (2 ^ 32-5), dan 116 adalah bilangan kecil (kurang dari 128; lihat di bawah) yang merupakan akar primitifnya . Saya memilih akar primitif yang memiliki distribusi nol acak yang lebih atau kurang dan yang dalam representasi biner (01110100). RNG ini memiliki periode maksimum yang mungkin adalah 4294967290, jika benih bukan nol.
Angka yang relatif kecil yang saya gunakan di sini (116 dan 4294967291, yang dapat diwakili juga sebagai -5) izinkan saya mengambil keuntungan dari
lea
pengkodean instruksi:Ia dirangkai menjadi 3 byte jika angka-angka tersebut dapat masuk ke dalam 1 byte.
Perkalian dan penggunaan divisi
edx
daneax
sebagai register kerja mereka, itulah sebabnya saya membuatseed
parameter kedua ke fungsi (fastcall
konvensi pemanggilan digunakanedx
untuk melewati parameter kedua). Selain itu, parameter pertama dilewatkanecx
, yang merupakan tempat yang baik untuk menyimpan penghitung: loop dapat diatur dalam 1 instruksi!Untuk mengkonversi integer menjadi angka floating-point, saya mengeksploitasi representasi angka floating-point presisi tunggal: jika saya mengatur tinggi 9 bit (eksponen) ke pola bit
001111111
, dan meninggalkan 23 bit rendah secara acak, saya akan dapatkan nomor acak di kisaran 1 ... 2. Saya mengambil ide dari sini . Untuk mengatur bit 9 tinggi, saya menggunakan beberapa bit-mengutak-atikebx
:Untuk menghasilkan dua angka acak, saya menggunakan loop bersarang dari 2 iterasi. Saya mengaturnya dengan
xor
:Kode floating-point mengimplementasikan transformasi Box-Muller .
sumber
Haskell, 118
144Contoh penggunaan:
Tipe kembalinya
random
dibatasiFloat
, yang membuatrandom
menghasilkan float yang seragam dalam [0, 1). Sejak saat itu, ini adalah formula box-muller simlpe dengan sihir tak berguna untuk pembuatan daftar.sumber
Golflua, 63
70Info dan instruksi Golflua.
Mengembalikan tabel yang berisi nilai-nilai. Dalam contoh yang saya gunakan
~T.u( )
, yang sama denganreturn table.unpack( )
di lua.Banyak karakter disimpan dengan mengatur lingkungan fungsi ke
M
(aliasmath
).sumber
SAS, 108
Saya sudah memposting jawaban dalam R yang lebih pendek dari ini, tetapi ada sangat sedikit jawaban SAS di PPCG, jadi mengapa tidak menambahkan yang lain?
Dengan sedikit ruang putih:
Ini mendefinisikan makro yang bisa disebut seperti
%f(5, 3)
. Makro mengeksekusi langkah data yang loop melalui bilangan bulat 1 ke N, dan pada setiap iterasi menghitung penyimpangan normal acak menggunakan Box-Muller dan mencetaknya ke log menggunakanput
pernyataan.SAS tidak memiliki built-in untuk pi, jadi yang terbaik yang bisa kita lakukan adalah memperkirakannya dengan arctangent.
The
ranuni()
function (yang sudah ditinggalkan tetapi membutuhkan pasangan karakter yang lebih sedikit daripada fungsi baru) mengembalikan nomor acak dari distribusi seragam. Dokumentasi SAS tidak memberikan banyak detail tentang implementasi RNG selain memiliki periode 2 ^ 31-2.Dalam makro SAS, variabel makro direferensikan dengan sebelumnya
&
dan menyelesaikan nilai-nilainya pada saat run time.Seperti yang mungkin telah Anda saksikan, SAS jarang menjadi lawan yang sebenarnya dalam kontes kode-golf .
sumber
Java, 193 byte
Meskipun ini tidak mengalahkan pemimpin Java saat ini, saya memutuskan untuk tetap memposting untuk menunjukkan metode perhitungan yang berbeda. Ini adalah versi OpenJDK dari golf
nextGaussian()
.Dengan jeda baris:
sumber
(s,n)->{java.util.Random r=new java.util.Random(s);for(float a,v;n-->0;System.out.println(v*Math.sqrt(-2*Math.log(a)/a)))for(a=0;a>=1|a==0;a=v*v+(v=2*r.nextFloat()-1)*v)v=2*r.nextFloat()-1;}
T-SQL, 155 byte
Gunakan dengan EXEC RS, N karena tidak ada STD_IN di T-SQL di mana S dan N adalah seed dan N masing-masing. S akan menghasilkan urutan "acak" (RAND (seed) adalah implementasi angka acak yang benar-benar buruk) ketika S> 2 ^ 16 (mungkin sebelum itu, tetapi saya tidak akan menjaminnya). Menggunakan Box-Muller seperti kebanyakan solusi sejauh ini. 8388607 adalah 2 ^ 23-1, yang diharapkan akan menghasilkan 2 ^ 20 nilai yang berbeda.
sumber
Powershell, 164 byte
Sama seperti kebanyakan jawaban dengan Box-Muller. Tidak terlalu berpengalaman dengan Powershell, sehingga bantuan golf apa pun akan dihargai.
sumber
Ruby, 72 byte
Input (sebagai fungsi lambda):
Keluaran:
PS: Saya ingin tahu apakah ini bisa golf lebih lanjut. Saya hanya seorang pemula.
sumber
Matlab, 77
Input pertama harus
n
, input keduas
.sumber
Oktaf,
919688 byteAtau, dengan spasi putih:
Atur benih di depan, dan gunakan metode Box-Mueller.
NB: Oktaf memungkinkan untuk menghasilkan array angka acak, dan dapat menggunakan operasi standar pada array ini yang menghasilkan output array. The
.*
operator adalah elemen-by-elemen perkalian dua array untuk menghasilkan hasil.sumber
n(0,1)
dann(0,2)
mendapatkan nomor pertama yang berbeda, bukan?Pyth, 32 byte
Tidak ada Python yang digunakan sekarang dalam tanda kutip super karena fungsi baru yang dimiliki Pyth sekarang. Namun Box-Mueller yang lain.
Ruang pada awalnya itu penting.
Penyemaian tampaknya tidak berfungsi dalam penerjemah online, tetapi berfungsi dengan baik dalam versi lokal.Penerjemah online tampaknya sudah diperbaiki, jadi inilah permalink: permalinksumber
.nZ
) yang tidak diterapkan, ketika pertanyaan diajukan. (Ini sebenarnya diterapkan hari ini.) Oleh karena itu jawaban ini tidak boleh menjadi bagian dari kompetisi ( meta.codegolf.stackexchange.com/questions/4867/… ).STATA, 85 byte
Mengambil input melalui standar dalam (angka pertama adalah S, lalu N). Atur seed menjadi S. Atur jumlah pengamatan ke N. Membuat variabel dan set nilainya ke nilai transformasi Box Muller (terima kasih kepada @Alex untuk menunjukkannya). Kemudian daftarkan semua pengamatan dalam sebuah tabel dengan tajuk kolom a dan angka-angka pengamatan di sebelahnya. Jika ini tidak apa-apa, beri tahu saya, dan saya bisa menghapus header dan / atau nomor observasi.
sumber
R, 89 Bytes
Saya tahu R telah dilakukan sebelumnya tetapi saya ingin menunjukkan pendekatan yang berbeda dari Box-Muller yang digunakan orang lain. Solusi saya menggunakan Teorema Limit Pusat .
sumber
a
dalam kode Anda sehingga hasilnya "adil".)TI-Basic, 74 byte
The
¹
sebenarnya operator terbalik.sumber
Perl,
150108107 byteIni menggunakan Metode Kutub Marsaglia . Disebut dengan f (S, N).
Pindah tugas
$a
ke dalam perhitungan$c
.107:
Penyimpanan nomor cadangan yang dihapus dan definisi
$b
.108:
150:
sumber
Swift,
144142Tidak ada yang pintar, hanya melihat cara kerja Swift.
Saya berharap saya bisa menggunakan (0 ... n) .map {} tetapi kompilernya sepertinya tidak mengenali peta {} kecuali Anda menggunakan parameter.
sumber
forEach
jika Anda tidak ingin nilai kembali, dan saya cukup yakin_ in
ini wajib/0xffffffff
btwHaskell , 97 byte
Cobalah online!
Hanya transformasi Box-Muller dasar Anda, pada daftar angka acak tanpa batas.
sumber
Python 3 , 118 byte
Cobalah online!
sumber
SmileBASIC, 81 byte
Nah, sekarang saya sudah menjawab pertanyaan pertama, saya harus melakukan semua yang lain ...
Menghasilkan angka acak itu murah, tetapi menyemai RNG menggunakan fungsi builtin terpanjang dalam bahasa
RANDOMIZE
,.Mungkin ada beberapa cara untuk mengoptimalkan formula. Saya tidak melihat bagaimana diperlukan untuk menggunakan dua panggilan RNG.
sumber