Mari kita lihat seberapa bagus bahasa pilihan Anda dalam keacakan selektif.
Mengingat 4 karakter, A
, B
, C
, dan D
, atau string dari 4 karakter ABCD
sebagai masukan , keluaran salah satu karakter dengan probabilitas berikut:
A
harus memiliki 1/8 (12,5%) kesempatan untuk dipilihB
harus memiliki kesempatan 3/8 (37,5%) untuk dipilihC
harus memiliki 2/8 (25%) kesempatan untuk dipilihD
harus memiliki 2/8 (25%) kesempatan untuk dipilih
Ini sejalan dengan tata letak mesin Plinko berikut :
^
^ ^
^ ^ ^
A B \ /
^
C D
Jawaban Anda harus melakukan upaya tulus untuk menghormati probabilitas yang dijelaskan. Penjelasan yang tepat tentang bagaimana probabilitas dihitung dalam jawaban Anda (dan mengapa mereka menghormati spesifikasi, mengabaikan pseudo-randomness dan masalah angka besar) sudah cukup.
Mencetak gol
Ini adalah kode-golf sehingga byte paling sedikit di setiap bahasa menang!
ceil(abs(i - 6)/ 2.0)
akan memetakan indeks dari0-7
ke indeks dari0-3
dengan distribusi yang sesuai (0 111 22 33
) untuk tantangan ini ...Jawaban:
Lean Mean Bean Machine ,
554342 byte-13 byte berkat Alex Varga
Semoga kalian tidak keberatan saya menjawab pertanyaan saya sendiri setelah hanya 2 jam, tapi saya sangat ragu ada orang lain yang berencana memposting jawaban di LMBM.
Ini benar-benar hanya mencerminkan tata letak Plinko yang ditunjukkan dalam OP, membalik secara horizontal untuk mengurangi ruang putih yang tidak perlu.
sumber
Jelly , 6 byte
Tautan monadik mengambil daftar empat karakter dan mengembalikan satu dengan distribusi probabilitas yang dijelaskan.
Cobalah online!
Bagaimana?
sumber
ṁ
!Cubix ,
3924222119 byteLihat di penerjemah online!
Ini memetakan ke jaring kubus berikut:
Penjelasan Implementasi Distribusi Acak
Cubix adalah bahasa di mana penunjuk instruksi berjalan di sekitar wajah sebuah kubus, menjalankan perintah yang dihadapinya. Satu-satunya bentuk keacakan adalah perintah
D
, yang mengirim IP dalam arah acak: kesempatan yang sama untuk1/4
setiap cara.Namun, kita bisa menggunakan ini untuk menghasilkan probabilitas tertimbang yang benar: dengan menggunakan
D
dua kali. Yang pertamaD
memiliki1/4
judul menuju yang keduaD
. Yang kedua iniD
, bagaimanapun, memiliki dua arah diblokir dengan panah (> D <
) yang mengirim penunjuk instruksi kembali keD
untuk memilih arah lain. Ini berarti hanya ada dua kemungkinan arah dari sana, masing-masing dengan1/8
kemungkinan keseluruhan terjadi. Ini dapat digunakan untuk menghasilkan karakter yang benar, seperti yang ditunjukkan pada diagram di bawah ini:(Perhatikan bahwa, dalam kode aktual, panah di sebelah kanan diganti dengan cermin,
|
)Penjelasan Kode
Penunjuk instruksi dimulai di sebelah kanan, di karakter
i
, menghadap ke kanan. Menjalankan inii
, mengambil karakter pertama sebagai input, dan kemudian bergerak keD
, memulai proses acak yang ditunjukkan di atas.Char A: Dalam hal yang pertama
D
mengirim kami ke timur, dan selatan yang kedua, kita perlu mencetak karakter A. Ini sudah di stack dari yang pertamai
. Berikut ini dieksekusi:\
- Refleksikan IP sehingga mengarah ke timuri;
- Ambil input, lalu pop lagi (no-op)U
- Lakukan putar-U, putar IP kiri dua kalio
- Keluarkan TOS, karakter A@
- Hentikan programChar B: Jika kepala pertama atau kedua
D
utara, kita perlu menghasilkan karakter B, yang akan menjadi input berikutnya. Kedua jalur menjalankan perintah berikut:^
- Kepala utara<
- Kepala barat, membungkus ...i
- Ambil input lain, karakter Bo
- Keluarkan TOS, karakter B;
- Pop TOS@
- Hentikan programChar C: Jika yang pertama
D
mengirim kami ke barat, yang berikut ini dijalankan:i
- Ambil input lain, karakter Bi
- Ambil input lain, karakter Co
- Keluaran TOS, karakter C@
- Hentikan programChar D: Jika yang pertama
D
mengirim kami ke selatan, yang berikut ini dijalankan:i
- Ambil input lain, karakter B..
- Dua no-opsi
- Ambil input lain, karakter C|
- Cermin ini memantulkan timur-barat, tetapi IP mengarah ke utara, jadi kami melewatinya.^
- Ini bergabung dengan jalur yang diambil untuk karakter B. Namun, karena kami telah mengambil dua input, karakter keempat (karakter D) akan berakhir dicetak.sumber
Python , 50 byte
Fungsi tanpa nama mengambil dan mengembalikan string (atau daftar karakter).
Cobalah online!
Bagaimana?
random.choice
memilih elemen acak dari daftar, sehingga fungsi membentuk string dengan distribusi yang benar, yaitu, diberikan"ABCD"
,"ABCD"[:2] = "AB"
ditambah"ABCD"[1:]*2 = "BCD"*2 = "BCDBCD"
yang mana"ABBCDBCD"
.sumber
R , 31 byte
Membaca karakter dari
stdin
dipisahkan oleh spasi.sample
mengambil sampel acak dari input pertama dalam jumlah input kedua (so1
), (argumen penggantian opsional), dengan bobot yang diberikan oleh argumen terakhir.Cobalah online!
Cobalah
n
berkali - kali!Untuk kode yang terakhir, saya sampel
n
kali (diaturn
di header) dengan penggantian diatur keT
rue (itu salah secara default), tabulasikan hasilnya, dan bagi dengann
untuk melihat probabilitas relatif dari input.sumber
PHP, 28 byte
Jalankan sebagai pipa dengan
-nR
.01112233
di basis-45551
dalam desimal ...sumber
7030
adalah salah satu favorit pribadi saya.Java 8,
5344 byteIni adalah
Function<char[], Character>
.Cobalah online! (Program tes ini menjalankan fungsi di atas 1.000.000 kali dan output probabilitas eksperimental memilih
A
,B
,C
, danD
).Ide umum di sini adalah untuk menemukan beberapa cara untuk memetakan
0-7
ke0-3
, sehingga0
muncul1/8
kali,1
muncul3/8
kali,2
muncul2/8
kali, dan3
muncul2/8
kali.round(abs(k - 6) / 2.0))
bekerja untuk ini, di manak
bilangan bulat acak dalam kisaran[0,8)
. Ini menghasilkan pemetaan berikut:Yang, seperti yang Anda lihat, hasil dalam indeks
0 111 22 33
, yang menghasilkan probabilitas yang diinginkan1/8
,3/8
,2/8
dan2/8
.Tapi tunggu! Bagaimana di dunia
-~Math.abs(k-6)/2
mencapai hasil yang sama (sekali lagi, di manak
bilangan bulat acak dalam kisaran[0,8]
)? Ini sebenarnya cukup sederhana ...(x+1)/2
(pembagian integer) adalah hal yang sama denganround(x/2)
, danx + 1
hal yang sama dengan-~x
. Meskipunx+1
dan-~x
memiliki panjang yang sama, dalam fungsi di atas lebih baik digunakan-~x
karena lebih-~
diutamakan dan dengan demikian tidak memerlukan tanda kurung.sumber
Math.abs
juga menerima ganda sebagai parameter):s->s[-~(int)Math.abs(Math.random()*8-6)/2]
( 42 byte ).APL, 14 byte
Input sebagai string.
Bagaimana?
1 3 2 2\⊢
- ulangi setiap huruf x kali ('ABCD'
→'ABBBCCDD'
)⊃
- ambil elemen di indeks ..(?8)
- acak 1-8sumber
⎕U2378
.Arang , 11 byte
Cobalah online! Tautan adalah untuk versi kode yang verbose, meskipun Anda tidak membutuhkannya;
‽
mengambil elemen acak,⟦⟧
membuat daftar, dan variabelnya adalah mereka yang mendapatkan huruf input yang sesuai (dalam urutan terbalik karena saya merasa menyukainya).sumber
Pyth ,
87 byteMenggunakan algoritma yang sama persis seperti pada jawaban Python saya.
Coba di sini!
Pyth ,
108 byteMenggunakan algoritma yang sama persis seperti jawaban Python Jonathan Allan's.
Coba di sini!
Penjelasan
O
- Mengambil elemen acak dari String yang dibuat dengan menambahkan (dengan+
):<Q2
- Dua karakter pertama dari String.*2t
Gandakan seluruh String (*2
) kecuali karakter pertama (t
).Menerapkan algoritma ini untuk
ABCD
:<Q2
mengambilAB
.*2t
mengambilBCD
dan ganda itu:BCDBCD
.+
bergabung dengan dua Strings:ABBCDBCD
.O
mengambil karakter acak.-2 Berkat Leaky Nun (solusi kedua)
-1 berkat mnemonic (solusi pertama)
sumber
>Q1
menjaditQ
, yang menjadit
.*2
dengan+
dan menggunakan input implisit dua kali.y
sebaliknya, yang tidak berfungsi untuk string ...Jelly , 8 byte
Cobalah online!
Hapus
X
untuk melihat"ABBBCCDD"
. TheX
memilih elemen acak.sumber
C # (.NET Core) ,
7655 byteCobalah online!
Jawaban pertama saya ditulis langsung di TIO menggunakan ponsel saya. Naik tingkat!
Penjelasan: jika string asli adalah "ABCD", fungsi tersebut menciptakan string "ABCDBBCD" dan mengambil elemen acak darinya.
sumber
Javascript 35 byte
Mengambil string
ABCD
sebagai input, menghasilkanA
1/8 waktu,B
3/8 waktu,C
1/4 waktu, danD
1/4 waktu.Penjelasan
sumber
05AB1E , 5 byte
Cobalah online!
Penjelasan
sumber
> <> ,
252219 byteCobalah online! , atau tonton di taman bermain ikan !
Gambaran singkat tentang> <>: ini adalah bahasa 2D dengan ikan yang berenang melalui kode, menjalankan instruksi saat berjalan. Jika mencapai tepi kode, ia membungkus ke sisi lain. Ikan mulai di sudut kiri atas, bergerak ke kanan. Keacakan rumit dalam> <>: satu-satunya instruksi acak adalah
x
, yang menetapkan arah ikan secara acak dari atas, bawah, kiri dan kanan (dengan probabilitas yang sama).Pada awal program, ikan membaca dua karakter input dengan
i_i
(masing-masingi
membaca karakter dari STDIN ke tumpukan, dan_
merupakan cermin horizontal, yang diabaikan oleh ikan sekarang). Kemudian mencapaix
.Jika
x
mengirimkan ikan ke kanan, ia membaca dalam satu karakter lagi (yang ketiga), mencetaknya dengano
dan berhenti dengan;
. Arah kiri mirip: ikan membaca dua karakter lagi (jadi kita naik ke keempat), membungkus ke kanan, mencetak karakter keempat dan berhenti. Jika ikan berenang, ia membungkus dan mencetak karakter kedua, sebelum dipantulkan oleh/
dan dihentikan. Jika berenang turun, itu akan dipantulkan ke kiri oleh/
dan mengenai yang lainx
.Kali ini, dua arah hanya mengirim ikan kembali ke
x
(kanan dengan panah<
,, dan ke atas dengan cermin,_
). Oleh karena itu ikan memiliki kemungkinan 1/2 lolos dari inix
di masing-masing dua arah lainnya. Kiri mencetak karakter teratas pada stack, yang merupakan karakter kedua, tetapi ke bawah pertama-tama menukar kedua elemen pada stack dengan$
, jadi arah ini mencetak karakter pertama.Singkatnya, karakter ketiga dan keempat dicetak dengan probabilitas 1/4 masing-masing; karakter pertama memiliki probabilitas 1/2 x 1/4 = 1/8; dan karakter kedua memiliki probabilitas 1/4 + 1/2 x 1/4 = 3/8.
sumber
05AB1E , 8 byte
Cobalah online!
sumber
MATL ,
1210 byteCobalah online! Atau jalankan 1000 kali (kode sedikit dimodifikasi) dan periksa berapa kali masing-masing karakter muncul.
Penjelasan
Perubahan kode yang dimodifikasi:
1000:"Gl3HH4$vY"1Zr]vSY'
1000:"...]
adalah loop untuk mengulang1000
kali.G
memastikan input ditekan pada setiap awal iterasi.v
perlu diganti dengan4$v
hanya menyatukan4
nomor atas .v
gabungkan1000
hasilnya menjadi vektor,S
sortir, danY'
run-length mengkodekannya. Ini memberi empat huruf dan berapa kali mereka muncul.sumber
05AB1E , 6 byte
Cobalah online!
Penjelasan
Berfungsi untuk daftar dan string.
sumber
C (gcc) ,
5049 byteCobalah online!
sumber
ABCD
adalah contoh input, kode Anda harus mengambil 4 karakter (atau string dengan panjang 4) sebagai inputRuby,
34332927 byteDisimpan 2 byte berkat @Value Inc
Masukan sebagai empat karakter
membangun sebuah array
[B,B,C,D,A,B,C,D]
dan sampel itu.coba online!
coba
n
kali! (Saya mengonversinya menjadi fungsi untuk mengulanginya lebih mudah, tetapi algoritmanya sama)sumber
$*
adalah alias untukARGV
.Pyth, 7 byte
Suite uji
O8
menghasilkan angka acak dari 0 hingga 7.| ... 1
menggunakan logika atau dengan 1, mengonversi 0 menjadi 1 dan membiarkan semuanya tetap sama. Angka pada tahap ini adalah 1 2/8 waktu, dan 2, 3, 4, 5, 6, 7 atau 8 1/8 waktu.@z
mengindeks ke dalam string input pada posisi itu. Pengindeksan dilakukan modulo panjang string, jadi 4 indeks di posisi 0, 5 di posisi 1, dan seterusnya.Peluangnya adalah:
Posisi 0: Nomor acak 4. 1/8 dari waktu.
Posisi 1: Angka acak 0, 1 atau 5. 3/8 dari waktu.
Posisi 2: Nomor acak 2 atau 6. 2/8 dari waktu.
Posisi 3: Angka acak 3 atau 7. 2/8 dari waktu.
sumber
Javascript,
3130 byte / 23 byteMelihat jawaban Javascript sebelumnya asgallant membuat saya berpikir tentang JS. Seperti yang dia katakan:
Punya saya:
Penjelasan:
Dari
Math.random()*8&7
itu terurai sebagai berikut:Versi 2, 23 byte
Tapi kemudian terima kasih kepada Arnauld, yang diposting setelah saya, ketika dia berkata:
yang, jika memang diizinkan, mengarahkan saya ke:
di mana
new Date%8
menggunakan tabel break-down yang sama seperti di atas.Dan
%8
bisa juga&7
; ambil pilihanmu. Sekali lagi terima kasih, Arnauld.sumber
ngn / apl, 10 byte
?2 4
memilih secara acak sepasang angka - yang pertama di antara 0 1 dan yang kedua di antara 0 1 2 3⌈/
adalah "maks. dikurangi" - temukan nomor yang lebih besar⎕a
adalah huruf besar[ ]
pengindeksancatat bagan untuk maks (a, b) ketika a∊ {0,1} dan b∊ {0,1,2,3}:
jika a dan b dipilih secara acak dan independen, kita dapat mengganti 0123 = ABCD untuk mendapatkan distribusi probabilitas yang diinginkan
sumber
Python 3 ,
64 5551 byte-9 byte terima kasih kepada @ovs
Cobalah online!
Penjelasan
random.choice()
mendapat karakter acak dari String, sementara(s*2)[1:]+s[1]
menciptakanBCDABCDB
untuk inputABCD
, yang memiliki 1/8A
detik, 2/8C
detik, 2/8D
detik dan 3/8B
detik.sumber
random.choice
untuk 55 byte:lambda s:choice((s[0]+s[1:]*3)[:8])
choice()
.QBIC , 27 byte
Penjelasan
sumber
> <>, 56 byte
Cobalah online!
sumber
Chip , 60 byte
Cobalah online!
Ketiganya
?
menghasilkan bit acak. Pada siklus pertama, bit-bit ini dijalankan melalui sakelar di atas (/
's dan\
' s) untuk menentukan nilai yang akan kita hasilkan dari tabel ini:(di mana
_
bisa menjadi0
atau1
). Kami kemudian berjalan di sepanjang input seperlunya, mencetak dan mengakhiri ketika nilai yang benar tercapai.Gumpalan alfabetik besar pada akhirnya disalin secara grosir dari program kucing, solusi ini hanya menekan output dan berakhir untuk mendapatkan efek yang diinginkan.
sumber
Ruby, 32 byte
Cukup mudah ..?
Cobalah online!
sumber
Applesoft,
29oops, 32 byteContoh "retrocomputing" kecil. Bersabarlah dengan saya, saya baru dalam hal ini. Saya berpendapat bahwa apa yang ditunjuk sebagai "input" tidak perlu dihitung sendiri. Sebagaimana dinyatakan dalam OP, input akan diberikan sebagai "ABCD". (Awalnya saya tidak menyadari bahwa saya perlu menentukan input yang diperoleh, yang menambahkan 4 byte, sementara saya memasukkan sisanya ke byte.)
Istilah INPUT, RND, PRINT dan MID $ masing-masing dikodekan secara internal sebagai token byte tunggal.
Pertama, X diberi nilai acak dalam kisaran 0 <X <4. Ini digunakan untuk memilih salah satu karakter dari I $, sesuai dengan (X <.5) + X + 1. Nilai posisi karakter diambil sebagai evaluasi ekspresi terpotong. X <0,5 menambahkan 1 jika X kurang dari 0,5, jika tidak tambahkan 0. Hasil dari X memecah sebagai berikut:
sumber
Common Lisp , 198 byte
Cobalah online!
Dapat dibaca:
sumber