Mensimulasikan Dadu Meledak

31

Tugas Anda adalah membuat program yang menggunakan bilangan bulat n > 1, dan mengeluarkan gulungan ndadu satu sisi. Namun, dadu ini mengikuti aturan untuk meledak dadu .

Saat Anda menggulung dadu, periksa nilai apa yang Anda gulir. Jika Anda mendapatkan jumlah maksimum untuk jenis die (pada d4 standar yang akan menjadi 4, atau 6 pada d6, dll.), Gulung lagi dan tambahkan gulungan baru ke total itu. Setiap gulungan terus menambahkan ke total, sampai Anda tidak menggulung angka maks lagi. Angka terakhir itu masih ditambahkan.

Program Anda harus mengambil satu bilangan bulat n, dan menggulung ndadu sisi yang meledak . Berikut adalah contoh distribusi untuk menunjukkan seperti apa tampilannya n=4. Perhatikan bahwa Anda seharusnya tidak pernah menghasilkan kelipatan n, karena mereka akan selalu meledak.

Anda dapat mengasumsikan ukuran tumpukan untuk setiap rekursi yang Anda lakukan tidak terbatas, dan fungsi acak Anda harus memenuhi standar kami untuk keacakan (generator acak bawaan atau waktu / tanggal ). Fungsi acak Anda juga harus seseragam mungkin, vs. sesuatu seperti distribusi geometris, karena ini adalah dadu yang sedang kita bicarakan.

Rɪᴋᴇʀ
sumber
1
apakah program harus sempurna? Seperti bisakah distribusinya dimatikan dengan jumlah yang sangat rendah?
Maltysen
Kepada: Riker; RE: @ komentar Maltysen di atas; atau jumlah yang sangat tinggi?
Artemis mendukung Monica
2
@ArtemisFowl Lihat standar kami untuk keacakan. Di sini juga .
Rɪᴋᴇʀ

Jawaban:

36

x86 Machine Code (untuk Intel Ivy Bridge dan yang lebih baru), 17 byte

31 C9 0F C7 F0 31 D2 F7 F6 42 01 D1 39 F2 74 F2 C3

Byte kode di atas mendefinisikan fungsi yang mensimulasikan mati meledak. Dibutuhkan satu input, diteruskan dalam ESIregister, menunjukkan jumlah maksimum die. Ini mengembalikan nilai tunggal diECX register, yang merupakan hasil dari gulungan.

Secara internal, menggunakan para RDRANDinstruksi untuk menghasilkan nomor acak. Ini menggunakan generator angka acak (RNG) yang dibangun ke dalam perangkat keras pada prosesor Intel Ivy Bridge dan yang lebih baru (beberapa CPU AMD juga mendukung instruksi ini).

Logika fungsi ini sebaliknya cukup mudah. Angka acak yang dihasilkan diskalakan agar berada dalam kisaran yang diinginkan menggunakan teknik standar ((rand % dieSize) + 1 ), dan kemudian diperiksa untuk melihat apakah harus menyebabkan ledakan. Hasil akhir disimpan dalam register akumulator.

Berikut adalah versi beranotasi yang menunjukkan mnemonik bahasa assembly:

           unsigned int RollExplodingDie(unsigned int dieSize)
31 C9        xor     ecx, ecx    ; zero-out ECX, which accumulates the final result
           Roll:
0F C7 F0     rdrand  eax         ; generate a random number in EAX
31 D2        xor     edx, edx    ; zero-out EDX (in preparation for unsigned division)
F7 F6        div     esi         ; divide EDX:EAX by ESI (the die size)
                                 ;   EAX receives the quotient; EDX receives the remainder
42           inc     edx         ; increment the remainder
01 D1        add     ecx, edx    ; add this roll result to the accumulator
39 F2        cmp     edx, esi    ; see if this roll result should cause an explosion
74 F2        jz      Roll        ; if so, re-roll; otherwise, fall through
C3           ret                 ; return, with result in ECX register

Saya sedikit curang . Semua konvensi panggilan x86 standar mengembalikan hasil fungsi dalam EAXregister. Tetapi, dalam kode mesin yang sebenarnya, tidak ada konvensi pemanggilan. Anda dapat menggunakan register yang Anda inginkan untuk input / output. Menggunakan ECXuntuk register keluaran menyelamatkan saya 1 byte. Jika Anda ingin menggunakan EAX, masukkan XCHG eax, ecxinstruksi 1-byte segera sebelum retinstruksi. Ini menukar nilai EAXdan ECXregister, secara efektif menyalin hasil dari ECXke EAX, dan merusak ECXdengan nilai lama dari EAX.

Cobalah online!

Berikut fungsi setara ditranskripsikan dalam C, menggunakan yang __builtin_ia32_rdrand32_stepintrinsik didukung oleh GCC, dentang, dan ICC untuk menghasilkan RDRANDinstruksi:

#include <immintrin.h>

unsigned int RollExplodingDie(unsigned int dieSize)
{
    unsigned int result = 0;
Roll:
    unsigned int roll;
    __builtin_ia32_rdrand32_step(&roll);
    roll    = ((roll % dieSize) + 1);
    result += roll;
    if (roll == dieSize)   goto Roll;
    return result;
}

Menariknya, GCC dengan -Osflag mengubah ini menjadi kode mesin yang hampir persis sama . Dibutuhkan input EDIbukannya ESI, yang sepenuhnya sewenang-wenang dan tidak mengubah substansi tentang kode. Ini harus mengembalikan hasilnya EAX, seperti yang saya sebutkan sebelumnya, dan menggunakan MOVinstruksi yang lebih efisien (tetapi lebih besar) untuk melakukan ini segera sebelum RET. Jika tidak, sama. Itu selalu menyenangkan ketika proses sepenuhnya reversibel: tulis kode dalam rakitan, transkrip ke dalam C, jalankan melalui kompiler C, dan dapatkan kembali rakitan asli Anda!

Cody Grey
sumber
12

Python 2 , 66 64 61 byte

-3 byte terima kasih kepada xnor

f=lambda n,c=0:c%n or c+f(n,randint(1,n))
from random import*

Cobalah online!

Gulungan sebelumnya disimpan di c, memungkinkan kita untuk mengaksesnya berkali-kali tanpa harus menyimpannya ke variabel, yang tidak dapat dilakukan dalam Python lambda. Setiap rekursi, kami memeriksa apakah kami melempar dadu yang meledak.

cdiinisialisasi ke nol, begitu c%npula falsey di sana. Dalam iterasi berikutnya, itu hanya akan menjadi falsey jika dadu meledak digulung.

Python 2 , 55 byte

f=lambda n:randint(1,n)%n or n+f(n)
from random import*

Cobalah online!

Jawaban saya yang lain tampaknya agak terlalu direkayasa, karena ini tampaknya bekerja juga ... Saya tetap akan membiarkannya.

ArBo
sumber
2
Fungsi rekursif di mana kondisi putus didasarkan pada keacakan akan selalu memiliki peluang stack overflow yang tidak nol. Peluang yang tidak signifikan secara statistik, tetapi masih ...
mypetlion
3
Biasanya, ukuran tumpukan diasumsikan tak terbatas dalam tantangan kode golf dalam pengalaman saya. Ketika ukuran stack meningkat hingga tak terbatas, kemungkinan stack overflow dengan cepat menyatu menjadi nol.
ArBo
ArBo do @mypetlion sebelum Anda mengetik komentar Anda sehingga Anda dapat melakukan ping pengguna
MilkyWay90
1
Saya pikir c*(c<n)bisa c%n.
xnor
@ xnor Tentu saja, saya idiot ...
ArBo
12

R , 39 byte

n=scan();n*rgeom(1,1-1/n)+sample(n-1,1)

Cobalah online!

Penjelasan: solusi ini menghindari rekursi / loop sementara dengan langsung menghitung distribusi jumlah ledakan yang akan terjadi. Biarkan n menjadi jumlah sisi pada dadu. Jika Anda menunjukkan kesuksesan sebagai bergulir sebuah n dan kegagalan sebagai bergulir hal lain, maka Anda memiliki probabilitas 1n sukses. Jumlah total ledakan adalah jumlah keberhasilan sebelum kegagalan pertama. Ini sesuai denganGeometric(11n)distribusi (lihathalaman wikipedia, yang mendefinisikan keberhasilan dan kegagalan sebaliknya). Setiap ledakan membawanke total. Gulungan terakhir mengikutidistribusiUniform(1,2,,n1)yang kami tambahkan ke total.

Robin Ryder
sumber
sangat bagus! Harus menyukai distribusi bawaan untuk tantangan acak !
Giuseppe
Apakah samplememenuhi standar untuk keacakan, mengingat biasnya ?
Xi'an
@ Xi'an Cukup yakin itu : itu adalah generator acak bawaan untuk variabel acak diskrit.
Robin Ryder
Saya tahu, saya tahu, tetapi periksa tautan yang saya masukkan: diskresi yang melekat pada samplemengarah pada kurangnya keseragaman yang memberikan rasio probabilitas maks ke minimum setinggi 1,03 ... Mengejutkan, bukan ?!
Xi'an
Ya, ini mengejutkan. Tapi sekali lagi, seberapa sering Anda menggunakan sampledengan ? ;-)m231
Robin Ryder
9

Perl 6 , 26 byte

{sum {roll 1..$_:}...*-$_}

Cobalah online!

Penjelasan

{                        } # Anonymous block
                  ...      # Sequence constructor
     {roll 1..$_:}         #   Next elem is random int between 1 and n
                           #   (Called as 0-ary function with the original
                           #   $_ for the 1st elem, then as 1-ary function
                           #   with $_ set to the previous elem which
                           #   equals n.)
                     *-$_  #   Until elem not equal to n (non-zero difference)
 sum                       # Sum all elements
nwellnhof
sumber
2
Bagus, solusi saya sendiri adalah{sum roll(*,1..$_)...$_>*}
Jo King
9

J , 16 11 byte

(+$:)^:=1+?

Cobalah online!

Penjelasan

TL; DR 1+? melakukan die roll, (+$:)^:=hanya mengulangi ketika sama dengan input.


Fungsi ini adalah kereta dari 4 kata kerja:

             ┌─ + 
         ┌───┴─ $:
  ┌─ ^: ─┴─ =     
  │               
──┤      ┌─ 1     
  └──────┼─ +     
         └─ ?     

Kereta adalah ketika 2 atau lebih kata kerja disatukan. Di sini, jawabannya adalah dalam bentuk f g h j:

(+$:)^:=  1  +  ?
    f     g  h  j

Apa yang disebut "kereta 4" diurai sebagai kait dan garpu:

f g h j   ⇔   f (g h j)

Dengan demikian, jawabannya setara dengan:

(+$:)^:= (1 + ?)

Hooks: (f g) xdanx (f g) y

Hook monadic (satu argumen) dari dua kata kerja, diberikan argumen x, persamaan berikut berlaku:

(f g) x   ⇔   x f (g x)

Misalnya, (* -) 5mengevaluasi ke 5 * (- 5), yang mengevaluasi ke _25.

Ini berarti bahwa 4 kereta kami, sebuah kait dari fdan (g h j), setara dengan:

(f (g h j)) x   ⇔   x f ((g h j) x)

Tetapi apa yang fdilakukan di sini? (+$:)^:=adalah konjungsi dari dua kata kerja menggunakan konjungsi Daya^: : hook lain ( (+$:)) dan kata kerja ( =). Perhatikan di sini bahwa fini adalah diadik — ada dua argumen ( xdan (g h j) x). Jadi kita harus melihat bagaimana ^:berperilaku. Konjungsi daya f^:omengambil kata kerja fdan kata kerja atau kata benda o(kata benda hanya sepotong data) dan berlaku f okali. Sebagai contoh, ambil o = 3. Persamaan berikut berlaku:

(f^:3) x     ⇔   f (f (f x))
x (f^:3) y   ⇔   x f (x f (x f y))

Jika oadalah kata kerja, konjungsi daya hanya akan mengevaluasi oargumen dan menggunakan hasil kata benda sebagai hitungan ulang.

Untuk kata kerja kami, oadalah =, kata kerja kesetaraan. Ini mengevaluasi 0untuk argumen yang berbeda dan 1untuk argumen yang sama. Kami mengulangi hook (+$:)sekali untuk argumen yang sama dan tidak ada waktu untuk yang berbeda. Untuk kemudahan notasi penjelasannya, mari y ⇔ ((g h j) x). Ingat bahwa kait awal kami setara dengan ini:

x   (+$:)^:=   ((g h j) x)
x   (+$:)^:=   y

Memperluas konjungsi, ini menjadi:

x ((+$:)^:(x = y)) y

Jika xdan ysama, ini menjadi:

x (+$:)^:1 y   ⇔   x (+$:) y

Kalau tidak, ini menjadi:

x (+$:)^:0 y   ⇔   y

Sekarang, kita telah melihat garpu monadik. Di sini, kami memiliki garpu diad:

x (f g) y   ⇔   x f (g y)

Jadi, kapan xdan ysama, kita mendapatkan:

x (+$:) y   ⇔   x + ($: y)

Apa $:? Ini merujuk ke seluruh kata kerja itu sendiri dan memungkinkan untuk rekursi. Ini berarti bahwa, ketika xdan y are the same, we apply the verb toy and addx` untuk itu.

Garpu: (g h j) x

Sekarang, apa yang dilakukan garpu dalam? Ini adalah ycontoh terakhir kami. Untuk fork monadik dengan tiga kata kerja, diberikan argumen x, persamaan kesetaraan berikut:

(g h j) x   ⇔   (g x) h (j x)

Sebagai contoh berikut ini, misalkan kita telah verba bernama SUM, DIVIDE, dan LENGTH, yang melakukan apa yang Anda kira mereka mungkin. Jika kami menggabungkan ketiganya menjadi garpu, kami mendapatkan:

(SUM DIVIDE LENGTH) x   ⇔   (SUM x) DIVIDE (LENGTH x)

Garpu ini mengevaluasi ke rata-rata x(dengan asumsi xadalah daftar angka). Di J, kami akan menulis ini sebagai contoh +/ % #.

Satu hal lagi tentang garpu. Ketika "tine" paling kiri (dalam kasus simbolis kami di atas, g) adalah kata benda, itu diperlakukan sebagai fungsi konstan mengembalikan nilai itu.

Dengan semua ini, kita sekarang dapat memahami garpu di atas:

(1 + ?) x   ⇔   (1 x) + (? x)
            ⇔   1 + (? x)

? di sini memberikan bilangan bulat acak dalam kisaran [0,x), jadi kita perlu mengubah rentang untuk mewakili dadu; incrementing menghasilkan rentang[1,x].

Menyatukan semuanya

Dengan semua hal ini, kata kerja kami setara dengan:

((+$:)^:=1+?) x   ⇔   ((+$:)^:= 1 + ?) x
                  ⇔   ((+$:)^:= (1 + ?)) x
                  ⇔   x ((+$:)^:=) (1 + ?) x
                  ⇔   x ((+$:)^:=) (1 + (? x))
                  ⇔   x (+$:)^:(x = (1 + (? x))
(let y = 1 + (? x))
if x = y          ⇒   x + $: y
otherwise         ⇒   y

Ini mengekspresikan fungsi yang diinginkan.

Conor O'Brien
sumber
1
(+$:)^:=1+?­­
ngn
@ ngn, terima kasih! Tergabung.
Conor O'Brien
7

Jelly , 7 byte

X+ß}¥=¡

Cobalah online!

Gunakan rekursi. Jalankan lagi program ( ß) dan tambahkan ( +) jika ( ¡) angka acak ( X) sama dengan ( =) ke input program. }membuat ßtindakan pada input program dan ¥bergabung +ß}menjadi satu tautan untuk¡ dikonsumsi.

Di sini distribusi 1000 output untuk n = 6 yang saya kumpulkan menggunakan program ini . Diplot dengan python / matplotlib. histogram

Berikut adalah 5000 titik data dari n = 3 pada plot semilog yang menunjukkan distribusi eksponensial (kurang lebih?). masukkan deskripsi gambar di sini

dylnan
sumber
Plot bagus! Distribusi yang Anda dapatkan adalah distribusi geometris (lihat jawaban R saya ), yang terkait erat dengan distribusi eksponensial.
Robin Ryder
6

Pyth - 12 11 byte

Menggunakan fungsional sementara. Saya merasa harus ada jawaban yang lebih cerdas yang hanya mensimulasikan distribusi.

-.W!%HQ+hOQ

-         (Q)         Subtract Q. This is because we start Z at Q to save a char
 .W                   While, functionally
  !                   Logical not. In this case, it checks for 0
   %HQ                Current val mod input
  +     (Z)           Add to current val
   h                  Plus 1
    OQ                Random val in [0, input)

Cobalah online .

Maltysen
sumber
4

Python 3 , 80 byte

import random as r,math
lambda n:int(-math.log(r.random(),n))*n+r.randint(1,n-1)

Cobalah online!

Lynn
sumber
1
Meskipun demikian, ada sedikit peluang untuk gagal jika r.random()mengembalikan 0. 1-r.random()harus bekerja.
nwellnhof
Meskipun secara teknis kesempatan itu adalah 0
Quintec
1
Kasus langka di mana import ... as _terpendek!
xnor
@ xnor memang! Satu-satunya waktu lain yang saya ingat bahwa menang dalam jawaban saya ada di sini
Lynn
4

05AB1E , 10 byte

[ILΩDIÊ#}O

Cobalah online atau verifikasi daftar .

Alternatif 10 byte:

[LΩDˆÊ#}¯O

Cobalah online atau verifikasi daftar .

Meskipun saya suka yang teratas lagi karena mendapat 'kata' DIÊ di dalamnya, yang sesuai dengan tantangan.

Penjelasan:

[         # Start an infinite loop:
 IL       #  Create a list in the range [1, input]
   Ω      #  Pop and push a random value from this list
    D     #  Duplicate it
     IÊ   #  If it's NOT equal to the input:
       #  #   Stop the infinite loop
}O        # After the loop: sum all values on the stack
          # (which is output implicitly as result)

[         # Start an infinite loop
 L        #  Create a list in the range [1, (implicit) input]
  Ω       #  Pop and push a random value from this list
   Dˆ     #  Add a copy to the global_array
     Ê    #  If it's NOT equal to the (implicit) input:
      #   #   Stop the infinite loop
        # After the loop: push the global_array
  O       # Pop and push its sum
          # (which is output implicitly as result)  
Kevin Cruijssen
sumber
Sedang berusaha memikirkan cara untuk menggunakan atau sesuatu.
Magic Gurita Guci
3

R , 47 42 byte

function(n){while(!F%%n)F=F+sample(n,1)
F}

Cobalah online!

Credit to ArBo's approach.

Still a byte longer than Robin Ryder's, go upvote his!

Giuseppe
sumber
Interesting, I reworked this to a recursive if for 46 bytes, but ended up getting a 52 on one roll which shouldn't be possible with n=4, so I don't know if there's a weird low recursion limit thing happening, but I think it may be buggy. Try it online!
CriminallyVulgar
Saya mencoba rekursif dan mendapat solusi 54 byte. Kemudian cobalah
Aaron Hayman
3

Ruby , 35 byte

->n,s=0{s+=x=1+rand(n);x<n||redo;s}

Cobalah online!

Pasang kembali Monica iamnotmaynard
sumber
Simpan satu byte dengan menjatuhkan xvariabel: Cobalah online!
benj2240
3

Haskell , 77 76 byte

import System.Random
f x=randomRIO(1,x)>>=(x!)
x!y|y<x=pure y|0<1=(y+)<$>f x

Cobalah online!

Terima kasih untuk killmous selama satu byte.

Jika <|>berada di awal, kita bisa melakukan yang lebih baik dengan MonadComprehensions:

Haskell , tidak bersaing, 66 byte

import System.Random
f x=do y<-randomRIO(1,x);[y|y<x]<|>(y+)<$>f x

Cobalah online!

dfeuer
sumber
1
You can save a byte if you define g as an infix function.
killmous
1
@killmous, thanks. At first glance I figured that would be the same or worse, but it's better.
dfeuer
3

Python 2, 53 bytes

f=lambda n:random()*n//1or n+f(n)
from random import*

Try it online!

Menggunakan oride hubungan pendek dari jawaban Arbo . Ekspresi random()*n//1menghasilkan angka dari 0ke n-1, dengan 0menggantikan gulungan n. The ormengambil nomor yang, kecuali jika itu nol (Falsey) terus ke n+f(n).

Tidak
sumber
Sepertinya jawaban Anda sudah naik ketika saya mengedit di yang lebih pendek ... Saya tidak melihat ini, tetapi jika Anda ingin saya menghapusnya karena itu sangat mirip saya akan.
ArBo
3

Japt , 13 byte

ö)g@¶°X?X+ß:X

Cobalah

Jawaban Port of Arnauld . Menemukan cara melakukan panggilan rekursif;)

JS yang dialihkan:

// U: Implicit input
// ö: generate a random number [0,U)
(U.ö())
  // g: run the result through a function
  .g(function(X, Y, Z) {
    // increment the result and compare to input
    return U === (++X)
      // if they are the same, roll again and add to current roll
      ? (X + rp())
      // if they are different, use current roll
      : X
   })
dana
sumber
1
Penggunaan N.g(f):) yang sangat bagus
Shaggy
Mengambil bacokan di meself ini dan berakhir dengan 12 byte tetapi saya tidak ingin mempostingnya karena saya terlalu menyukai solusi Anda!
Shaggy
Posting sebagai jawaban yang berbeda :)
dana
Mungkin lebih pendek, tapi jauh lebih jelek daripada milik Anda: petershaggynoble.github.io/Japt-Interpreter/…
Shaggy
Saya mengerti - ya saya mencoba mencari cara untuk tidak mencemari U. Melompati garis sepertinya juga berhasil. Itu trik yang bagus :)
dana
3

Japt , 12 byte

Ini mungkin lebih pendek daripada solusi dana, tetapi jauh lebih buruk dari itu. Saya hanya mempostingnya karena sepertinya selamanya karena kami memiliki solusi Japt yang dimulai dengan baris kosong.


ö
>°V©VªV+ß

Cobalah

Shaggy
sumber
2

PowerShell , 49 byte

for($a=$l="$args";$a-eq$l){$o+=$l=1..$a|Random}$o

Cobalah online!

Metode berulang. Atur input $argske $adan $lroll ast (selesai maka kita memasuki loop setidaknya sekali). Kemudian, selama gulungan terakhir -equal ke input, kami terus bergulir. Di dalam loop kami terakumulasi ke $odalam gulungan terakhir, yang diperbarui dengan membuat rentang mulai dari 1input $adan memilih Randomelemennya. (Jujur, saya sedikit terkejut itu $o+=$l=bekerja.) Setelah kita keluar dari loop, kita pergi $opada jalur pipa dan output tersirat.

AdmBorkBork
sumber
2

Keempat (gforth) , 72 byte

include random.fs
: f >r 0 begin i random 1+ >r i + r> i < until rdrop ;

Cobalah online!

Penjelasan Kode

include random.fs      \ include library file for random
: f                    \ start a new word definition
  >r                   \ stick the input on the return stack (for easy access)
  0                    \ add a counter to hold the sum
  begin                \ start an indefinite loop
    i random 1+        \ generate a random number from 1 to n
    >r i + r>          \ add the result to the counter, use the return stack to save a few bytes
    i <                \ check if result was less than n
  until                \ end the loop if it was, otherwise go back to begin
  rdrop                \ remove n from the return stack
;                      \ end the word definition
reffu
sumber
2

Batch, 70 byte

@set t=0
:g
@set/at+=d=%random%%%%1+1
@if %d%==%1 goto g
@echo %t%

Mengambil input nsebagai parameter baris perintah %1. dadalah gulungan saat ini, ttotal kumulatif. Cukup terus bergulir sampai dtidak sama dengan n.

Neil
sumber
2

Jelly , 9 byte

x⁹X€Ä%ƇµḢ

Cobalah online!

Tautan monadik yang mengambil n sebagai argumennya dan mengembalikan angka yang dihasilkan oleh d-sisi mati yang meledak. Ini menghasilkan 256 angka dari 1 ke n dan mengembalikan jumlah kumulatif pertama yang bukan kelipatan n. Secara teori ini bisa mengembalikan 256n, tetapi bahkan untuk dadu 2 sisi ini hanya akan terjadi satu setiap2256 waktu.

Alternatif yang tidak memiliki batasan ini adalah:

Jelly , 10 byte

X³X¤+¥³ḍ¥¿

Cobalah online!

Perhatikan bahwa kedua tautan TIO menghasilkan 400 angka untuk menunjukkan distribusi.

Nick Kennedy
sumber
2

Python 3 , 81 72 byte

from random import*
def f(x,a=0):
 while a%x<1:a+=randint(1,x)
 return a

Cobalah online!

-9 byte terima kasih kepada ArBo

Penjelasan

import random             #load the random module              
def explodeDice(num):     #main function
    ans = 0                     #set answer to 0
    while a % num != 0:         #while a isn't a multiple of the input
        ans += random.randint(1, num) #add the next dice roll to answer
    return ans                  #return the answer
Artemis mendukung Monica
sumber
Anda dapat menyimpan 1 byte from random import*sebagai gantinya.
orthoplex
1
Anda bisa mendapatkan ini hingga 74 byte menggunakan solusi rekursif ini
Reinstate Monica
1
@ cumi Anda dapat menyimpan 1 byte seperti ini .
orthoplex
1
@orthoplex lalu Anda dapat mempersingkat if / else, dan menjadikannya one-liner . Mulai terlihat seperti solusi saya kemudian;)
ArBo
1
@ ArBo Ya itu sebabnya saya tidak berubah menjadi rekursif, tidak ingin hanya menyalin Anda.
Artemis mendukung Monica
2

TI-BASIC, 28 23 byte

-5 byte berkat postingan meta ini !

Ans→N:0:Repeat fPart(Ans/N:Ans+randInt(1,N:End:Ans

Input di Ans.
Keluaran dalam Ansdan dicetak secara implisit.

Contoh:

4
              4
prgmCDGF11
              5
6
              6
prgmCDGF11
              3

Penjelasan:

Ans→N:0:Repeat fPart(Ans/N:Ans+randInt(1,N:End:Ans   ;full logic

Ans→N                                                ;store the input in "N"
      0                                              ;leave 0 in "Ans"
        Repeat fPart(Ans/N                 End       ;loop until the sum
                                                     ; is not a multiple of
                                                     ; the input
                               randInt(1,N           ;generate a random
                                                     ; integer in [1,N]
                           Ans+                      ;then add it to "Ans"
                                               Ans   ;leave the sum in "Ans"
                                                     ;implicitly print "Ans"

Catatan:

  • TI-BASIC adalah bahasa tokenized. Jumlah karakter tidak sama dengan jumlah byte.
Tau
sumber
Karena startTmrtidak diperlukan lagi, pengiriman ini sekarang akan berfungsi untuk versi TI-BASIC lebih awal dari TI-84 +
Tau
2

SmileBASIC 3, 49 byte

Fungsi D N OUT Rmengimplementasikan gulungan dadu yang meledak secara rekursif.

DEF D N OUT R
R=RND(N)+1IF R==N THEN R=R+D(N)
END

Tidak disatukan

DEF D N OUT R  'N is sides and R is output param (shorter than using RETURN in this case)
 R=RND(N)+1  'random number in [1, N]
 IF R==N THEN R=R+D(N)  'if roll is same as N then roll again and add
END

Perhatikan bahwa dalam SmileBASIC, fungsi dapat memiliki beberapa nilai balik. Jika suatu fungsi memiliki satu nilai balik maka fun in OUT vardan var = fun(in)persis sama, itulah sebabnya kita dapat mendefinisikan fungsi dalam OUTbentuk dan juga memanggilnya dalam ekspresi di tubuh fungsi itu sendiri. Jika saya telah mendefinisikan fungsi karena DEF D(N)saya harus secara eksplisit menyatakan RETURN Rdalam tubuh fungsi; mencampur kedua sintaks menyelamatkan saya byte.

siput_
sumber
2

Jelly , 7 byte

X=п⁸S_

Tautan monadik yang menerima bilangan bulat n,, yang menghasilkan bilangan bulat.

Cobalah online! Atau lihat hitungan105 berjalan

Bagaimana?

X=п⁸S_ - Link: integer, n
  п    - Collect up while...
 =  ⁸   - ...condition: equal to chain's left argument, n
X       - ...next value: random number in [1..n]
     S  - sum
      _ - subtract n (since the collection starts with [n])
Jonathan Allan
sumber
2

SmileBASIC, 41 byte

INPUT N@L
S=S+RND(N)+1ON S MOD N GOTO@L?S

Setelah membaca:

Perhatikan bahwa Anda seharusnya tidak pernah menghasilkan kelipatan n apa pun, karena n akan selalu meledak.

Saya menyadari bahwa alih-alih memeriksa apakah gulungan dadu itu n, Anda bisa mengulanginya sementara jumlahnya adalah kelipatan n.

12Me21
sumber
2

AnyDice , 36 byte

Hampir built-in dalam bahasa:

function:f I:n{result: [explode dI]}

Agar ini benar, saya harus menyalahgunakan asumsi kedalaman rekursi tak terbatas. AnyDice membatasi kedalaman rekursi dengan kedalaman fungsi maksimum properti global. meledak namun menggunakan itu sendiri; kedalaman ledakan - yang standarnya adalah 2.

set "explode depth" to 99

Akan menambah 25 byte; dan tidak akan benar-benar cocok dengan persyaratan karena secara teori dimungkinkan dadu meledak lebih dari 99 kali.

Output dari fungsi adalah mati, yaitu. tipe bawaan AnyDice yang merupakan pengupas hasil dan probabilitas untuk hasilnya.

Taemyr
sumber
1
Saya pikir saya baik-baik saja dengan itu tidak meledak banyak, yang 36 byte baik-baik saja oleh saya. Saya tidak mengatakan tidak builtin dan saya baik-baik saja dengan memilikinya di sini, karena tidak seperti jawaban 1 atau 0 byte Anda menang. Tapi selamat datang di situs ini!
Rɪᴋᴇʀ
2

CJam , 19 byte

qi{__mr)_T+:T;=}g;T

Penjelasan:

T is pre-set to 0

qi{__mr)_T+:T;=}g;T - whole code
qi                  - read input as integer (n) | Stack: n
  {            }    - block
   __               - Duplicate twice | Stack: n n n
     mr)            - Choose a random number from 1 to n (r). Since 'mr' picks a
                      number from 0 to n-1, the number has to be incremented with ')' 
                      Stack: n n r
        _           - Duplicate |  Stack: n n r r
         T          - push T | Stack: n n r r T
          +         - add the random number to T (t) | Stack: n n r t
           :T;      - pop the value and store in T | Stack: n n r
              =     - are the top two stack values the same (c) | Stack: n c
               }
                g   - do while loop that pops the condition from the stack after each
                      iteration | Stack: n
                 ;  - pop the top stack element and discard | Stack: T
                  T - push T | Stack: T
                    - implicit output

Atau dalam pseudocode:

input n
var sum = 0
do {
    var random_number = pick random number from 1 to n
    sum = sum + random_number
} while (random_number == n)
output n

Sebagai diagram alur:

Flowchart of code

Cobalah online!

lolad
sumber
2

Excel VBA, 46 byte

Terima kasih kepada @TaylorScott

Do:v=-Int(-[A1]*Rnd):t=t+v:Loop While[A1]=v:?t

Dieksekusi di jendela perintah.

Sebagai fungsi yang ditentukan pengguna.

Excel VBA, 108 67 byte

Function z(i)
Do
v=Int((i*Rnd)+1)
z=z+v
Loop While v=i
End Function
william porter
sumber
Anda dapat melakukannya cukup sedikit dengan menggunakan loop do.. loop while, dan mengubah fungsi menjadi fungsi jendela langsung. - Do:v=-Int(-[A1]*Rnd):t=t+v:Loop While[A1]=v:?t- 46 Bytes
Taylor Scott
1
@TaylorScott Terima kasih, saya lupa bahwa Do x While y ada di Excel VBA.
william porter