Program / fungsi Anda harus
- Output tepat satu integer
- Output setiap bilangan bulat dengan probabilitas positif
- menghasilkan bilangan bulat lebih besar dari 1.000.000 atau kurang dari -1.000.000 dengan setidaknya dengan probabilitas 50%.
Contoh output (semua harus dimungkinkan):
59875669123
12
-42
-4640055890
0
2014
12
24
-7190464664658648640055894646646586486400558904644646646586486400558904646649001
Klarifikasi:
- Istirahat garis trailing diizinkan.
- Angka nol di depan tidak diizinkan.
-0
diizinkan.
Kode terpendek menang.
way too long to fit in an integer
- Ini hanya benar jika Anda menganggap ituinteger
berartiint
tipe data pada lengkungan 32/64 bit, yang belum tentu asumsi yang valid. "Integer" dimulai sebagai istilah matematika , yang tidak memiliki batasan ukuran.Jawaban:
CJam,
161413 byteIni akan berjalan untuk waktu yang sangat lama, karena ia menggunakan cap waktu saat ini (pada urutan 10 12 ) untuk menentukan apakah loop harus diakhiri. Saya menggunakan ini sebagai kiriman, karena ini adalah yang terpendek, tetapi ada dua alternatif 14-byte, yang memiliki kelebihan sendiri:
Yang ini tidak dibatasi oleh periode PRNG, karena rentang semua angka acak tergantung pada cap waktu saat ini. Oleh karena itu, ini harus dapat menghasilkan angka apa pun, walaupun kemungkinan untuk negatif, atau bahkan angka positif kecil semakin kecil.
Di bawah ini adalah versi yang setara yang menggunakan
3e5
bukan timestamp. Dan20
untuk rentang pertama (seperti pengiriman 13 byte). Ini jauh lebih cepat dan juga mematuhi semua aturan. Ini adalah semacam pembatas kasus untuk mendapatkan probabilitas 50% untuk angka di atas 1.000.000 sambil menjaga runtime yang masuk akal dan ukuran kode kecil. Penjelasan dan pembenaran matematis merujuk pada versi ini:Ini biasanya membutuhkan beberapa detik untuk berjalan. Anda dapat mengganti dengan
5
dengan2
untuk membuatnya berjalan lebih cepat. Tetapi kemudian persyaratan 50% probabilitas hanya akan dipenuhi untuk 1.000, bukan 1.000.000.Saya mulai dari 0. Kemudian saya mendapatkan satu lingkaran, yang saya hentikan dengan probabilitas 1 / (3 * 10 5 ). Dalam loop itu saya menambahkan bilangan bulat acak antara -1 dan 18 (inklusif) ke total berjalan saya. Ada probabilitas yang terbatas (walaupun kecil) bahwa setiap bilangan bulat akan menjadi output, dengan bilangan bulat positif lebih mungkin daripada yang negatif (saya tidak berpikir Anda akan melihat yang negatif dalam hidup Anda). Keluar dengan probabilitas sekecil itu, dan menambah sebagian besar waktu (dan menambahkan lebih banyak daripada mengurangi) memastikan bahwa kita biasanya melampaui 1.000.000.
Beberapa pembenaran matematika:
Probabilitas yang akan kita lakukan kurang dari jumlah langkah ini adalah
yang dievaluasi menjadi
0.324402
. Oleh karena itu, dalam sekitar dua pertiga dari kasus, kami akan mengambil 117.647 langkah, dan masing-masing 1.000.000.9e9
tanpa menambahkan byte (tetapi bertahun-tahun runtime).... atau 11 byte?
Akhirnya, ada versi 11 byte, yang juga tidak dibatasi oleh periode PRNG, tetapi yang akan kehabisan memori hampir setiap waktu. Ini hanya menghasilkan satu nomor acak (berdasarkan stempel waktu) setiap iterasi, dan menggunakannya baik untuk menambah dan mengakhiri. Hasil dari setiap iterasi tetap di stack dan hanya disimpulkan di akhir. Terima kasih kepada Dennis untuk ide ini:
sumber
Kmr
dalam suatu periode kemungkinan masih selalu merupakan angka positif besar yang lebih besar dari periode tersebut. Dan itu tidak dapat menghasilkan setiap angka yang mungkin dalam kasus itu.Jawa,
133149Keluaran contoh
Tidak disatukan
Jawaban lama (sebelum perubahan aturan)
sumber
-
.Mathematica - 47
Pada dasarnya hanya menghasilkan angka acak menggunakan distribusi normal dengan varians sama dengan 1500000. Ini akan menghasilkan bilangan bulat antara -10 ^ 6 dan 10 ^ 6 dengan probabilitas 49,5015%.
sumber
Python 2,
7569 byteItu sepele untuk memeriksa bahwa loop sementara di tengah dapat menghasilkan semua bilangan bulat (meskipun bias terhadap nol). "12" dipilih sedemikian rupa sehingga kira-kira setengah dari angka yang melebihi ± 10 6 .
Solusi yang lebih lama:
Python 2, 44 byteBerdasarkan solusi Mathematica .Tidak benar-benar berfungsi karena Python
float
hanya memiliki ketepatan terbatas.sumber
Ruby, 70
Untuk membuat menghasilkan angka yang sangat besar, saya mengembalikan angka sebagai a
String
dari lambda. Jika itu tidak diizinkan, hitung 8 karakter tambahan (untukputs f[]
) untuk menjadikannya program alih-alih fungsi.Penjelasan
Hasilkan nomor antara
-1,000,000
dan1,000,000
. Jika angkanya1
atau lebih tinggi, angkanya dikembalikan sebagai aString
.Jika angkanya lebih rendah dari
1
, fungsinya disebut secara rekursif untuk mengembalikan nomor di luar rentang angka. Untuk memastikan angka negatif juga dapat dihasilkan, a-
diawali dengan hasilString
jika angka awal lebih besar dari-500,000
.Saya harap saya memahami tantangan dengan benar!
sumber
R, 38
Penarikan dari distribusi Gaussian dengan rata-rata 2.000.000, dipilih secara acak, dan standar deviasi 1.000.000, sehingga sekitar 2/3 dari pengundian akan berada dalam 1.000.000 dan 3.000.000. Distribusi tidak terikat sehingga secara teori ini dapat menghasilkan bilangan bulat apa pun. Paket Rmpfr menggantikan R's built in double floats dengan presisi sewenang-wenang.
sumber
sample(c(1,-1),1)
berpikir secara keseluruhan . Hanya berpusat pada 1e6 sudah cukup ..Perl, 53 karakter
Saya jelas tidak melihat alasan untuk bekerja dengan bilangan bulat saat mencetaknya :)
Memiliki probabilitas yang sama untuk mencetak nomor dengan atau tanpa "-" pengarah.
Mencetak angka 1 digit 10% dari waktu, angka 2 digit 9% dari waktu, angka 3 digit 8,1% dari waktu, angka 4 digit 7,29% dari waktu, angka 5 digit 6,56% dari waktu, angka 6-digit 5,9% dari waktu, dll. Panjang mana pun dimungkinkan, dengan kemungkinan menurun. Angka satu hingga lima digit mencapai sekitar 41,5% dari kasus keluaran, dan jumlah 1.000.000 (atau -1.000.000) hanya 6 juta per persen, sehingga jumlah output akan berada di luar kisaran -1.000.000 hingga 1.000.000 sekitar 54,6 % waktu.
Baik "0" dan "-0" adalah output yang mungkin, yang saya harap tidak menjadi masalah.
sumber
print int(rand(20)-10)||1
. Saya butuh cara untuk menghasilkan 0 sebagai output, meskipun. Mungkin || mati 0, jika sampah setelah nol dibolehkan. Lain perlu cara singkat untuk mencetak nol dan keluar tanpa output lebih lanjut jikaint(rand(20)-10)==0
.Perl, 114 Chars
Kerusakan:
Peluang untuk mendapatkan nilai antara -1.000.000 dan 1.000.000 cenderung nol tetapi itu mungkin.
Perl, 25Menghasilkan bilangan bulat acak dalam kisaran +/- 2 ^ 99.
Kerusakan
Diuji dengan 1 juta sampel:
Ini memenuhi semua aturan:
Edit:
Saya harus meningkatkan eksponen sehingga bilangan bulat yang lebih besar dihasilkan. Saya memilih 99 karena menjaga kode sesingkat mungkin.sumber
-2^31
dan+2^31-1
(32 bit). Anda dapat dengan mudah meningkatkan eksponen jika Anda ingin menghasilkan bilangan bulat yang lebih besar tetapi mungkin gagal tergantung pada implementasi Perl.1.#INF
tepatnya)C #,
126107 byteTidak Disatukan:
Peluang untuk menghasilkan sejumlah n digit adalah 1/2 ^ (n-10), yang lebih besar dari 0 untuk semua n positif, dan 1/2 untuk n = 11.
Juga menciptakan angka nol di depan, yang tampaknya tidak diingkari dalam pertanyaan awal atau komentarnya.sumber
using System;
, Anda tidak perluSystem.Random
dua kali, tetapi hanyaRandom
, kan?using
pernyataan. Itu hanya akan menghemat 1 char.-1E6, 1E6+1
.Perl, 62 byte
print $n=int rand(20)-10;while($n&&rand>.1){print int rand 10}
Saya memiliki ide yang sama dengan @Hobbs, untuk menghasilkan digit pada satu waktu, tetapi kodenya tidak memenuhi persyaratan tambahan no-leading-zero. Menghasilkan digit pertama dan bukan hanya pertanda memecahkannya. Dan kecuali ada cara yang lebih pendek untuk keluar jika kita mencetak nol, atau cara yang lebih pendek untuk menghasilkan -9 ke 9, ini harus dilakukan untuk ukuran.
Dalam lingkaran shell:
while perl -e '...'; do echo;done |less
Saya pikir ini adalah salah satu yang terpendek yang tidak memerlukan RAM yang tak terbatas untuk memenuhi masalah. Sebagai bonus, hasilnya tidak terlalu bias terhadap apa pun, dan runtime sangat cepat.
Saya mencoba menggunakan bitwise dan untuk menyimpan karakter dalam kondisi sementara, tapi saya pikir ini akhirnya menjadi benar lebih sering, sehingga loop berakhir lebih cepat. Akan membutuhkan lebih banyak karakter untuk menyesuaikan hal-hal lain untuk mengatasinya, untuk mempertahankan probabilitas menghasilkan abs (output)> 1M.
sumber
Javascript (73)
Solusi ini menggunakan bahwa Anda dapat membuat angka dengan basis n dengan mengalikan angka sebelumnya dengan n dan menambahkan angka dalam basis n . Kami memiliki tambahan
..?..:..
di sana untuk dapat membuat semua bilangan bulat negatif. Kode berikut harus diuji di konsol browser.Probabilitas untuk mendapatkan integer> =
2^1
(atau <=-(2^1)
) sama dengan kemungkinan loop dijalankan 2 kali. Peluang terjadinya itu adalah(98/99)^2
. Karena itu peluang untuk mendapatkan angka yang lebih besar dari2^20
(atau <=-(2^20)
) adalah(98/99)^21 = 0.808
81%. Ini semua dalam teori, dan dengan asumsi bahwa Math.random benar-benar acak. Jelas tidak.Cuplikan menguji kode ini. Juga dengan cara yang lebih mudah dibaca.
Tampilkan cuplikan kode
sumber
GolfScript, 20 byte
Ya, ini juga agak lambat.
Dibandingkan dengan bahasa-bahasa seperti CJam dan Pyth, GolfScript menderita kata kunci pembangkitan angka acak verbose (
rand
). Untuk mengatasi cacat ini, saya perlu menemukan cara untuk menggunakannya hanya sekali.Kode ini bekerja dengan berulang kali memilih angka acak antara 0 dan 8 8 −1 = 16.777.215 inklusif, dan menambah penghitung hingga bilangan acak menjadi 0. Nilai penghitung yang dihasilkan memiliki distribusi geometris dengan median sekitar -1 / log 2 (1 - 1/8 8 ) ≈ 11.629.080, sehingga memenuhi tes "lebih dari 1.000.000 setidaknya 50% dari waktu".
Sayangnya, angka acak yang dihasilkan selalu benar-benar positif. Jadi, ekstra
.2&(*4/
diperlukan untuk menjadikannya negatif atau nol. Ia bekerja dengan mengekstraksi bit terendah nomor kedua (yang dengan demikian 0 atau 2), menurunkannya menjadi -1 atau 1, mengalikannya dengan angka asli, dan membagi hasilnya dengan 4 (untuk menghilangkan dua bit terendah, yang sekarang berkorelasi dengan tanda, dan juga untuk memungkinkan hasilnya menjadi nol). Bahkan setelah pembagian dengan 4, nilai absolut dari angka acak masih memiliki median -1 / log 2 (1 - 1/8 8 ) / 4 ≈ 2.907.270, sehingga masih melewati tes 50%.sumber
JavaScript, 81 byte
Kode ini memenuhi semua aturan:
0
dalam outputSebagai bonus, algoritma ini berjalan dengan kompleksitas waktu O (log 10 n) sehingga mengembalikan integer hampir secara instan.
Ini mengasumsikan lingkungan REPL. Coba jalankan kode di atas di konsol browser Anda, atau gunakan snipet stack di bawah ini:
Algoritma :
s
hingga aMath.random() > 0.1
.Math.random() > 0.5
, buat angka negatif (dengan mengawali strings
dengan-
).Algoritma ini tidak memiliki distribusi seragam di semua bilangan bulat. Integer dengan jumlah digit yang lebih tinggi lebih kecil kemungkinannya daripada yang lebih rendah. Di setiap untuk iterasi loop, ada kemungkinan 10% bahwa saya akan berhenti pada digit saat ini. Saya hanya harus memastikan bahwa saya berhenti setelah 6 digit lebih dari 50% dari waktu.
Persamaan ini oleh @nutki menjelaskan nilai maksimum persentase peluang berhenti berdasarkan kondisi di atas:
Dengan demikian 0,1 berada dalam jangkauan untuk memenuhi ketiga aturan pertanyaan.
sumber
TI-BASIC, 14 byte
Mirip dengan jawaban R @ ssdecontrol, ini diambil dari distribusi Gaussian dengan rata-rata -1.000.000 atau 1.000.000, dipilih secara acak, dan standar deviasi 9. Distribusi tidak terikat sehingga secara teori ini dapat menghasilkan bilangan bulat apa pun.
Penjelasan :
sumber
:
berarti "cetak" karena bagaimana penjelasannya disajikan). Tapi bisakah itu menghasilkan angka lebih dari 20 digit?randNorm
?Bash, 66
Hampir selalu mencetak 50.000.000. Tetapi jika menemukan nomor yang valid
/dev/random
, ia akan mencetak nomor itu.Dan ini lebih cepat:
sumber
/dev/urandom
yang kurang acak./dev/urandom
dalam skrip shell pada dasarnya sama dengan memanggilrand()
dalam bahasa lain. Meskipun jika Anda benar-benar menggunakan bash, bukan POSIX sh, Anda bisa mendapatkan nomor acak dariecho $RANDOM
. wiki.ubuntu.com/DashAsBinSh memberihexdump /dev/urandom
sebagai yang setara untuk minimum-POSIX/bin/dash
.C ++, 95 byte
Diperluas:
Penjelasan:
Fungsi ini terus mencetak angka acak berurutan hingga sakelar nilai acak mengambil nilai yang diperlukan untuk menghentikan fungsi. d adalah variabel yang menjaga nilai digit berikutnya untuk dicetak. s adalah variabel sakelar yang mengambil nilai bilangan bulat acak dalam interval [0, 9], jika s == 9 maka tidak ada lagi digit yang dicetak dan funtion berakhir.
Variabel d dan s diinisialisasi untuk memberikan perlakuan khusus pada digit pertama (mengambilnya dari interval [-9, 9] dan jika digit pertama adalah nol maka fungsi harus diakhiri untuk menghindari memimpin nol). Nilai d dapat ditetapkan sebagai d = rand ()% 10 tetapi kemudian digit pertama tidak boleh negatif. d ditugaskan sebagai d = (rand ()% 19 + d + 9)% 10 dan diinisialisasi pada -18 sehingga nilai pertama dari d akan berkisar dari [-9, 9] dan nilai selanjutnya akan selalu berkisar dari [0 , 9].
Variabel s berkisar secara acak dari [0, 9], dan jika s sama dengan 9, fungsi berakhir, jadi setelah mencetak digit pertama yang berikutnya akan dicetak dengan probabilitas 90% (dengan asumsi rand () benar-benar acak, dan untuk memenuhi kondisi ketiga). s dapat dengan mudah ditetapkan sebagai s = rand ()% 10, namun, ada pengecualian, jika digit pertama adalah nol, fungsi harus diakhiri. Untuk menangani pengecualian tersebut, s telah ditetapkan sebagai s = 9-rand ()% 10 * min (d * d + s + 1,1) dan diinisialisasi sebagai -1. Jika digit pertama adalah nol, min akan mengembalikan 0 dan s akan sama dengan 9-0 = 9. Tugas variabel s akan selalu berkisar dari [0, 9], jadi pengecualian hanya dapat terjadi pada digit pertama.
Karakteristik (dengan asumsi rand () benar-benar acak)
Integer dicetak digit demi digit, dengan probabilitas tetap 90% untuk mencetak digit lain setelah mencetak yang terakhir.
0 adalah bilangan bulat dengan peluang tertinggi untuk dicetak, dengan probabilitas sekitar 5,2%.
Probabilitas mencetak bilangan bulat pada interval [-10 ^ 6, 10 ^ 6] adalah sekitar 44% (perhitungan tidak ditulis di sini).
Bilangan bulat positif dan negatif dicetak dengan probabilitas yang sama (~ 47,4%).
Tidak semua digit dicetak dengan probabilitas yang sama. Misalnya: di tengah pencetakan bilangan bulat, jika digit terakhir adalah 5, digit 3 akan memiliki peluang yang sedikit lebih rendah untuk dicetak berikutnya. Secara umum, jika digit terakhir adalah d, digit (d + 18)% 10 akan memiliki peluang yang sedikit lebih rendah untuk dicetak berikutnya.
Contoh output (10 eksekusi)
sumber
Bash, 42 byte
printf "%d\n" 0x$(xxd -p -l5 /dev/random)
/ dev / random pada OSX hanya byte acak, dan
xxd -p -l5
mengubah 5 karakter ascii menjadi hex, danprintf
mengubahnya menjadi format desimal.sumber
Pyth , 11 byte
Catatan: program ini mungkin akan macet dengan kesalahan memori di komputer mana pun. Untuk mengujinya, coba ganti
G
dengan string yang lebih pendek, seperti dalam kode ini, yang menghasilkan angka rata-rata sekitar 28000:Kode ini berulang, menambahkan angka acak dari -1 hingga 8
Z
, dengan probabilitas 2 ^ -26 keluar dari loop pada setiap pengulangan. Probabilitas 2 ^ -26 diperoleh dengan memilih elemen acak (O
) dari himpunan semua himpunan bagian (y
) dari alfabet (G
).Detail & justifikasi teknis:
Probabilitas 2 ^ -26 berasal dari dua fakta:,
y
ketika dipanggil pada sekuens, adalah fungsi power-set, sebuah susunan daftar semua himpunan bagian dari input. Karena input,,G
adalah 26 karakter, set daya ini,yG
memiliki 2 ^ 26 entri.OyG
memilih elemen acak dari 2 ^ 26 entri itu. Salah satu dari entri itu, string kosong, akan dievaluasi sebagai falsy ketika diteruskan keW
, while. Oleh karena itu, ada kemungkinan 2 ^ -26 keluar dari loop setiap kali.Dalam jumlah tetap dari siklus loop K, probabilitas mendapatkan angka K * 3.5 + m dan mendapatkan K * 3.5 - m adalah sama, karena setiap urutan penambahan yang mencapai satu total dapat dibalik, -1 -> 8, 0 -> 7, dll., Untuk mencapai yang lain. Selain itu, angka yang lebih dekat ke K * 3,5 jelas lebih mungkin daripada angka yang lebih jauh. Dengan demikian, jika K> 2000000 / 3.5 = 571428.5 kemungkinan mendapatkan angka lebih dari 10.00000 lebih besar dari 75%, karena beberapa hasil di atas angka itu dapat dimasukkan ke dalam korespondensi satu-ke-satu dengan semua hasil di bawah ini yang angka, dan bagian atas kurang dari setengah, dapat dimasukkan ke dalam korespondensi satu-ke-satu dengan yang di bawah 1000000. Kemungkinan mendapatkan setidaknya 571429 loop adalah (1-2 ^ -26) ^ 571429, yang tidak ada kurang dari (1-2 ^ -26 * 571429), perkiraan berapa kali meninggalkan loop pada 571429 percobaan pertama, yaitu 99,1%. Jadi, pada 99,1% atau lebih uji coba, ada kemungkinan 75% atau lebih untuk mendapatkan setidaknya 10.00000, sehingga ada lebih dari 50% peluang untuk mendapatkan lebih dari 10.00000.
Kode ini bergantung pada perilaku di
O
mana bug diperkenalkan secara tidak sengaja 3 hari yang lalu dan diperbaiki hari ini. Ini harus bekerja pada versi Pyth 3 apa pun dari sebelum 22 Desember, atau setelah hari ini. Kode berikut ini setara, dan selalu berfungsi:sumber
Java, 113 byte
Program ini mencetak angka biner ke aliran keluaran standar. Anda mungkin harus menunggu beberapa saat karena probabilitas untuk mengakhiri angka (atau positif) adalah sekitar 0. Gagasan bahwa nilai absolut dari angka yang dihasilkan kurang dari 1 juta adalah lucu, namun dimungkinkan.
Tidak Disatukan:
Contoh output: Akan memposting ketika angka selesai dibuat.
sumber
Java (JDK) ,
140127 byte-13 bytes
dengan menyelinap lebih banyak logika ke header loop - terima kasih kepada @ceilingcatCobalah online!
sumber