Iterated Dice Rolling


12

Diberikan input di nmana 3 <= n <= 25, lakukan langkah-langkah berikut, dimulai dengan ndie satu sisi (wajah dalam kisaran [1, n], inklusif):

  1. Cetak hasil dari menggulirkan ndadu sisi-sisi saat ini dalam bentuk kdn: X(di mana Xhasilnya dan kjumlah dadu yang dimainkan).
  2. Jika Xlebih besar atau sama dengan n/2jumlah dadu yang dimainkan, tambahkan dadu. Lain, lepaskan dadu.
  3. Jika jumlah dadu yang dimainkan sama dengan 0atau n, berhenti. Lain, lanjutkan ke langkah 1.

Contoh berjalan (perhatikan bahwa output dalam tanda kurung adalah untuk penjelasan dan tidak diperlukan):

6-sisi:

1d6: 4 (avg: 3.0, add)
2d6: 6 (avg: 6.0, add)
3d6: 9 (avg: 9.0, add)
4d6: 16 (avg: 12.0, add)
5d6: 13 (avg: 15.0, remove)
4d6: 9 (avg: 12.0, remove)
3d6: 5 (avg: 9.0, remove)
2d6: 7 (avg: 6.0, add)
3d6: 11 (avg: 9.0, add)
4d6: 14 (avg: 12.0, add)
5d6: 17 (avg: 15.0, add)

9-sisi:

1d9: 7 (avg: 4.5, add)
2d9: 14 (avg: 9.0, add)
3d9: 18 (avg: 13.5, add)
4d9: 18 (avg: 18.0, add)
5d9: 28 (avg: 22.5, add)
6d9: 26 (avg: 27.0, remove)
5d9: 28 (avg: 22.5, add)
6d9: 34 (avg: 27.0, add)
7d9: 33 (avg: 31.5, add)
8d9: 30 (avg: 36.0, remove)
7d9: 29 (avg: 31.5, remove)
6d9: 35 (avg: 27.0, add)
7d9: 32 (avg: 31.5, add)
8d9: 42 (avg: 36.0, add)

Aturan

  • Output harus persis dalam format kdn: X, dengan baris baru memisahkan setiap gulungan
  • Anda harus benar-benar mensimulasikan rolling dadu ganda; cukup mengembalikan bilangan bulat acak dalam rentang [1, n](inklusif) dikalikan dengan jumlah dadu yang saat ini dimainkan tidak diperbolehkan, karena itu tidak secara akurat mensimulasikan pengguliran banyak dadu.
  • Celah standar dilarang
  • Ini adalah , jadi jawaban tersingkat dalam byte menang

Papan peringkat

Cuplikan Stack di bagian bawah posting ini menghasilkan leaderboard dari jawaban a) sebagai daftar solusi terpendek per bahasa dan b) sebagai leaderboard keseluruhan.

Untuk memastikan bahwa jawaban Anda muncul, silakan mulai jawaban Anda dengan tajuk utama, menggunakan templat Penurunan harga berikut:

## Language Name, N bytes

di mana Nukuran 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

Jika Anda ingin memasukkan beberapa angka dalam tajuk Anda (mis. Karena skor Anda adalah jumlah dari dua file atau Anda ingin membuat daftar hukuman penterjemah secara terpisah), pastikan bahwa skor sebenarnya adalah angka terakhir di tajuk:

## Perl, 43 + 2 (-p flag) = 45 bytes

Anda juga dapat membuat nama bahasa menjadi tautan yang kemudian akan muncul di cuplikan:

## [><>](http://esolangs.org/wiki/Fish), 121 bytes


Saya menemukan ini membingungkan. Contoh jawaban, tolong?
Hipe99

Contoh jawaban , karena contohnya singkat.
Hipe99

Hasil edit Anda diklarifikasi. Terima kasih!
Hipe99

16
Apakah Anda yakin tentang aritmatika Anda? D6 konvensional memiliki gulungan rata-rata 3,5.
Peter Taylor

11
Semua rata-rata dalam contoh Anda tampak salah
edc65

Jawaban:



3

Mathematica, 95 89 80 karakter

For[k=1,0<k<#,If[Print[k,d,#,": ",x=Tr[{1,#}~RandomInteger~k]];x<k/2#,k--,k++]]&

Tidak disatukan

For[
  k = 1,
  0 < k < #,
  If[
    Print[k, d, #, ": ", x = Tr[{1, #}~RandomInteger~k]];
    x < k/2 #,
    k--,
    k++
  ]
] &

1
@ MartinBüttner terima kasih atas saran Anda. Echosayangnya tidak dapat mengambil urutan input seperti Printhalnya.
shrx

Oh, bagus.
Martin Ender

3

PHP, 164 121 112 113 109 byte

Versi final, aku janji. Ditingkatkan menggunakan saran Titus:

function d($x,$y){for($i=$y;$i--;)$r+=rand(1,$x);echo$y."d$x: $r\n";$y+=$r/$y>$x/2?:-1;$y<$x&&$y?d($x,$y):0;}

EDIT: Menambahkan byte ekstra untuk pemformatan. Lupa ada IF di sana yang, berkat menjatuhkan teks "add / sub", bisa jadi operator ternary:

function d($x,$y){for($i=$y;$i--;)$r+=rand(1,$x);echo$y."d$x: $r\n";$r/$y>$x/2?$y++:$y--;if($y<$x&&$y)d($x,$y);}

Output sekarang terlihat seperti:

1d6: 5
2d6: 11
3d6: 8
2d6: 11
3d6: 7
2d6: 4
1d6: 5

EDIT: Terima kasih kepada @Manatwork, saya banyak menyelamatkan! Versi baru dan segera:

function d($x,$y){for($i=$y;$i--;)$r+=rand(1,$x);echo$y."d$x=$r\n";if($r/$y>$x/2)$y++;else$y--;if($y<$x&&$y){d($x,$y);}}

Entri sebelumnya:

function d($x,$y){for($i=0;$i<$y;$i++)($r+=rand(1,$x));$s=$y."d$x=$r, ";if($r/$y>$x/2){$y++;$s.="add";}else{$y--;$s.="sub";}echo $s."\n";if($y<$x&&$y>0){d($x,$y);}}`

Rolls terpisah mati, menampilkan ini:

1d6=6, add
2d6=7, add
3d6=11, add
4d6=14, add
5d6=15, sub
4d6=15, add
5d6=18, add

Dan itu disebut demikian: d(6, 1);

Apakah menampilkan Adddan Subakhiran wajib? Ini tidak jelas dari pertanyaan Anda.


Persyaratan mengatakan "perhatikan bahwa output dalam tanda kurung adalah untuk penjelasan dan tidak diperlukan". Cara ini tampaknya lebih pendek:function d($x,$y=1){for($i=$y;$i--;)$r+=rand(1,$x);echo$y."d$x, $r↵";$r/$y>$x/2?$y++:$y--;if($y<$x&&$y)d($x,$y);}
manatwork

@manatwork Terima kasih, Anda benar-benar banyak membantu!
steenbergh

Jika masih bisa menjadi ternary, menghemat satu byte. Dan renovasi kenaikan / penurunan dapat menghemat dua byte:$y-=$r/$y>$x/2?:-1
Titus

2

Python 3, 125

Disimpan 3 byte berkat DSM.

def x(d):
 import random;c=1
 while 0<c<d:r=sum(map(random.randint,[1]*c,[d]*c));print('%id%i: %i'%(c,d,r));c+=2*(r>=d*c/2)-1

Cukup sederhana, melempar banyak dadu dan memeriksa rata-rata. Belum ada yang terlalu mewah di sini.
Perlu dipanggil dengan int. Jadi, x(6)akan menghasilkan sesuatu seperti ini:

1d6: 5
2d6: 10
3d6: 8
2d6: 7
3d6: 11
4d6: 8
3d6: 13
4d6: 19
5d6: 13
4d6: 15
5d6: 22

.


2

JavaScript (ES6), 97 102 106 112 byte

Terima kasih @ user81655 dan @Jupotter karena telah menyelamatkan saya beberapa byte.

f=n=>{for(k=1;k%n;console.log(k+`d${n}: `+x),k+=x<k*n/2?-1:1)for(x=i=k;i--;)x+=Math.random()*n|0}

// 102 bytes:
f=n=>{for(k=1;k%n;console.log(k+`d${n}: `+x),k+=x<k*n/2?-1:1)for(x=i=0;++i<=k;)x+=1+Math.random()*n|0}

// Previous attempt, 112 bytes
f=n=>{k=1;while(k&&k!=n){for(x=i=0;i++<=k;)x+=1+~~(Math.random()*n);console.log(k+`d${n}: `+x);k+=x<k*n/2?-1:1}}

Demo

Ini hanya berfungsi di browser yang sesuai dengan ES6 (saat ini termasuk Firefox dan Edge, mungkin dengan Chrome dan Opera dengan fitur JavaScript eksperimental diaktifkan):

f=n=>{for(k=1;k%n;console.log(k+`d${n}: `+x),k+=x<k*n/2?-1:1)for(x=i=k;i--;)x+=Math.random()*n|0}

// Snippet stuff
console.log = x => {
  document.getElementById('O').innerHTML += x + `<br>`;
}

document.getElementById('F').addEventListener('submit', e => {
  document.getElementById('O').innerHTML = ``
  f(document.getElementById('I').valueAsNumber)
})
<form id=F action=# method=get>
  <label>
    Number of faces: 
    <input type=number min=3 max=25 value=9 required id=I>
  </label>
  <button>Play</button>
  
  <div>
    <output id=O></output>
  </div>
</form>


Anda bisa mengubah whileke forloop, bulat dengan |0alih - alih ~~()dan memindahkan beberapa pernyataan sehingga Anda dapat menghapus tanda kurung untuk menyimpan beberapa byte. Anda juga diizinkan menjadikannya fungsi anonim (tidak f=). 103 byte:n=>{for(k=1;k&&k!=n;k+=x<k*n/2?-1:1)for(x=i=0;i++<=k;console.log(k+`d${n}: `+x))x+=1+Math.random()*n|0}
user81655

@ user81655 Terima kasih. Untuk beberapa alasan, versi Anda menciptakan banyak output luar, jadi saya memindahkannya console.logke forloop lain (harganya 1 char lebih mahal dari milik Anda). Masih turun ke 106
rink.attendant.6

Saya hanya menulis ini tanpa mengujinya, jadi saya senang sebagian besar berhasil. :)
user81655

Anda dapat memperoleh satu karakter dengan mengganti k&&k!=nkondisi dengan perbandingank%n!=0
Jupotter

@Jupotter Terima kasih, k%nbekerja lebih baik;)
rink.attendant.6

1

CJam, 45 byte

ri:M;{X__{Mmr+}*[X'dM':S5$N]o_+XM*<_+(-:XM%}g

Cobalah online.

Menerapkan spesifikasi secara harfiah (termasuk rumus "mean roll" yang salah secara matematis). Seperti yang diharapkan, porting program GolfScript asli di bawah ini ke CJam menyimpan banyak byte karena nama perintah built-in yang lebih pendek ( mr, odan gbukannya rand, putsdan do).

GolfScript, 51 byte

~:&;{1..{&rand+}*[1"d"&": "4$]puts.+1&*<.+(-:1&%}do

Inilah entri GolfScript asli saya. Trik golf terkenal termasuk menggunakan nomor 1sebagai variabel pra-diinisialisasi nyaman untuk menyimpan jumlah dadu saat ini untuk digulung. (Versi CJam sebagai gantinya menggunakan X, yang diinisialisasi CJam ke nilai 1.)


Ps. Melihat judulnya, saya awalnya ingin menjawab ini di AnyDice . Tapi ternyata itu menjadi pilihan yang mengerikan untuk tantangan ini, dan saya tidak berpikir itu secara teknis mungkin untuk menggunakannya untuk mengimplementasikan spesifikasi ini seperti yang diberikan.

Masalahnya adalah bahwa AnyDice adalah bahasa khusus domain untuk menulis program deterministik untuk menghitung statistik dadu bergulir. Sementara memeriksa hasil yang mungkin dari gulungan dan melakukan gulungan bersyarat berdasarkan pada mereka adalah mungkin melalui rekursi, tidak ada cara untuk menghasilkan setiap keacakan yang sebenarnya. Jadi, sementara Anda bisa mensimulasikan urutan gulungan dadu di AnyDice, yang bisa Anda dapatkan sebagai output adalah statistik pada hal-hal seperti, katakanlah, jumlah gulungan hingga proses berakhir, atau distribusi hasil pada langkah tertentu.

Semua yang dikatakan, inilah yang paling dekat yang bisa saya dapatkan di AnyDice :

N: 6
K: 1
function: clip X:n { result: X * (X < N) }
function: adjust X:n { result: [clip X + ((XdN)*2 >= X*N)*2-1] * (X > 0) }
loop I over {1..20} {
  output K named "dice in roll [I]"
  output KdN named "outcome of roll [I]"
  K: [adjust K]
}

Ini bukan kode golf khusus, karena sepertinya latihan sia-sia. Trik golf standar bahasa penjepit, seperti memperpendek nama fungsi dan menghilangkan ruang kosong yang tidak perlu, harus menghabiskan sebagian besar potensi golf.

Trik kunci yang digunakan di sini adalah bahwa, ketika Anda memanggil fungsi yang mengharapkan angka (seperti yang ditunjukkan oleh :ndefinisi fungsi) di AnyDice, dan memberikannya die (mis. Distribusi probabilitas), AnyDice secara otomatis mengevaluasi fungsi tersebut untuk semua kemungkinan nilai mati, dan menggabungkan hasilnya menjadi mati baru.

Berikut screenshot dari output (dalam format grafik batang) untuk tiga gulungan pertama:

Tangkapan layar AnyDice

(Perhatikan bahwa "0" kolom di setiap grafik menunjukkan probabilitas bahwa iterasi berhenti, karena jumlah dadu memukul baik 0 atau N, sebelum roll saat ini. Hal ini terjadi menjadi cara yang nyaman untuk mewakili kondisi berhenti, karena tentu saja bergulir 0dN selalu menghasilkan 0.)


1

R, 103 Bytes

Implementasi yang cukup lurus ke depan. Gulungan dadu dilakukan oleh sum(sample(n,i)).

i=1;n=scan();while(i&i<=n){cat(i,'d',n,': ',s<-sum(sample(n,i)),'\n',sep='');i=ifelse(s<i*n/2,i-1,i+1)}

Uji coba

> i=1;n=scan();while(i&i<=n){cat(i,'d',n,': ',s<-sum(sample(n,i)),'\n',sep='');i=ifelse(s<i*n/2,i-1,i+1)}
1: 9
2: 
Read 1 item
1d9: 9
2d9: 14
3d9: 10
2d9: 14
3d9: 9
2d9: 9
3d9: 12
2d9: 7
1d9: 9
2d9: 11
3d9: 17
4d9: 18
5d9: 25
6d9: 29
7d9: 33
8d9: 43
9d9: 45
> 

1

CoffeeScript, 106 99 byte

f=(n,k=1)->(x=k;x+=Math.random()*n|0for[k..0];console.log k+"d#{n}: "+x;k+=x<k*n/2&&-1||1)while k%n

# Previous attempt, 106 bytes
f=(n,k=1)->(x=i=0;x+=1+Math.random()*n//1while++i<=k;console.log k+"d#{n}: "+x;k+=x<k*n/2&&-1||1)while k%n

Tidak disatukan

f = (n, k = 1) ->
 (x = k
 x += 1 + Math.random() * n | 0 for [k..0]
 console.log k + "d#{n}: " + x
 k += x < k * n / 2 && -1 || 1
 ) while k % n

1

Julia, 77 byte

n->(N=1;while 0<N<n k=sum(rand(1:n,N));print(N,"d$n: $k
");N+=1-2(2k<N*n)end)

Sebagian besar harus jelas - baris baru yang sebenarnya sedang digunakan dalam printstring daripada menggunakan printlnuntuk menyimpan byte. rand(1:n,N)menghasilkan Nbilangan bulat acak antara 1 dan n.


1

Ruby, 93 90 82 karakter

->n{d=s=2
puts"#{d}d#{n}: #{s=eval'+rand(n)+1'*d}"while(d+=s<d*n/2.0?-1:1)>0&&d<n}

Contoh dijalankan:

2.1.5 :001 > -->n{d=s=2;puts"#{d}d#{n}: #{s=eval'+rand(n)+1'*d}"while(d+=s<d*n/2.0?-1:1)>0&&d<n}[6]
1d6: 5
2d6: 10
3d6: 6
2d6: 5
1d6: 5
2d6: 8
3d6: 15
4d6: 18
5d6: 22

0

QBIC , 83 byte (tidak bersaing)

:c=a{e=0[1,q|e=e+_rq,a|]?!q$+@d|!+a$+@:|+!e$~e<c/2|q=q-1\q=q+1]c=q*a~q=a|_X]~q=0|_X

Penjelasan:

q                    Tracks the number of dice (is implicitly 1 at the start)
:                    Takes input from a CMD line parameter
[1,q|e=e+_rq,a|]     Rolls the dice separately
?!q$+@d|!+a$+@:|+!e$ Prints the roll result (requires an unfortunate amount of casting...)
~e<c/2|q=q-1\q=q+1]  Checks whether to increase or decrease
~q=a|_X]~q=0|_X      Tests the amount of dice and quits on either boundary.

0

PHP, 104 byte

for($n=$argv[$k=1];$k&&$k<$n;print$k."d$n: $x\n",$k-=$x<$n*$k/2?:-1)for($x=$i=0;$i++<$k;)$x+=rand(1,$n);

Jalankan dengan php -r '<code>' <N>

kerusakan

for($n=$argv[$k=1];     // import input, init number of dice
    $k&&$k<$n;          // while 0<$k<$n
    print$k."d$n: $x\n",    // 2. print results
    $k-=$x<$n*$k/2?:-1      // 3. remove or add a die
)
    for($x=$i=0;$i++<$k;)   // 1. roll dice separately
        $x+=rand(1,$n);         // sum up results
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.