Mô phỏng xúc xắc nổ


31

Nhiệm vụ của bạn là tạo ra một chương trình lấy một số nguyên n > 1và xuất ra cuộn một nkhuôn mặt đơn . Tuy nhiên, xúc xắc này tuân theo các quy tắc cho nổ xúc xắc .

Khi bạn lăn súc sắc, kiểm tra giá trị bạn lăn. Nếu bạn có mức tối đa cho loại chết đó (trên d4 tiêu chuẩn sẽ là 4 hoặc 6 trên d6, v.v.), hãy cuộn lại và thêm cuộn mới vào tổng số đó. Mỗi cuộn tiếp tục cộng vào tổng số, cho đến khi bạn không cuộn số lượng tối đa nữa. Con số cuối cùng vẫn được thêm vào.

Chương trình của bạn sẽ nhận một số nguyên duy nhất nvà cuộn nchết theo hướng phát nổ . Đây là một bản phân phối ví dụ để hiển thị những gì nó sẽ trông như thế nào n=4. Lưu ý rằng bạn không bao giờ nên xuất bất kỳ bội số nào n, vì chúng sẽ luôn phát nổ.

Bạn có thể giả sử kích thước ngăn xếp cho bất kỳ đệ quy nào bạn thực hiện là vô hạn và hàm ngẫu nhiên của bạn phải đáp ứng các tiêu chuẩn của chúng tôi về tính ngẫu nhiên (trình tạo ngẫu nhiên tích hợp hoặc thời gian / ngày ). Hàm ngẫu nhiên của bạn cũng phải đồng nhất nhất có thể, so với thứ gì đó giống như phân phối hình học, vì đây là những viên xí ngầu mà chúng ta đang nói đến.


1
chương trình có phải là hoàn hảo? Giống như phân phối của nó có thể được giảm bởi một số lượng cực kỳ thấp?
Maltysen

Tới: Riker; RE: @ Maltysen bình luận ở trên; hay số tiền cực cao?
Artemis hỗ trợ Monica

Câu trả lời:


36

Mã máy x86 (cho Intel Ivy Bridge trở lên), 17 byte

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

Các byte mã trên xác định một hàm mô phỏng một khuôn phát nổ. Nó nhận một đầu vào duy nhất, được thông qua trong thanh ESIghi, cho biết số lượng tối đa của khuôn. Nó trả về một giá trị duy nhất trong thanh ECXghi, đó là kết quả của các cuộn.

Bên trong, nó sử dụng các RDRANDhướng dẫn để tạo ra một số ngẫu nhiên. Điều này sử dụng trình tạo số ngẫu nhiên (RNG) được tích hợp vào phần cứng trên bộ xử lý Intel Ivy Bridge và sau đó (một số CPU AMD cũng hỗ trợ hướng dẫn này).

Logic của hàm khá đơn giản. Số ngẫu nhiên được tạo được chia tỷ lệ để nằm trong phạm vi mong muốn bằng cách sử dụng kỹ thuật tiêu chuẩn ( (rand % dieSize) + 1), và sau đó nó được kiểm tra để xem liệu nó có gây ra vụ nổ hay không. Kết quả cuối cùng được giữ trong một thanh ghi tích lũy.

Đây là một phiên bản chú thích hiển thị các ký hiệu ngôn ngữ lắp ráp:

           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

Tôi đang lừa dối một chút . Tất cả các quy ước gọi x86 tiêu chuẩn trả về kết quả của hàm trong thanh EAXghi. Nhưng, trong mã máy thực sự, không có quy ước gọi. Bạn có thể sử dụng bất kỳ thanh ghi nào bạn muốn cho đầu vào / đầu ra. Sử dụng ECXcho thanh ghi đầu ra tiết kiệm cho tôi 1 byte. Nếu bạn muốn sử dụng EAX, chèn lệnh 1 byte XCHG eax, ecxngay trước retlệnh. Điều này hoán đổi các giá trị của EAXvà các ECXthanh ghi, sao chép hiệu quả kết quả từ ECXvào EAXECXbỏ vào giá trị cũ của EAX.

Hãy thử trực tuyến!

Dưới đây là các chức năng tương đương chép trong C, sử dụng các __builtin_ia32_rdrand32_stepnội tại được hỗ trợ bởi GCC, Clang, và ICC để tạo ra các RDRANDhướng dẫn:

#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;
}

Thật thú vị, GCC với -Oscờ biến đổi điều này thành mã máy gần như chính xác . Nó lấy đầu vào EDIthay vì ESI, hoàn toàn tùy ý và không thay đổi gì về nội dung của mã. Nó phải trả về kết quả EAX, như tôi đã đề cập trước đó và nó sử dụng MOVhướng dẫn hiệu quả hơn (nhưng lớn hơn) để thực hiện việc này ngay trước khi RET. Nếu không, cùng. Thật thú vị khi quy trình hoàn toàn có thể đảo ngược: viết mã trong phần lắp ráp, sao chép nó thành C, chạy nó thông qua trình biên dịch C và lấy lại bản gốc của bạn!


12

Python 2 , 66 64 61 byte

-3 byte nhờ xnor

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

Hãy thử trực tuyến!

Cuộn trước được lưu trữ trong đó c, cho phép chúng tôi truy cập nó nhiều lần mà không phải lưu nó vào một biến, điều này không thể thực hiện được trong lambda Python. Mỗi lần đệ quy, chúng tôi kiểm tra xem chúng tôi có tung xúc xắc nổ tung không.

c được khởi tạo bằng không, vì vậy c%n falsey cũng vậy. Trong các lần lặp lại tiếp theo, nó sẽ chỉ là chim ưng nếu xúc xắc nổ tung được tung ra.

Python 2 , 55 byte

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

Hãy thử trực tuyến!

Câu trả lời khác của tôi có vẻ hơi quá, vì điều này dường như cũng hoạt động ... Dù sao tôi cũng sẽ rời bỏ nó.


2
Các hàm đệ quy trong đó điều kiện phá vỡ dựa trên tính ngẫu nhiên sẽ luôn có cơ hội tràn ngăn không. Cơ hội không đáng kể về mặt thống kê, nhưng vẫn ...
mypetlion

3
Thông thường, kích thước ngăn xếp được coi là vô hạn trong các thử thách chơi gôn mã theo kinh nghiệm của tôi. Khi kích thước ngăn xếp tăng lên vô cùng, khả năng tràn ngăn xếp sẽ nhanh chóng hội tụ về không.
ArBo

ArBo do @mypetlion trước khi bạn nhập nhận xét để bạn có thể ping người dùng
MilkyWay90

1
Tôi nghĩ rằng c*(c<n)có thể c%n.
xnor

@xnor Tất nhiên, tôi là một thằng ngốc ...
ArBo

12

R , 39 byte

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

Hãy thử trực tuyến!

Giải thích: giải pháp này tránh được đệ quy / vòng lặp trong khi tính toán trực tiếp sự phân bố số vụ nổ sẽ xảy ra. Gọi n là số cạnh trên khuôn. Nếu bạn biểu thị thành công là lăn n và thất bại như lăn bất cứ thứ gì khác, thì bạn có xác suất 1n thành công. Tổng số vụ nổ là số lần thành công trước thất bại đầu tiên. Điều này tương ứng với mộtGeometrtôic(1-1n)phân phối (xemtrang wikipedia, định nghĩa thành công và thất bại theo cách khác). Mỗi vụ nổ mangnđến tổng số. Các cuộn thức sau mộtBạnntôiform(1,2,Giáo dục,n-1)phân phối mà chúng tôi thêm vào tổng số.


rất đẹp! Phải yêu các bản phân phối dựng sẵn cho các thử thách ngẫu nhiên !
Giuseppe

sampleđáp ứng các tiêu chuẩn cho sự ngẫu nhiên, cho sự thiên vị của nó ?
Tây An

@ Xi'an Khá chắc chắn rằng nó là : nó là trình tạo ngẫu nhiên tích hợp cho các biến ngẫu nhiên rời rạc.
Robin Ryder

Tôi biết, tôi biết, nhưng hãy kiểm tra liên kết tôi đặt: sự rời rạc vốn có sampledẫn đến sự thiếu đồng bộ mang lại tỷ lệ xác suất tối đa đến tối thiểu cao tới 1,03 ... Thật sốc phải không?!
Tây An

Vâng, nó gây sốc. Nhưng sau đó một lần nữa, bao lâu thì bạn sử dụng samplevới ? ;-)m231
Robin Ryder

9

Perl 6 , 26 byte

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

Hãy thử trực tuyến!

Giải trình

{                        } # 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

2
Thật tuyệt, giải pháp của riêng tôi là{sum roll(*,1..$_)...$_>*}
Jo King

9

J , 16 11 byte

(+$:)^:=1+?

Hãy thử trực tuyến!

Giải trình

TL; DR 1+? thực hiện cuộn chết, (+$:)^:=chỉ nhắc lại khi nó bằng đầu vào.


Chức năng là một đoàn tàu gồm 4 động từ:

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

Một chuyến tàu là khi 2 hoặc nhiều động từ được nối với nhau. Ở đây, câu trả lời có dạng f g h j:

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

Cái gọi là "4 tàu" được phân tích cú pháp như một cái móc và một cái nĩa:

f g h j   ⇔   f (g h j)

Do đó, câu trả lời tương đương với:

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

Móc: (f g) xx (f g) y

Một hook đơn âm (một đối số) của hai động từ, được đưa ra một đối số x, tương đương sau đây giữ:

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

Ví dụ, (* -) 5đánh giá 5 * (- 5), mà đánh giá đến _25.

Điều này có nghĩa là 4 tàu của chúng tôi, một cái móc f(g h j), tương đương với:

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

Nhưng flàm gì ở đây? (+$:)^:=là sự kết hợp của hai động từ sử dụng kết hợp Power^: : một hook khác ( (+$:)) và một động từ ( =). Lưu ý ở đây đó fdyadic Đập có hai đối số ( x(g h j) x). Vì vậy, chúng ta phải xem xét cách ^:cư xử. Sự kết hợp sức mạnh f^:ocó một động từ fvà một động từ hoặc một danh từ o(một danh từ chỉ là một phần của dữ liệu) và áp dụng f othời gian. Ví dụ, lấy o = 3. Các tương đương sau giữ:

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

Nếu olà một động từ, tổ hợp sức mạnh sẽ đơn giản đánh giá oqua các đối số và sử dụng kết quả danh từ làm số lần lặp lại.

Đối với động từ của chúng tôi, o=, động từ bình đẳng. Nó đánh giá để 0cho các đối số khác nhau và 1cho các đối số bằng nhau. Chúng tôi lặp lại hook (+$:)một lần cho các đối số bằng nhau và không có lần nào cho các đối số khác nhau. Để dễ dàng ký hiệu cho lời giải thích, hãy để y ⇔ ((g h j) x). Hãy nhớ rằng hook ban đầu của chúng tôi tương đương với điều này:

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

Mở rộng kết hợp, điều này trở thành:

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

Nếu xygiống nhau, điều này trở thành:

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

Mặt khác, điều này trở thành:

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

Bây giờ, chúng ta đã thấy dĩa đơn. Ở đây, chúng tôi có một ngã ba dyadic:

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

Vì vậy, khi xygiống nhau, chúng ta nhận được:

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

$:gì Nó đề cập đến toàn bộ động từ và cho phép đệ quy. Điều này có nghĩa là, khi xvà y are the same, we apply the verb toy and addx` với nó.

Nĩa: (g h j) x

Bây giờ, ngã ba bên trong làm gì? Đây là ytrong ví dụ cuối cùng của chúng tôi. Đối với một ngã ba đơn âm của ba động từ, đưa ra một đối số x, tương đương sau giữ:

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

Ví dụ tiếp theo này, giả sử chúng ta đã động từ đặt tên SUM, DIVIDELENGTH, mà làm những gì bạn cho rằng họ có thể. Nếu chúng ta ghép ba thành một ngã ba, chúng ta sẽ nhận được:

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

Ngã ba này ước tính trung bình x(giả sử xlà một danh sách các số). Trong J, chúng tôi thực sự sẽ viết điều này như ví dụ như +/ % #.

Một điều cuối cùng về dĩa. Khi "tine" ngoài cùng bên trái (trong trường hợp tượng trưng của chúng tôi ở trên g) , là một danh từ, nó được coi là một hàm hằng trả về giá trị đó.

Với tất cả điều này, bây giờ chúng ta có thể hiểu ngã ba ở trên:

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

?[0,x)[1,x]

Để tất cả chúng cùng nhau

Với tất cả những điều này, động từ của chúng tôi tương đương với:

((+$:)^:=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

Điều này thể hiện các chức năng mong muốn.


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

@ngn Cảm ơn! Hợp nhất.
Conor O'Brien

7

Thạch , 7 byte

X+ß}¥=¡

Hãy thử trực tuyến!

Sử dụng đệ quy. Chạy lại chương trình ( ß) và thêm ( +) if ( ¡) số ngẫu nhiên ( X) bằng ( =) với đầu vào chương trình. }thực hiện ßhành động trên đầu vào chương trình và ¥kết hợp +ß}thành một liên kết duy nhất cho¡ để tiêu thụ.

Ở đây phân phối 1000 đầu ra cho n = 6 mà tôi đã thu thập bằng chương trình này . Âm mưu với python / matplotlib. biểu đồ

Dưới đây là 5000 điểm dữ liệu từ n = 3 trên biểu đồ bán kết cho thấy phân bố hàm mũ (xấp xỉ?). nhập mô tả hình ảnh ở đây


Lô đất đẹp! Phân phối bạn nhận được là phân phối hình học (xem câu trả lời R của tôi ), liên quan chặt chẽ đến phân phối theo cấp số nhân.
Robin Ryder

6

Thứ 12 - 12 11 byte

Sử dụng chức năng trong khi. Tôi cảm thấy nên có một câu trả lời thông minh hơn chỉ mô phỏng phân phối.

-.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)

Hãy thử trực tuyến .


4

Python 3 , 80 byte

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

Hãy thử trực tuyến!


1
Tuy nhiên, có một cơ hội thất bại nhỏ nếu r.random()quay trở lại 0. 1-r.random()nên hoạt động.
nwellnhof

Mặc dù về mặt kỹ thuật, cơ hội đó là 0
Quintec

1
Một trường hợp hiếm hoi import ... as _là ngắn nhất!
xnor

@xnor quả thật! Lần khác duy nhất tôi nhớ rằng chiến thắng trong câu trả lời của tôi là ở đây
Lynn

4

05AB1E , 10 byte

[ILΩDIÊ#}O

Hãy thử trực tuyến hoặc xác minh danh sách .

Thay thế 10 byte:

[LΩDˆÊ#}¯O

Dùng thử trực tuyến hoặc xác minh danh sách .

Mặc dù tôi thích cái đầu hơn vì nó có 'từ' DIÊtrong đó, phù hợp với thử thách.

Giải trình:

[         # 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)  

Đã cố gắng nghĩ cách để sử dụng hoặc một cái gì đó.
Bạch tuộc ma thuật Urn


3

R , 47 42 byte

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

Hãy thử trực tuyến!

Tín dụng cho cách tiếp cận của ArBo .

Vẫn là một byte dài hơn Robin Ryder , hãy nâng cấp của anh ấy!


Thật thú vị, tôi đã làm lại điều này thành đệ quy ifcho 46 byte, nhưng cuối cùng lại nhận được 52 điểm trên một cuộn mà không thể thực hiện được với n = 4, vì vậy tôi không biết có điều gì giới hạn đệ quy thấp kỳ lạ xảy ra không, nhưng tôi nghĩ rằng nó có thể có lỗi Hãy thử trực tuyến!
CriminallyVulgar

Tôi đã thử một đệ quy và nhận được một giải pháp 54 byte. Sau đó thử một cái gì đó tương tự như của bạn cho 44 Hãy thử trực tuyến!
Aaron Hayman



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

Hãy thử trực tuyến!

Cảm ơn killmous cho một byte.

Nếu <|>ở trong khúc dạo đầu, chúng ta có thể làm tốt hơn với MonadComprehensions:

Haskell , không cạnh tranh, 66 byte

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

Hãy thử trực tuyến!


1
Bạn có thể lưu một byte nếu bạn xác định g là hàm infix.
sát thủ

1
@killmous, cảm ơn. Thoạt nhìn tôi đã nghĩ rằng nó sẽ giống hoặc tệ hơn, nhưng nó tốt hơn.
dfeuer

3

Python 2 , 53 byte

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

Hãy thử trực tuyến!

Sử dụng orý tưởng ngắn mạch từ câu trả lời của ArBo . Biểu thức random()*n//1tạo ra một số từ 0đến n-1, 0thay thế cho một cuộn n. Con orsố đó, trừ khi nó bằng không (Falsey), nó tiếp tục n+f(n).


Có vẻ như câu trả lời của bạn đã được đưa ra khi tôi chỉnh sửa trong phần ngắn hơn của mình ... Tôi không thấy điều này, nhưng nếu bạn muốn tôi xóa nó vì nó hoàn toàn giống tôi.
ArBo


3

Japt , 13 byte

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

Thử nó

Câu trả lời của cảng Arnauld . Tìm hiểu làm thế nào để thực hiện một cuộc gọi đệ quy;)

Mã hóa dịch mã:

// 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
   })

1
Cách sử dụng rất hay N.g(f):)
Shaggy

Đã đâm một nhát vào chính mình và kết thúc với 12 byte nhưng tôi không muốn đăng nó vì tôi thích giải pháp của bạn quá nhiều!
Shaggy

Gửi nó như một câu trả lời khác :)
dana

Nó có thể ngắn hơn, nhưng nó là một địa ngục xấu hơn rất nhiều so với của bạn: petershaggynoble.github.io/Japt-Interpreter/ Lỗi
Shaggy

Tôi hiểu rồi - vâng tôi đã cố gắng đưa ra một cách để không gây ô nhiễm U. Bỏ qua một dòng dường như cũng làm việc. Đó là một mẹo hay :)
dana

3

Japt , 12 byte

Nó có thể ngắn hơn giải pháp của dana, nhưng đó là một địa ngục xấu xí hơn nhiều. Tôi chỉ đăng nó vì nó dường như là mãi mãi vì chúng tôi đã có một giải pháp Japt bắt đầu bằng một dòng trống.


ö
>°V©VªV+ß

Thử nó


2

PowerShell , 49 byte

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

Hãy thử trực tuyến!

Phương pháp lặp. Bộ đầu vào $argsđể $a$lcuộn ast (làm như vậy chúng ta bước vào vòng ít nhất một lần). Sau đó, miễn là cuộn cuối cùng là -equal cho đầu vào, chúng ta tiếp tục lăn. Trong vòng lặp, chúng tôi tích lũy vào $ocuộn cuối cùng, được cập nhật bằng cách tạo một phạm vi từ 1đầu vào $avà chọn một Randomphần tử của nó. (Thành thật mà nói, tôi hơi ngạc nhiên khi $o+=$l=làm việc.) Một khi chúng tôi ra khỏi vòng lặp, chúng tôi rời khỏi $ođường ống dẫn và đầu ra là ẩn.


2

Forth (gforth) , 72 byte

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

Hãy thử trực tuyến!

Giải thích mã

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

2

Mẻ, 70 byte

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

Lấy đầu vào nlà một tham số dòng lệnh %1. dlà cuộn hiện tại, ttổng tích lũy. Đơn giản chỉ cần tiếp tục lăn cho đến khi dkhông bằng n.


2

Thạch , 9 byte

x⁹X€Ä%ƇµḢ

Hãy thử trực tuyến!

Một liên kết đơn âm lấy n làm đối số của nó và trả về một số được tạo bởi một khuôn mặt n nổ tung. Điều này tạo ra 256 số từ 1 đến n và trả về tổng tích lũy đầu tiên không phải là bội của n. Về lý thuyết, điều này có thể trả về 256n, nhưng ngay cả đối với một cái chết 2 mặt, điều này sẽ chỉ xảy ra một2256 lần

Một thay thế không có giới hạn này là:

Thạch , 10 byte

X³X¤+¥³ḍ¥¿

Hãy thử trực tuyến!

Lưu ý cả hai liên kết TIO tạo 400 số để hiển thị phân phối.


2

Python 3 , 81 72 byte

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

Hãy thử trực tuyến!

-9 byte nhờ ArBo

Giải trình

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

Bạn có thể tiết kiệm 1 byte bằng cách sử dụng from random import*thay thế.
orthoplex

1
Bạn có thể giảm xuống còn 74 byte bằng giải pháp đệ quy này
Phục hồi lại

1
@squid Bạn có thể lưu 1 byte như thế này .
orthoplex

1
@orthoplex và sau đó bạn có thể rút ngắn if / other và biến nó thành một lớp lót . Bắt đầu giống như giải pháp của tôi rồi;)
ArBo

1
@ArBo Yea đó là lý do tại sao tôi không thay đổi đệ quy, không muốn sao chép bạn.
Artemis hỗ trợ Monica

2

TI-BASIC, 28 23 byte

-5 byte nhờ vào bài đăng meta này !

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

Đầu vào là trong Ans.
Đầu ra là trong Ansvà được in ngầm.

Ví dụ:

4
              4
prgmCDGF11
              5
6
              6
prgmCDGF11
              3

Giải trình:

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"

Ghi chú:

  • TI-BASIC là một ngôn ngữ được mã hóa. Số lượng ký tự không bằng số byte.

Do startTmrkhông còn cần thiết, giờ đây, bản đệ trình này sẽ hoạt động cho các phiên bản TI-BASIC sớm hơn TI-84 +
Tau

2

SmileBASIC 3, 49 byte

Chức năng D N OUT R thực hiện nổ tung xúc xắc cuộn đệ quy.

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

Ung dung

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

Lưu ý rằng trong SmileBASIC, các hàm có thể có nhiều giá trị trả về. Nếu một hàm có một giá trị trả về sau đó fun in OUT varvar = fun(in)hoàn toàn giống nhau, đó là lý do tại sao chúng ta có thể định nghĩa hàm OUTdưới dạng và cũng gọi nó trong một biểu thức trong chính thân hàm. Nếu tôi đã định nghĩa hàm như DEF D(N)tôi sẽ phải nói rõ RETURN Rtrong thân hàm; trộn cả hai cú pháp đã lưu tôi byte.




2

SmileBASIC, 41 byte

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

Sau khi đọc:

Lưu ý rằng bạn không bao giờ nên xuất bất kỳ bội số nào của n, vì chúng sẽ luôn phát nổ.

Tôi nhận ra rằng thay vì kiểm tra xem một con xúc xắc có phải không n, bạn chỉ có thể lặp lại trong khi tổng là bội số của n.


2

AnyDice , 36 byte

Hầu như tích hợp sẵn trong ngôn ngữ:

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

Để điều này được chính xác, tôi phải lạm dụng giả định độ sâu đệ quy vô hạn. AnyDice giới hạn độ sâu đệ quy với độ sâu hàm tối đa thuộc tính toàn cầu. phần mềm dựng sẵn tuy nhiên sử dụng riêng của nó; độ sâu phát nổ - mặc định là 2.

set "explode depth" to 99

Sẽ thêm 25 byte nữa; và sẽ không thực sự phù hợp với các yêu cầu vì về mặt lý thuyết, con xúc xắc có thể phát nổ hơn 99 lần.

Đầu ra của hàm là một die, tức là. một loại tích hợp AnyDice là kết quả của các kết quả và xác suất cho kết quả.


1
Tôi nghĩ rằng tôi ổn với nó không phát nổ nhiều, 36 byte là tốt đối với tôi. Tôi đã không nói không có nội dung nào và tôi ổn khi có chúng ở đây, vì nó không giống như câu trả lời 1 hoặc 0 byte của bạn là chiến thắng. Nhưng chào mừng đến với trang web!
Rɪᴋᴇʀ

2

CJam , 19 byte

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

Giải trình:

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

Hoặc trong mã giả:

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

Như một sơ đồ:

Sơ đồ mã

Hãy thử trực tuyến!


2

VBA Excel, 46 byte

Cảm ơn @TaylorScott

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

Thực hiện trong cửa sổ lệnh.

Là một chức năng do người dùng định nghĩa.

VBA Excel, 108 67 byte

Function z(i)
Do
v=Int((i*Rnd)+1)
z=z+v
Loop While v=i
End Function

Bạn có thể giảm điều này xuống một chút bằng cách sử dụng vòng lặp do.. loop whilevà chuyển đổi chức năng thành chức năng cửa sổ ngay lập tức. - Do:v=-Int(-[A1]*Rnd):t=t+v:Loop While[A1]=v:?t- 46 Byte
Taylor Scott

1
@TaylorScott Cảm ơn, tôi đã quên rằng Do x While y tồn tại trong Excel VBA.
porter william
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.