Tugas Anda adalah menulis program atau fungsi yang menghasilkan n
angka acak dari interval [0,1] dengan jumlah tetap s
.
Memasukkan
n, n≥1
, jumlah angka acak untuk dihasilkan
s, s>=0, s<=n
, jumlah angka yang akan dihasilkan
Keluaran
n
Double- acak angka floating point dengan semua elemen dari interval [0,1] dan jumlah semua elemen sama dengan s
, output dengan cara yang jelas dan nyaman. Semua n
-tuple yang valid harus memiliki kemungkinan yang sama dalam batasan angka floating point.
Ini sama dengan pengambilan sampel secara seragam dari persimpangan titik-titik di dalam n
kubus unit -dimensi dan n-1
hyperplane -dimensi yang melewati (s/n, s/n, …, s/n)
dan tegak lurus terhadap vektor (1, 1, …, 1)
(lihat area merah pada Gambar 1 untuk tiga contoh).
Gambar 1: Bidang output yang valid dengan n = 3 dan jumlah 0,75, 1,75 dan 2,75
Contohnya
n=1, s=0.8 → [0.8]
n=3, s=3.0 → [1.0, 1.0, 1.0]
n=2, s=0.0 → [0.0, 0.0]
n=4, s=2.0 → [0.2509075946818119, 0.14887693388076845, 0.9449661625992032, 0.6552493088382167]
n=10, s=9.999999999999 → [0.9999999999999,0.9999999999999,0.9999999999999,0.9999999999999,0.9999999999999,0.9999999999999,0.9999999999999,0.9999999999999,0.9999999999999,0.9999999999999]
Aturan
- Program Anda harus selesai di bawah satu detik pada mesin Anda setidaknya dengan
n≤10
dan s yang valid. - Jika diinginkan, program Anda dapat eksklusif di ujung atas, yaitu
s<n
dan nomor output dari interval setengah terbuka [0,1) (melanggar contoh kedua) - Jika bahasa Anda tidak mendukung angka floating point, Anda dapat memalsukan output dengan setidaknya sepuluh digit desimal setelah titik desimal.
- Celah standar tidak diizinkan dan metode input / output standar diizinkan.
- Ini adalah kode-golf , sehingga entri terpendek, diukur dalam byte, menang.
This is equal to uniformly sampling from the intersection
- saya dapat melihat program memilih secara acak hanya dari sudut persimpangan itu. Apakah itu valid?s==0 or s==3
. Untuk semua nilai lainnyas
, bidang memiliki bidang nol dan Anda harus memilih titik pada bidang tersebut secara acak.s=2.99999999999, n=3
? Bisakah kita menghasilkan real acak dalam kelipatan, katakanlah1e-9
,?Jawaban:
Bahasa Wolfram (Mathematica) ,
9290 byteCobalah online!
Hapus kode golf:
Berikut adalah solusi yang bekerja dalam 55 byte tetapi untuk saat ini (Mathematica versi 12) dibatasi
n=1,2,3
karenaRandomPoint
menolak untuk menarik poin dari hyperplanes dimensi yang lebih tinggi (dalam versi TIO 11.3 juga gagal untukn=1
). Ini mungkin bekerja untuk yang lebih tinggin
di masa depan:Cobalah online!
Hapus kode golf:
sumber
JavaScript (Node.js) ,
122115 byteCobalah online!
sumber
Python 2 ,
144128119 byteCobalah online!
sumber
g(4, 2.0)
1.000 kali untuk mendapatkan 4.000 poin dan hasilnya terlihat seperti ini yang tampak seragam.Java 8,
194188196237236 byte+49 byte (188 → 196 dan 196 → 237) untuk memperbaiki kecepatan kasus uji mendekati 1, serta memperbaiki algoritme secara umum.
Cobalah online
Penjelasan:
Menggunakan pendekatan dalam jawaban StackoverFlow ini , di dalam lingkaran selama salah satu item masih lebih besar dari 1.
Selain itu, jika
2*s>n
,s
akan diubah menjadin-s
, dan sebuah bendera ditetapkan untuk menunjukkan bahwa kita harus menggunakan1-diff
alih-alihdiff
dalam array hasil (terima kasih atas tip @soktinpk dan @ l4m2 ).sumber
test(10, 9.99);
10, 9.0
setelah saya diedit untuk memperbaikin=10, s=9.999999999999
test case .. Tidak yakin apakah ada perbaikan di Java sementara masih menggunakan keacakan yang seragam .. Harus memikirkannya sebentar. Untuk sekarang saya akan mengeditnya untuk menyatakan waktu habis.n-s<1
Anda dapat meneleponf(n,n-s)
dan membalikkan setiap nomor1/2
(mis. Gantix
dengan1-x
) seperti yang dilakukan l4m2. Ini mungkin memecahkan masalah untuk nomors
yang dekatn
.s+s>n
bukann-s<1
, tetapi ketika saya melihat jawaban JavaScript yang lain itu memang masuk akal. Semuanya sudah diperbaiki sekarang, termasuk bug lain yang masih ada. Bytes naik sedikit, tetapi setiap berfungsi sekarang. Akan bekerja menghitung mundur byte dari sini. :)JavaScript (Node.js) , 153 byte
Cobalah online!
sumber
C ++ 11,
284267 byte-17 byte berkat Zacharý
Menggunakan perpustakaan acak C ++, keluaran pada keluaran standar
Untuk menelepon, Anda hanya perlu melakukan itu:
Di mana parameter templat (di sini, 2) adalah N, dan parameter aktual (di sini, 0,0) adalah S
sumber
<z>
danu
typedef float z;template<int N>void g(z s){z a[N],d=s/N;int i=N;for(;i;)a[--i]=d;std::uniform_real_distribution<z>u(.0,d<.5?d:1-d);std::default_random_engine e;for(;i<N;){z c=u(e);a[i]+=c;a[++i]-=c;}for(;i;)std::cout<<a[--i]<<' ';}
.d
sepenuhnya dengan mengubahd=s/N
kes/=N
Sarankan pengerjaan ulang lingkaran keduafor(z c;i<N;a[++i%N]-=c)a[i]+=c=u(e);
alih-alihfor(;i<N;){z c=u(e);a[i]+=c;a[++i]-=c;}
(perhatikan yang ditambahkan%N
untuk membuat program menghitung angka pertama dengan benar)Bersih ,
221201 byteMembersihkan, kode-golf, atau angka acak. Ambil dua.
Cobalah online!
Fungsi parsial literal
:: (Int Real -> [Real])
. Hanya akan menghasilkan hasil baru sekali per detik.Akurat hingga setidaknya 10 desimal.
sumber
R , 99 byte (dengan
gtools
paket)Cobalah online!
Jikas = 1 D i r i c h l e t ( 1 , 1 , … , 1 ) s ≠ 1 < 1 / dtk s .
sumber
C,
132127125118110107 byte-2 byte terima kasih kepada @ceilingcat
Cobalah online!
sumber
[0,1]
, dan distribusi bersama mereka tidak seragam.n=4
nilai-nilai Andas=3.23
dans=0.89
berikan output di luar kisaran. Lebih tepatnya, distribusiX-s/n
harus bergantung padas
, tetapi tidak.Haskell ,
122217208 byteCobalah online!
Kadang-kadang jawabannya sedikit tidak baik, saya berasumsi, karena kesalahan floating point. Jika masalah, saya bisa memperbaikinya dengan biaya 1 byte. Saya juga tidak yakin seberapa seragam ini (cukup yakin itu baik-baik saja tapi saya tidak begitu pandai dalam hal semacam ini), jadi saya akan menjelaskan algoritma saya.
Ide dasarnya adalah untuk menghasilkan angka
x
kemudian mengurangis
dan mengulanginya sampai kita memilikin
elemen kemudian mengocoknya. Saya menghasilkanx
dengan batas atas baik 1 ataus
(mana yang lebih kecil) dan batas bawahs-n+1
atau 0 (mana yang lebih besar). Batas bawah itu ada sehingga pada iterasi berikutnyas
masih akan kurang dari atau sama dengann
(derivasi:s-x<=n-1
->s<=n-1+x
->s-(n-1)<=x
->s-n+1<=x
).EDIT: Terima kasih kepada @ michi7x7 karena telah menunjukkan kekurangan pada keseragaman saya. Saya pikir saya sudah memperbaikinya dengan mengocok tetapi beri tahu saya jika ada masalah lain
EDIT2: Peningkatan jumlah byte ditambah pembatasan tipe tetap
sumber
Haskell , 188 byte
Tidak Disatukan:
Cobalah online!
sumber