ランダムジェネレーターの変更によるダイス


10

前書き

次の実装でランダムな整数ジェネレータが与えられます

  • 最初の呼び出しは常に1を返します。
  • 2番目の呼び出しは、1と2の間のランダムな整数を返します。
  • 3番目の呼び出しは、1〜3のランダムな整数を返します。
  • n番目の呼び出しは、1以上n以下のランダムな整数を返します。

上記の関数に基づいて、完全にランダムなランダムダイスジェネレーターを記述し、1から6までの値を等しい確率で返します。

ルール

  • プログラム/関数の結果は、1から6までのランダムな整数になり、使用可能な形式で、つまり標準出力に、または関数の戻り値として返されます。
  • 上記の昇順乱数ジェネレーターは、プログラムの「フリー」関数として定義できます(つまり、文字カウントにカウントされません)、または状態(n)が永続的であると想定して、必要に応じて実行される別のスクリプト/プログラムとして定義できます呼び出しの間。
  • プログラムの1つのユースケースで1000を超えるダイスロールが要求されることはないと想定し、最初の乱数ジェネレータ1を1000のダイスロールの最後にリセットして、のオーバーフローを回避することができますn
  • あなたのプログラムが使用することはできません任意の上記で定義された昇順乱数発生器を除いて、乱数の他のソースを。もちろん、単一のサイコロロール出力ごとに、乱数ジェネレータから複数の乱数を要求することもできます。
  • これはコードゴルフなので、同点の場合、勝者は最短の回答またはほとんどの票です。1000未満の生成された乱数を使用して1000のサイコロを生成できる場合、10ポイントの効率ボーナスを自分に与えます。

./asc-rand
1 # random integer between 1 and 1
./asc-rand
1 # random integer between 1 and 2
./asc-rand
3 # random integer between 1 and 3
./asc-rand
4 # random integer between 1 and 4

# dice-gen generates random dice based on output of asc-rand program.
./dice-gen
3
./dice-gen
6
./dice-gen
5
./dice-gen
1

プログラムはiterate(6):b=asc-rand(); print b違法ですか、それとも機能しませんか?3番目のルールを誤解しているかもしれません。
beary605 2012年

@ beary605:乱数ジェネレーターは、すべてのサイコロのロール間ではなく、1000個のサイコロのロールの後でのみリセットできます。私が言及する唯一の理由は、乱数ジェネレーターによって返される値のオーバーフローの可能性に対処することは、この課題の懸念事項の1つではありません編集:私はルールの目的を明確にしました、それが役に立てば幸いです。
mellamokb

「乱数」とは、「ランダムな整数」または「ランダムな(切り捨てられた)実数」という意味ですか?おそらく私が知らない慣習があるかもしれません。
DavidC、

@DavidCarraher:非常に良い点です。私はランダムな整数を意味していましたが、それは明確ではありません。質問を更新します。 編集:更新されました。
mellamokb

1
ランダマイザーに乱数を生成した回数を尋ねることはできますか?できないという印象を受けました。
Matt

回答:


2

J-13文字

これはGolfscriptと同じ仮定をします。サイコロの数は標準入力であり、出てくるサイコロの目録をリストします。

r=:1+?  NB. free random function
r>:i.".1!:1]1

爆発で説明:

r=:1+?           NB. r(x) = 1 + a random number between 0 and n-1
           ]1    NB. input file handle
       1!:1      NB. read in a string
     ".          NB. convert to integer
 >:i.            NB. make a list of numbers, from 1 to that integer
r                NB. apply the random function

それがどういうわけか物足りない場合は、ここに長い21文字のプログラムがあります。これを呼び出してf''乱数を生成し、状態とすべてのものを特徴とすることができます。

r=:1+?  NB. free random function
c=:0
f=:3 :'r c=:1+c'

Kの類似体:無料のランダム関数r:{*1_draw x}、標準入力バージョン(10文字)r'1+!. 0:` 、関数バージョン(14文字)からc:0;f:{r@c+:1}呼び出されf[]ます。
algorithmhark

6

Python、31文字

scleaverと同様に、ジェネレーターを次のように定義します。

from random import randint
n=0
def r():
    global n;n+=1
    return randint(1,n)

次に、サイコロを振る関数:

D=lambda:eval('r(),'*6)[-1]%6+1

D()ランダムにサイコロを振る必要があるときはいつでもコールしてください。


ああ、evalの賢い使い方です。
scleaver

3

Scala 23

def s={r;r;r;r;r;r%6+1}

メソッドrは次のように(おおよそ)実装できます。

var cnt = 0 
val rnd = new util.Random 

def r = {
  cnt %= 1000
  cnt += 1
  rnd.nextInt (cnt)
}

大まかなテスト:

scala> (1 to 6).map (i => ((1 to 600) map (_=>s)).filter (_ == i).size)
res26: scala.collection.immutable.IndexedSeq[Int] = Vector(110, 105, 91, 96, 106, 102)

6回の呼び出しごとに6つの値に等しい分布が生成されるため、5を破棄します。


2

GolfScript(15文字)

これは、必要なロールの数がstdinで提供され、その多くの結果をstdoutにリストすることを前提としています。

# The free increasing random function
0:N;{N):N rand)}:r;

~{r{;r}5*6%)n}*

オンラインデモ

1000未満のロールを使用して1000の数字を生成することで10ポイントのボーナスを得ることができましたが、10文字をはるかに超えるコストがかかりました。Nが2または3の累乗の倍数である場合に適切なエントロピーを抽出する簡単な方法は、mod 3で利用可能な結果の数が333 + 111 + 37 + 12 + 4 + 1 = 498しかないため、十分に不十分です。したがって、次のことを行う必要があります。サンプルと拒否のアプローチをとります。このアプローチを使用するとr、1000の呼び出しから2242の予想されるロールを得ることができますが、簿記による余分なオーバーヘッドがありbase、非常に長い関数名です。


5
「そしてbase非常に長い関数名です」Mathematicaを使用していないようです。私たちは、このような驚異を取得NegativeBinomialDistributionExponentialGeneratingFunctionMathieuCharacteristicExponentInverseFourierSequenceTransform、とSemialgebraicComponentInstances。:-)
Mr.Wizard 2012年

1

Python 65 63

i=7
while i>5:[R()for x in range(9)];i=int(`R()`[-1])
print i+1

関数R()は昇順ランダマイザーです。

使用法:

$ ./rollDice.py
3
$ ./rollDice.py
5

forループを削除して、ループのR前に1回だけ呼び出してみませんwhileか?
キースランドール

@KeithRandallサイコロを振ったときに返す数値は、昇順ジェネレーターが返す数値の最後の桁です。可能なすべての桁で確率が等しくなるように、昇順ジェネレーターを10回呼び出す必要があります。
Matt

なぜ10コールですか?原則として、ジェネレーターがランダムである場合、各呼び出しは(10)桁のいずれかに対して等しい確率を提供すべきではありませんか?もちろん、実際には、各数値の等しい数に近づくことしか期待できません。
DavidC、2012年

@DavidCarraherジェネレータは、1からnまでの乱数を返します。nは、呼び出した回数です。この返された番号の最後の桁を調べています。nが10の整数倍でない場合、確率は均一ではありません。例:n = 13の場合、確率は次のように分類されます。ロール1、5、6の場合は1/9、ロール2、3、4の場合は2/9
Matt

@マット:私はR()浮動小数点数を返すと仮定し、あなたは最下位桁をつかんでいた。R()整数を返すことが明確になったので、理にかなっています。
キースランドール

1

Python、56

rは次のように定義されます。

from random import randint
n=0
def r(z):
    global n;n+=1
    return randint(1,n)

ダイスジェネレータd:

import math;d=lambda:math.ceil(6.*r(r(r(r(r(r(0))))))/n)

使用法、たとえば100ロールの場合:

for i in range(100):print d()

あなたはおそらく削除することができimport mathますが、交換した場合math.ceil(...)int(...)+1
マット・

私はそうしますが、可能な出力として7を生成します。
scleaver

そうそう。私は逃しました。
Matt

mellamokbは、昇順ランダマイザーに関して私が持っていた質問を明確にしました。nを要求することはできません。
Matt

1

Mathematica 51

乱数ジェネレータはr、グローバル変数nを1に設定することによってリセットされます。

n = 1; r[c_] := RandomInteger[{1, c}]

コード

最短のコードで実行されていません...

h := (n++; If[n < 4 \[Or] (y = r@n) > 6 Quotient[n, 6], h, y~Mod~6 + 1])

使用法

t = Table[h, {60000}];
n
SortBy[Tally[t], First]

60000のサイコロを振るには、60031のコールが必要でしたhTallyは、1〜6の番号で分類されています。

60031

{{1、9923}、{2、9966}、{3、10016}、{4、10028}、{5、10009}、{6、10058}}


1

Perl、22または45

昇順乱数ジェネレーターの実装:

my $n=0;
sub r { $n++; return 1+int(rand$n); }

生成:

#copy of the Scala solution; short code; uses 6N rolls
sub s{r;r;r;r;r;1+r%6}
#more efficient implementation, uses approximately 6+N+lnN rolls
sub roll { do{$a=r-1}while($a>$n-$n%6);return 1+(1+$a)%6 }

テストアウト:

n数の二乗
1 10001867 0.348569
2 10004853 2.355161
3 9994395 3.141602
4 10000177 0.003133
5 9999227 0.059753
6 9999481 0.026936
T 60000000 5.935154
60000000ダイスの出目は、rへの60000042コールと570.432735秒かかりました


0

x86オペコード、15バイト

f:  mov cx, 6
    call r ; return in AX
    loop $-3
    cwd
    div word [f+1]
    inc dx
    ret ; return in DX

どうやらこれは低品質の投稿ですか?
ムハンマドサルマン

0

GolfScript、8バイト

f;3f*f(-

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

ジェネレータを1回ポップしてから、結果を取り除きます。次に、f2を転がし、3(3または6)を掛け、次にf3-1(0、1、2)を減算して、(3-2、3-1、3-0)または(6-2、 6-1、6-0)W5。

Golfscriptとランダム関数は、この質問が投稿される前から存在していたため、法的な提出物です。

これは、一度だけ実行される送信です。1回の呼び出しで数回実行する必要がある場合は、

GolfScript、12バイト

f;3f*f-)0:i;

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

これにより、i呼び出しが0にリセットされるため、それに応じてリセットされます。このTIOは50のランダムな結果を示します。


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.