爆発ダイスのシミュレーション


31

あなたの仕事は、整数を取り込んで片面ダイスのn > 1ロールを出力するプログラムを作成することnです。ただし、このサイコロはサイコロを爆発させるためのルールに従います。

サイコロを振るとき、どの値を振ったかを確認してください。その種類のダイの最大値(4になる標準d4、またはd6の6など)を取得した場合、もう一度ロールして、その合計に新しいロールを追加します。各ロールは、最大数をロールしなくなるまで、合計に追加され続けます。ただし、その最終番号はまだ追加されています。

あなたのプログラムは単一の整数を取りn、爆発する側のnダイスを振る必要があります。これがどのように見えるべきかを示すための配布例ですn=4nは常に爆発するため、の倍数は出力しないでください。

再帰のスタックサイズは無限であり、ランダム関数はランダム性の標準(組み込みランダムジェネレーターまたは時刻/日付)を満たしている必要があります。ランダム関数も可能な限り均一である必要があります。これは幾何分布のようなものです。これらは私たちが話しているサイコロだからです。


1
プログラムは完璧でなければなりませんか?その分布は、非常に低い量でオフにすることができますか?
マルティセン

宛先:Riker; RE:上記の@Maltysenのコメント。または非常に高い量?
アルテミスはモニカを

回答:


36

x86マシンコード(Intel Ivy Bridge以降用)、17バイト

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

上記のコードのバイトは、爆発するダイをシミュレートする関数を定義しています。単一の入力を受け取り、ESIレジスタ、ダイの最大数を示します。ECXロールの結果であるレジスタに単一の値を返します。

内部的にはRDRAND命令を使用して乱数を生成します。これは、Intel Ivy Bridgeプロセッサー以降のハードウェアに組み込まれている乱数ジェネレーター(RNG)を使用します(一部のAMD CPUもこの命令をサポートしています)。

それ以外の場合、関数のロジックは非常に簡単です。生成された乱数は、標準的な手法((rand % dieSize) + 1)、その後、爆発を引き起こすかどうかが確認されます。最終結果はアキュムレータレジスタに保持されます。

アセンブリ言語のニーモニックを示す注釈付きバージョンは次のとおりです。

           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

私は少し浮気しています。すべての標準x86呼び出し規約は、関数の結果をEAXレジスタに返します。しかし、真のマシンコードには呼び出し規約はありません。入出力に必要なレジスタを使用できます。ECX出力レジスタに使用すると、1バイト節約できました。を使用する場合はEAXXCHG eax, ecx命令の直前に1バイトの命令を挿入しretます。このスワップの値EAXECXレジスタは、効果的に結果をコピーECXEAXし、中傷ECXの古い値とEAX

オンラインでお試しください!

以下は、GCC、Clang、およびICCでサポートされる組み込み関数を使用__builtin_ia32_rdrand32_stepRDRAND命令を生成する、Cで転写された同等の関数です。

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

興味深いことに、フラグ付きのGCCは-Osこれをほぼ同じマシンコードに変換します。これはのEDI代わりに入力を受け取りますESI。これは完全に任意であり、コードに関する実質的な変更はありません。EAX前に述べたように、結果をに返す必要があり、より効率的な(ただし大きい)MOV命令を使用して、RET。そうでなければ、samezies。プロセスが完全にリバーシブルである場合は常に楽しいです。コードをアセンブリで記述し、Cに転写し、Cコンパイラーで実行し、元のアセンブリを元に戻します。


12

Python 266 64 61バイト

xnorのおかげで-3バイト

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

オンラインでお試しください!

前のロールはに保存されます c、変数に保存せずに複数回アクセスできます。これはPythonラムダでは実行できません。再帰ごとに、爆発するサイコロを振ったかどうかを確認します。

c ゼロに初期化されるため、 c%n、偽です。次の反復では、爆発するサイコロが振られた場合にのみ偽になります。

Python 2、55バイト

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

オンラインでお試しください!

私の別の答えは少し過剰に設計されているようです。


2
破壊条件がランダム性に基づいている再帰関数では、常にゼロ以外のスタックオーバーフローの可能性があります。統計的には取るに足らないチャンスですが、それでも...
mypetlion

3
通常、私の経験では、コードゴルフの課題ではスタックサイズは無限であると想定されています。スタックサイズが無限に増加すると、スタックオーバーフローの可能性はすぐにゼロに収束します。
ArBo

ArBoは、コメントを入力する前に@mypetlionを実行して、ユーザーにpingを送信できるようにします
MilkyWay90

1
c*(c<n)できると思いますc%n
xnor

@xnorもちろん、私はバカです...
ARBO

12

R、39バイト

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

オンラインでお試しください!

説明:このソリューションは、発生する爆発の数の分布を直接計算することにより、再帰/ whileループを回避します。してみましょうnのダイ上の辺の数です。nを転がすと成功を示す場合n、失敗を他の何かの、確率1n成功の n。爆発の総数は、最初の失敗の前の成功の数です。これはaGeometrc11nディストリビューション(ウィキペディアのページをご覧ください。成功と失敗を逆に定義しています)。爆発のたびに合計nがもたらされます。最終的なロールは以下のUniform(1,2,,n1我々は、合計に追加分布。


非常に素晴らしい!ランダムチャレンジ用の組み込みディストリビューションが大好きです!
ジュゼッペ

sample与えられた、ランダム性の基準を満たしてそのバイアス
西安

@ Xi'an それは確かにそうです。それは、離散ランダム変数のための組み込みランダムジェネレータです。
ロビンライダー

私は知っていますが、私が置いたリンクを確認してください:固有の離散化sampleは、最大確率と最小確率の比が1.03になる均一性の欠如につながります...衝撃的ではありませんか?!
西安

はい、衝撃的です。しかし、その後、再び、どのくらいの頻度で使用しないsample?;-)m231
ロビンライダー

9

Perl 6、26バイト

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

オンラインでお試しください!

説明

{                        } # 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
ニース、私自身の解決策は{sum roll(*,1..$_)...$_>*}
ジョー・キング

9

J16 11バイト

(+$:)^:=1+?

オンラインでお試しください!

説明

TL; DR 1+?はサイコロを実行し(+$:)^:=、入力と等しい場合にのみ繰り返します。


関数は4つの動詞の列です:

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

トレインとは、2つ以上の動詞が連結されている場合です。ここで、答えは次の形式f g h jです:

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

いわゆる「4-train」は、フックとフォークとして解析されます。

f g h j   ⇔   f (g h j)

したがって、答えは次と同等です。

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

フック:(f g) xおよびx (f g) y

引数が与えられた場合x、2つの動詞の単項(1引数)フックで、次の等価性が成り立ちます。

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

例えば、(* -) 5評価さへ5 * (- 5)と評価され、_25

これは、4トレイン、fおよびのフックが(g h j)、次と同等であることを意味します。

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

しかし、fここで何をしますか?Power接続詞(+$:)^:=を使用した2つの動詞の接続詞:別のフック()と動詞()。ここで注意です二項 -itは2つの引数を持っている(と)。だから、私たちはどのように振る舞うかを見なければなりません。べき乗接続詞は、動詞と動詞または名詞(名詞は単なるデータの一部)を取り、時間を適用します。例えば、取ります。次の同等性が保持されます。^:(+$:)=fx(g h j) x^:f^:ofof oo = 3

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

場合はo動詞で、電源連動は、単純に評価するo引数を経由し、繰り返し回数として、名詞の結果を使用しています。

私たちの動詞であるois =は、平等動詞です。0異なる引数と1等しい引数に対して評価されます。(+$:)等しい引数に対してフックを1回繰り返し、異なる引数に対してフックを繰り返しません。説明の表記を簡単にするために、をしましょうy ⇔ ((g h j) x)。最初のフックはこれと同等であることを忘れないでください:

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

接続詞を展開すると、これは次のようになります。

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

xyが同じ場合、これは次のようになります。

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

それ以外の場合、これは次のようになります。

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

さて、モナドの分岐点を見てきました。ここに、ダイアディックフォークがあります。

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

したがって、xyが同じ場合、次のようになります。

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

なに$:?動詞全体を指し、再帰を可能にします。これは、いつxy are the same, we apply the verb toy yand add x`かということです。

フォーク: (g h j) x

さて、インナーフォークは何をしますか?これはy最後の例でした。引数が与えられた3つの動詞の単項フォークのx場合、次の等価性が成り立ちます。

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

次の例では、我々は名前の動詞があるとしSUMDIVIDELENGTHあなたは、彼らがかもしれないと仮定し何、。3つをフォークに連結すると、次のようになります。

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

このフォークは、平均で評価されます(数値のリストであるとx仮定x)。Jでは、実際にこれを例として記述し+/ % #ます。

フォークに関する最後の1つです。左端の「タイン」(上記のシンボリックなケースではg)が名詞の場合、その値を返す定数関数として扱われます。

これらすべてが整ったところで、上記の分岐点を理解できます。

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

?[0バツ[1バツ]

すべてを一緒に入れて

これらすべてを考えると、私たちの動詞は次と同等です:

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

これは、目的の機能を表します。


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

@ngnありがとう!組み込まれています。
コナーオブライエン

7

ゼリー、7バイト

X+ß}¥=¡

オンラインでお試しください!

再帰を使用します。再度プログラムを実行ß+)し、(¡)乱数(X)が=プログラム入力に等しい()場合は()を追加します。}作るには、ßプログラムの入力とに作用する¥コンバイン+ß}のための単一のリンクに¡消費します。

ここで、このプログラムを使用し収集したn = 6の1000出力の分布。python / matplotlibでプロット。 histogram

(ほぼ?)指数分布を示す片対数プロット上のn = 3からの5000個のデータポイントがあります。 enter image description here


素敵なプロット!得られる分布は幾何学的分布(私のRの回答を参照)であり、指数分布と密接に関係しています。
ロビンライダー

6

Pyth- 12 11バイト

機能的なwhileを使用します。分布をシミュレートするだけの賢い答えが必要だと思います。

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

オンラインでお試しください


4

Python 3、80バイト

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

オンラインでお試しください!


1
r.random()たまたま0 1-r.random()が返された場合、失敗する可能性がわずかにあります。
nwellnhof

しかし技術的にチャンスが0であること
Quintec

1
import ... as _最短のまれなケース!
xnor

本当に@xnor!唯一の他の時間は、私は私の答えに出て勝つことであることを覚えて、ここで
リン・

4

05AB1E、10 バイト

[ILΩDIÊ#}O

オンラインそれを試してみてくださいまたはリストを確認してください

10バイトの代替:

[LΩDˆÊ#}¯O

オンラインそれを試してみてくださいまたはリストを確認してください

「言葉」を持っているので私は一番上が好きですが DIÊ in it, which suits the challenge.

説明:

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

Was trying to think of a way to use or something.
Magic Octopus Urn


3

R, 47 42 bytes

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

Try it online!

Credit to ArBo's approach.

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


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

I tried a recursive and got a 54 byte solution. Then tried something similar to yours for 44 Try it online!
Aaron Hayman



3

Haskell, 77 76 bytes

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

Try it online!

Thanks to killmous for one byte.

If <|> were in the prelude, we could do better with MonadComprehensions:

Haskell, non-competing, 66 bytes

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

Try it online!


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!

Uses the or short-circuiting idea from ArBo's answer. The expression random()*n//1 generates a number from 0 to n-1, with 0 taking the place of a roll of n. The or takes the that number, except if it's zero (Falsey) it continues on to n+f(n).


It seems your answer was already up when I edited in my shorter one... I didn't see this, but if you want me to delete it because it's quite alike I will.
ArBo


3

Japt, 13 bytes

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

Try it

Port of Arnauld's answer. Figured out how to make a recursive call ;)

Transpiled JS:

// 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
Very nice use of N.g(f) :)
Shaggy

Took a stab at this meself and ended up with 12 bytes but I don't want to post it 'cause I like your solution too much!
Shaggy

Post it as a different answer :)
dana

It may be shorter, but it's a hell of a lot uglier than yours: petershaggynoble.github.io/Japt-Interpreter/…
Shaggy

I see - yeah I was trying to come up with a way not to pollute U. Skipping a line seems to work as well. That's a good trick :)
dana

3

Japt, 12 bytes

It may be shorter than dana's solution, but it's a hell of a lot uglier. I'm only posting it 'cause it seems like forever since we had a Japt solution that started with an empty line.


ö
>°V©VªV+ß

Try it


2

PowerShell, 49 bytes

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

Try it online!

Iterative method. Sets the input $args to $a and the $last roll (done so we enter the loop at least once). Then, so long as the last roll is -equal to the input, we keep rolling. Inside the loop we accumulate into $o the last roll, which is updated by creating a range from 1 to input $a and picking a Random element thereof. (Honestly, I'm a little surprised that $o+=$l= works.) Once we're out of the loop, we leave $o on the pipeline and output is implicit.


2

Forth (gforth), 72 bytes

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

Try it online!

Code Explanation

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

Batch, 70 bytes

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

Takes input n as a command-line parameter %1. d is the current roll, t the cumulative total. Simply keeps rolling until d is not equal to n.


2

Jelly, 9 bytes

x⁹X€Ä%ƇµḢ

Try it online!

A monadic link that takes n as its argument and returns a number generated by an exploding n-sided die. This generates 256 numbers from 1 to n and returns the first cumulative sum that is not a multiple of n. In theory this could return 256n, but even for a 2-sided die this would happen only one every 2256 times.

An alternative that doesn’t have this limitation is:

Jelly, 10 bytes

X³X¤+¥³ḍ¥¿

Try it online!

Note both TIO links generate 400 numbers to show the distribution.


2

Python 3, 81 72 bytes

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

Try it online!

-9 bytes thanks to ArBo

Explanation

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

You can save 1 byte by using from random import* instead.
orthoplex

1
You can get this down to 74 bytes using this recursive solution
Reinstate Monica

1
@squid You can save 1 byte like this.
orthoplex

1
@orthoplex and then you can shorten the if/else, and make it a one-liner. Starts to look like my solution then ;)
ArBo

1
@ArBo Yea that's why I didn't change to recursive, didn't want to just copy you.
Artemis supports Monica

2

TI-BASIC, 28 23 bytes

-5 bytes thanks to this meta post!

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

Input is in Ans.
Output is in Ans and is implicitly printed.

Examples:

4
              4
prgmCDGF11
              5
6
              6
prgmCDGF11
              3

Explanation:

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"

Notes:

  • TI-BASIC is a tokenized language. Character count does not equal byte count.

Since startTmr is no longer necessary, this submission will now work for versions of TI-BASIC earlier than the TI-84+
Tau

2

SmileBASIC 3, 49 bytes

Function D N OUT R implements exploding dice rolls recursively.

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

Ungolfed

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

Note that in SmileBASIC, functions can have multiple return values. If a function has one return value then fun in OUT var and var = fun(in) are exactly the same, which is why we can define the function in OUT form and also call it in an expression in the function body itself. If I had defined the function as DEF D(N) I would have to explicitly state RETURN R in the function body; mixing both syntaxes saved me bytes.



2

Jelly, 7 bytes

X=п⁸S_

A monadic Link accepting an integer, n, which yields an integer.

Try it online! Or see the counts of 105 runs

How?

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

2

SmileBASIC, 41 bytes

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

After reading:

Note that you should never output any multiples of n, since they will always explode.

I realized that rather than checking if a dice roll was n, you can just repeat while the sum is a multiple of n.


2

AnyDice, 36 bytes

Almost a built-in in the language:

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

For this to be correct I have to abuse the infinite recursion depth assumption. AnyDice limits the recursion depth with a global property maximum function depth. the explode builtin however uses it's own; explode depth - which defaults to 2.

set "explode depth" to 99

Would add another 25 bytes; and would not really match the requirements since it's theoretically possible for a dice to explode more than 99 times.

The output of the function is a die, ie. an AnyDice built-in type that is a paring of results and probabilities for the result.


1
I think I'm OK with it not exploding much, the 36 byte one is fine by me. I didn't say no builtins and I'm ok with having them here, since it's not like your 1 or 0 byte answer is winning. But welcome to the site!
Rɪᴋᴇʀ

2

CJam, 19 bytes

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

Explanation:

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

Or in 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

As a flowchart:

Flowchart of code

Try it online!


2

Excel VBA, 46 bytes

Thanks to @TaylorScott

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

Executed in the command window.

As a user-defined function.

Excel VBA, 108 67 bytes

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

You can get this down quite a bit by using a do..loop while loop, and converting the function into an immediate window function. - Do:v=-Int(-[A1]*Rnd):t=t+v:Loop While[A1]=v:?t - 46 Bytes
Taylor Scott

1
@TaylorScott Thanks, I forgot that Do x While y existed in Excel VBA.
william porter
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.