Dadu nontransitif adalah mainan kecil yang bagus yang menentang intuisi kita dalam teori probabilitas. Kami membutuhkan beberapa definisi untuk tantangan ini:
Pertimbangkan dua dadu A dan B yang dilemparkan sekaligus. Kami mengatakan bahwa A mengalahkan B jika probabilitas A menunjukkan jumlah yang lebih besar daripada B benar-benar lebih besar dari probabilitas B yang menunjukkan jumlah yang lebih besar daripada A .
Sekarang mempertimbangkan satu set dari tiga dadu, dengan label A , B , C . Seperangkat dadu semacam itu disebut nontransitif jika
- baik A mengalahkan B , B mengalahkan C dan C mengalahkan A
- atau C mengalahkan B , B mengalahkan A dan A mengalahkan C .
Sebagai salah satu contoh favorit saya, pertimbangkan dadu Grime , yang memiliki sisi berikut:
A: 3 3 3 3 3 6
B: 2 2 2 5 5 5
C: 1 4 4 4 4 4
Menariknya, rata-rata setiap dadu adalah 3,5, sama seperti dadu biasa.
Seseorang dapat menunjukkan bahwa:
- A mengalahkan B dengan probabilitas 7/12.
- B mengalahkan C dengan probabilitas 7/12.
- C mengalahkan A dengan probabilitas 25/36.
Sekarang dadu khusus ini bahkan lebih aneh. Jika kita menggulung masing-masing dadu dua kali dan menjumlahkan hasilnya, urutan ketukan yang dibalik:
- B mengalahkan A dengan probabilitas 85/144.
- C ketukan B dengan probabilitas 85/144.
- Sebuah mengalahkan C dengan probabilitas 671/1296.
Mari kita memanggil satu set dadu dengan properti ini Grime-nontransitive .
Di sisi lain, jika dadu mempertahankan siklus aslinya saat menggunakan dua lemparan, kami menyebutnya sangat tidak transitif . (Jika tidak ada siklus sama sekali untuk dua lemparan, kami cukup menyebutnya tidak transitif .)
Tantangan
Mengingat tiga dadu bersisi enam, menentukan sifat-sifat di atas set ini memiliki, dan output salah satu string berikut: none
, nontransitive
, Grime-nontransitive
, strongly nontransitive
.
Anda dapat menulis program atau fungsi, mengambil input melalui STDIN, argumen baris perintah, prompt atau argumen fungsi, dan menulis hasilnya ke STDOUT atau mengembalikannya sebagai string.
Anda dapat mengasumsikan bahwa semua pihak adalah bilangan bulat non-negatif. Anda tidak dapat mengasumsikan bahwa sisi atau dadu berada dalam urutan tertentu. Anda dapat mengambil input dalam format string atau daftar yang mudah digunakan.
Ini adalah kode golf, jadi jawaban tersingkat (dalam byte) menang.
Uji Kasus
none
1 2 3 4 5 6, 6 5 4 3 2 1, 1 3 5 2 4 6
1 1 1 6 6 6, 4 4 4 5 5 5, 5 5 5 5 5 5
1 1 2 5 6 6, 2 2 3 4 4 6, 2 3 3 4 4 5
0 1 2 3 4 5, 1 1 2 3 3 5, 1 2 2 2 3 5
3 13 5 7 13 7, 5 7 11 5 7 13, 5 9 13 5 7 9
nontransitive
1 2 2 4 6 6, 1 2 3 5 5 5, 2 3 4 4 4 4
1 4 4 4 4 4, 2 2 2 4 5 6, 2 3 3 3 5 5
1 2 1 6 5 6, 3 1 3 6 2 6, 2 4 2 4 4 5
3 4 6 6 7 7, 4 4 4 7 7 7, 5 5 5 5 6 7
2 5 11 11 14 14, 5 5 5 14 14 14, 8 8 8 8 8 17
Grime-nontransitive
3 3 3 3 3 6, 2 2 2 5 5 5, 1 4 4 4 4 4
1 1 4 5 5 5, 2 2 2 3 6 6, 3 3 3 4 4 4
2 1 4 6 4 4, 2 4 5 2 3 5, 3 3 6 3 3 3
11 11 13 15 15 16, 12 12 12 13 16 16, 13 13 13 14 14 14
4 4 7 16 19 19, 4 7 13 13 13 19, 4 10 10 10 16 19
strongly nontransitive
2 2 2 5 5 5, 2 3 3 3 5 5, 1 1 4 5 5 5
2 2 2 3 6 6, 2 2 2 5 5 5, 2 2 4 4 4 5
1 5 1 3 6 5, 6 6 4 2 2 1, 5 3 4 3 4 2
0 0 2 4 4 5, 0 1 1 3 5 5, 1 1 2 3 4 4
1 1 9 17 17 21, 1 5 5 13 21 21, 5 5 13 13 13 17
Jika Anda ingin menguji kode Anda bahkan lebih teliti, Peter Taylor cukup baik untuk menulis implementasi referensi, yang mengklasifikasikan semua ~ 5000 set dadu dengan sisi 1 hingga 6 dan rata-rata 3,5. Tautan pastebin
sumber
1 2 2 4 6 6, 1 2 3 5 5 5, 2 3 4 4 4 4
Saya mendapatkan A <B 17/36, B> C 19/36, C <A 16/36.Jawaban:
Dyalog APL,
107100 byte{({+/×+/¨,¨×⍵∘.-¨1⌽⍵}{3≠|a←⍺⍺⍵:1⋄a=b←⍺⍺∘.+⍨¨⍵:2⋄3+a=-b}⍵)⊃(⊂'none'),'strongly '⍬'Grime-',¨⊂'nontransitive'}
{T←{+/×+/¨∊¨×⍵∘.-¨1⌽⍵}⋄3≠|S←T⍵:'none'⋄N←'nontransitive'⋄S=D←T∘.+⍨¨⍵:'strongly ',N⋄S=-D:'Grime-',N⋄N}
(Terima kasih @Tobia untuk solusi yang lebih sederhana, lebih pendek, dan lebih baik ini)
Dasar-dasar:
←
tugas⋄
pemisah pernyataan{}
bentuk lambda⍺⍵
argumen kiri dan kananA:B
penjaga ("jikaA
kemudian kembaliB
")T
adalah fungsi yang mengembalikan 3 jika A mengalahkan B, B mengalahkan C, dan C mengalahkan A; -3 jika yang terjadi adalah sebaliknya; dan sesuatu peralihan sebaliknya. Secara terperinci:1⌽⍵
adalah satu-rotasi dari⍵
. Jika⍵
ABC, rotasi adalah BCA.∘.-
menghitung tabel pengurangan antara dua vektor (1 2...10 ∘.× 1 2...10
akan menjadi tabel perkalian yang kita tahu dari sekolah). Kami menerapkan ini di antara setiap (¨
) item⍵
dan item terkait di1⌽⍵
.×
signum dari semua angka dalam tabel pengurangan∊¨
ratakan setiap meja+/¨
dan jumlah itu. Kami sekarang memiliki tiga angka yang mewakili saldo: jumlah kemenangan dikurangi kekalahan untuk masing-masing A vs B, B vs C, C vs A.×
signum dari mereka+/
jumlahKemudian menangani kasus-kasus secara bergantian:
3≠|S←T⍵:'none'
jikaT⍵
nilai absolut bukan 3, kembalikan 'tidak ada'N←'nontransitive'
kita akan membutuhkan kata ini banyakS=D←T∘.+⍨¨⍵:'strongly ',N
menghitungT
pasangan dadu (∘.+⍨¨⍵
← →⍵((∘.+)¨)⍵
) dan mengembalikan "sangat ..." jika hubungan yang sama di antara ABC masih berlakuS=-D:'Grime-',N
⍝ "Grime" jika hubungan berada di arah yang berlawananN
jika semuanya gagal, cukup "tidak transitif"sumber
{T←{+/×+/¨∊¨×⍵∘.-¨1⌽⍵}⋄3≠|S←T⍵:'none'⋄N←'nontransitive'⋄S=D←T∘.+⍨¨⍵:'strongly ',N⋄S=-D:'Grime-',N⋄N}
Python 2, 269
Berikut adalah ekspresi kecil yang menyenangkan yang mengevaluasi fungsi. Ia menerima tiga daftar bilangan bulat. Lewati semua kasus uji.
sumber
J -
311257 bytePembaruan (13 Jan 2015):
Penjelasan: Menggunakan Gerunds, sederhanakan
if.
s ke@.
s.Versi yang lebih lama:
Pertama coba di kedua coding di J dan juga golf.
Jalankan menggunakan sintaksis yang mirip dengan berikut (spasi ekstra untuk kejelasan):
Penjelasan:
g
didefinisikan sebagai diad yang mengambil dua larik yang memberitahu jika dadu pertama mengalahkan dadu keduah
didefinisikan sebagai diad yang mengambil dua larik yang memberitahu jika melempar dua kali dan menjumlahkan, apakah dadu pertama mengalahkan keduaf
adalah monad yang mengambil tabel dan mengembalikan string dengan jawaban benarSunting: Perbaiki kesalahan dalam kondisi Grime-nontransitive (ganti
,
dengan*
)sumber
Pyth 129
133Cobalah di sini , atau setidaknya Anda bisa, tetapi secara online
eval
sepertinya tidak suka daftar daftar :( Jika Anda ingin mencobanya di sana, secara manual simpan daftar 3 dadu ke dalam variabel yang tidak digunakan oleh program dan kemudian ganti semua contohQ
dengan variabel itu. Inisialisasi sampel:Ini melewati semua kasus uji Martin, saya belum hati melewati semua kasus Peter: P
Penjelasan (ini akan menjadi doozy)
Cukup sederhana, membuat fungsi
y
yang mengembalikan jumlah dari setiap pasangan nilai Cartesian dalam iterable. Setara dengan:def y(b):return map(lambda d:sum(d),product(b,repeats=2))
. Ini digunakan untuk membuat banyak sisi cetakan yang mensimulasikan melempar mati biasa dua kali.Mendefinisikan fungsi
g
2 argumen yang mengembalikan berapa kali sebuah die mengalahkan yang lain. Setara dengandef g(G,H):return sum(map(lambda k:sum(map(lambda b:b>k,G)),H)
.Mendefinisikan funtion
P
yang menggunakan daftar dua dadu sebagai argumennya. Ini mengembalikan -1 jika die pertama 'kalah', 0 untuk dasi dan 1 jika die pertama 'menang'. Setara dengan:The
AGH
ditunjuk bertindak seperti python 2-tupel tugas. IntinyaG,H=(result)
Akan menjelaskan mundur melalui peta.
m,@Qb@QhbUQ
iterasi lebih dari b = 0..2 dan menghasilkan 2-tupel dadu dengan indeks b dan indeks b +1. Ini memberi kita dadu (A, B), (B, C), (C, A) (pyth secara otomatis mengubah indeks dengan panjang daftar).Selanjutnya,
m,PkP,yhkyek
ulangi hasil dari peta sebelumnya, dengan masing-masing pasangan dadu disimpan dalam k pada setiap lintasan. Pengembaliantuple(P(k),P(tuple(y(k[0]),y(k[-1]))))
untuk setiap nilai. Itu bermuara pada `((A beats B?, 2 * A beats 2 * B), (B beats C?, 2 * B beats ..)).Terakhir,
msdC
jumlahkan nilai-nilai peta sebelumnya setelah zip. Zip menyebabkan semua nilai 'beats' dadu tunggal dalam tupel pertama, dan nilai dadu ganda dalam dadu kedua.Suatu hal yang kotor yang mencetak hasilnya. Jika G adalah 0 atau tidak habis dibagi 3, ini tangkapan bot +/- 3, (
|!G%G3
), cetakannone
, jika tidak mencetak jumlah dari daftar follwing:[not(G+H)*"Grime",(G==H)*"strongly ","nontransitive"]
. Saya pikir boolean cukup jelas tentang definisi dalam pertanyaan. Perhatikan bahwa G tidak boleh nol di sini, seperti yang ditangkap oleh cek sebelumnya.sumber
J (204)
Terlalu lama, mungkin bisa banyak bermain golf dengan memiliki sistem yang lebih efisien untuk memilih string yang tepat.
sumber
Matlab (427)
Ini tidak sesingkat itu dan saya yakin itu bisa bermain golf lebih banyak, saya hanya mencoba untuk menyelesaikan tantangan ini karena saya pikir itu adalah tugas yang sangat menyenangkan, jadi terima kasih @ MartinBüttner untuk membuat tantangan ini!
Berikut kode panjang lengkap dengan beberapa komentar jika Anda ingin mencoba memahami apa yang terjadi. Saya menyertakan beberapa test case kelinci dan tidak memasukkan perintah input:
sumber
input()
dan kemudian menetapkan tiga elemena,b,c
? Juga, gunakan string tepat di spec (none
,nontransitive
, dan dikapitalisasiGrime
) ... mungkin harus bahkan menghemat byte.disp
perintah dalam versi panjang, mereka hanya untuk menguji program, tetapi pesan terakhir disimpan dim
. Dan saya mengoreksiG
.JavaScript - 276 byte
Saya tidak benar-benar baik dalam probabilitas, jadi untuk memastikan hasil saya, saya lebih suka melempar dadu ratusan ribu kali.
Ekspresi mengevaluasi ke suatu fungsi, yang harus dipanggil dengan hanya satu argumen: array tiga array bilangan bulat. Periksa biola untuk dapat menjalankan kode sendiri.
Ini adalah versi yang tidak disunat:
sumber