一定の乱数のソースを使用して、0〜nの間の乱数を選択します


26

仕事

正の整数で考えるとn以下の2^30コードは、あなたが選択した任意の方法で入力として必要があり、指定された出力ランダムの間の整数0n、包括的に。生成する数値は、ランダムに均一に選択する必要があります。つまり、0toの各値はn等しい確率で発生する必要があります(「規則と警告」を参照)。

ルールと警告

あなたのコードは、あなたの言語または標準ライブラリに組み込まれた、一様にランダムであると主張する任意の乱数ジェネレータが実際に一様であると仮定できます。つまり、使用しているランダムソースの品質を心配する必要はありません。しかしながら、

  • 使用しているランダムソースが均一である場合、コードはから0まで均一なランダム整数を正しく出力することを確立する必要がありますn
  • 組み込みまたはライブラリのランダム関数を呼び出すときの引数は定数でなければなりません。つまり、入力値から完全に独立している必要があります。
  • コードは、終了が保証されているのではなく、確率1で終了する場合があります。

ノート

  • randInt(0,n) 組み込み関数またはライブラリ関数への引数として入力を受け取るため、無効です。
  • rand()%nではない一般的には一様乱数を与えます。betsegによって与えられた例として、場合intmax == 15n = 10、あなたが取得する多くの可能性が高くなります0-5より6-10
  • floor(randomfloat()*(n+1)) また、0と1の間の異なる浮動小数点値の有限数により、一般に均一な乱数を与えません。

出力が一様にランダムであることをどのように確認しますか?与えられた言語/ライブラリは一様に乱数を出力するかもしれませんが、操作は不均一な出力をもたらす可能性があります。(例えばrng()0- 100、if n = 75、およびfunctionが提供される場合、rng()%750-25がより一般的です...)
Baldrickk

1
@Baldrickk群衆の知恵によって:)私たちはコードを読んでそれについて考えることができるだけです。

最も単純な確率論的質問をするという悲しい結論:ランダム性と確率は非常によく理解されていません。:((そしてルールを読むのは難しいようです。)
マーティン・エンダー

これが思い浮かぶ:乱数
-BgrWorker

短い回答が3つあるのに、なぜx86の回答を受け入れたのですか?
デニス

回答:


25

rdrand命令付きx86マシン、10バイト

BITS 64

_try_again:

 rdrand eax
jnc _try_again

 cmp eax, edi
ja _try_again

 ret

マシンコード

0FC7F0 73FB 39F8 77F7 C3

入力はレジスタにrdiあり、出力はにありraxます。
これはSYS V AMD64 ABIを尊重するため、コードはC関数を効果的に実装します。

unsigned int foo(unsigned int max); 

32ビット整数で。

命令rdrandはIntelによって記述されています

RDRAND暗号的に安全な決定論的なランダムビットジェネレーターDRBGによって提供される乱数を返します。DRBGは、NIST SP 800-90A標準を満たすように設計されています。

CSRNGを扱う場合、NIST SP 800-90Aを引用して、とにかく分布が均一であることは暗黙的です。

乱数は、不偏ランダム変数のインスタンス、つまり、均一に分散されたランダムプロセスによって生成される出力です。


プロシージャは乱数を生成し、入力よりも厳密に大きくない場合は返されます。
それ以外の場合、プロセスは繰り返されます。

のでeax、32ビットであり、rdrand0と2の間の数を返す32 -1、そうすべてのためのN [0、2 32 -1]予想反復の数が2である32全てに対して定義され/(N + 1)n個 in [0、2 30)。


驚くほど低レベル。ありがとうございました。

何のjncためですか?
l4m2

@ l4m2 rdrandは、CF返されたデータが有効な場合にiifを設定します。エントロピープールを使い果たした要求が多すぎるため、データが無効である可能性があります。rdrandおよびthisのマニュアルエントリを参照してください。
マーガレットブルーム

20

ゼリー7 6バイト

⁴!!X%‘

1バイトのゴルフをしてくれた@JonathanAllanに感謝します!

(16!)のため、TIOで実行できませんある膨大な数。

使い方

⁴!!X%‘  Main link. Argument: n

⁴       Set the return value to 16.
 !!     Compute (16!)!.
   X    Pseudo-randomly choose an integer between 1 and (16!)!.
        Since (16!)! is evenly divisible by any k ≤ 2**30, it is evenly divisible
        by n+1.
    %‘  Take the result modulo n+1.

これは、削除された回答の修正版で、同じ考えです。不要なべき乗はありましたが。
orlp

申し訳ありませんが、投稿する前に見ていません。
デニス

どうでもいい、とにかく修正するつもりはなかった。私はJellyを実際にいじるにはあまりにも不快です。
orlp

1
「なぜあなたが怒っているのか分かりません。アルゴリズムは一定の時間です。それは良いことですよね。なぜセキュリティとHRはドアの外にあるのですか?」
corsiKa

1
同意した。8桁の数字と417桁の数字の違いのビット:p
ジョナサンアラン

11

Mathematica、29バイト

デニスのゼリーの回答に基づいています

RandomInteger[2*^9!-1]~Mod~#&

これを実際に実行することはお勧めしません。2e9!かなり大きな数字です...

すべての可能な入力で割り切れる巨大な数を生成し、単純なモジュロで結果を必要な範囲にマップすることが最短であることが判明しました。

拒否サンプリング、34バイト

やや興味深いコードにつながった私の古いアプローチ:

13!//.x_/;x>#:>RandomInteger[13!]&

基本的な拒否サンプリング。出力を13に初期化します(最大入力2 30よりも大きい)、それを繰り返し0から13の間のランダムな整数に置き換えます!値が入力よりも大きい限り。


1
「入力以下」という意味ですか?

1
@Lembikいいえ。値が目的の範囲に収まらない限り、値を再生成します。
マーティンエンダー

ああなるほど。何らかの理由で、希望の範囲から繰り返しサンプリングしていると思いました。ありがとう。

1
次回に制限時間を追加するように

9

Brachylog、9バイト

≥.∧13ḟṙ|↰

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

これは13!、Martin Enderの答えのように使用します(13ḟ1バイト未満です2^₃₀)。

を使用して実装されrandom_between/3ます。ソースを掘るときに、random_float/0リンク先random/1のMersenne Twisterアルゴリズムを使用します。

説明

≥.           Input ≥ Output
  ∧          And
   13ḟṙ      Output = rand(0, 13!)
       |     Else
        ↰    Call recursively with the same input

7

プロローグ(SWI)、38バイト

X*Y:-Z is 2^31,random(0,Z,Y),Y=<X;X*Y.

拒否サンプリングで動作します。

間の乱数発生02 ^ 31-1 = 2147483647をより1つ少ないまで又は発見された入力に等しいです。

私は他の代わりにカットを使用できるように感じますが、どのように見ることができません。


1
を使用してelseを回避することもできますが、最終的にrepeatは3バイト長くなります。無限の選択ポイントを繰り返すより短い方法があるかどうかはわかりません。
14:17に致命的

@ファタライズ:うん、私も繰り返してみた。,!.バックトラックを強制するようなものを使用した記憶がありましたが、間違っていることを覚えているか、このソリューションには適用できません。
エミグナ

7

ラビリンス、63バイト

 ?
 #00}__""*_
 ;    #"  _
{-{=  } "><)
!{ : ;"({ +
@  }}:  >`#

(ここでの重いゴルフの手助けをしてくれた@MartinEnderに感謝します。)

ラビリンスは2D言語であり、ランダム性の唯一の原因は次のような状況です。

   x
  "<)
 " "
 " "

命令ポインタが上にありx、下に向かっていると仮定します。次にに到達し<ます。スタックの最上部が0の場合(上記の実際のプログラムでは常にそうです)、現在の行を1だけ左にシフトします。

   "
 "<)
 " "
 " "

指示ポインターは現在、<下方向に移動しています。ジャンクションで、ラビリンスはスタックの最上部に基づいて回転します。負は左に、正は右に、ゼロは前方に移動します。スタックの最上部がこの時点でまだゼロの場合、パスがないため前方または後方に移動できません。そのため、ラビリンスは左に曲がるか右に曲がるかを同じ確率でランダム化します。

基本的に、上記のプログラムが行うことは、ランダム性機能を使用して100ビットの数値(#00ここで100を指定)を生成し、数値を生成するまでループを続け<= nます。

テストでは、#0"代わりに10ビットの数値を代わりに使用し"て、no-opパスを使用すると役立ちます。オンラインでお試しください!

大まかな説明:

 ?            <--- ? is input and starting point
 #0"}__""*_   <--- * here: first run is *0, after that is *2 to double
 ;    #"  _
{-{=  } "><)  <--- Randomness section, +0 or +1 depending on path.
!{ : ;"({ +        After <, the >s reset the row for the next inner loop.
@  }}:  >`#

 ^    ^
 |    |
 |    The " junction in this column checks whether the
 |    100-bit number has been generated, and if not then
 |    continue by turning right into }.
 |
 Minus sign junction here checks whether the generated number <= n.
 If so, head into the output area (! is output as num, @ is terminate).
 Otherwise, head up and do the outer loop all over again.

7

Python、61バイト

from random import*
lambda n,x=2.**30:int(randrange(x)*-~n/x)

編集:禁止されたフォームを避けるために更新

Edit2:2バイト保存、ありがとう@ JonathanAllan

Edit3:完全に機能するソリューションのために2バイトを支払った-再び@JonathanAllanに感謝

Edit4:削除f=、2バイト節約

Edit5:@ JonathanAllanのおかげでさらに1バイト節約

Edit6:@ JonathanAllanのおかげでさらに2バイト節約

今では、git責任が私に悪いことを、JonathanAllanが助けになることを指摘します。

Edit7:雨が降ると、それは注ぐ-もう2バイト

Edit8:さらに2バイト


1
これは決して出力しnませんがfrom random import*r.
ジョナサンアラン

1
はい、あなたはそれ以外の場合は、必要な括弧を避けるため、そうするために「オタマジャクシ演算子」を使用することができる...*(-~n*1.0/2**30))のではなく...*((n+1)*1.0/2**30))
ジョナサン・アラン

1
本当に?甘い!70番に対する長年のgrみはありますか?たくさんのご協力いただきありがとうございます
iwaseatenbyagrue

1
実際randrange、フロートを受け入れるように見えるので、lambda n,x=2.**30:int(randrange(x)*-~n/x)さらに2つ[編集...] 4つ保存します!
ジョナサンアラン

1
^括弧を削除した別の2つ。掛け算が進むべき道だったことを示すだけです!
ジョナサンアラン

6

Python 2、61バイト

from random import*
lambda n:map(randrange,range(1,2**31))[n]

擬似乱数の整数を選択する0及びKのすべての値に対してKの間の02 31 - 2、その後に対応する整数かかりkは= N


5

バッチ、64バイト

@set/ar=%random%*32768+%random%
@if %r% gtr %1 %0 %1
@echo %r%

%random%15ビットのランダム性しか与えられないため、2つの乱数を結合する必要があります。ランダムな値が目的の範囲内に収まるまでループしnます。低速になると遅くなります。高速バージョンの場合は98バイト:

@set/a"n=%1+1,m=~(3<<30)/n*n,r=%random%*32768+%random%
@if %r% geq %m% %0 %1
@cmd/cset/a%r%%%%n%

コードは遅いかもしれませんが、答えは速かったです!

3
@Lembik私は...あなたの削除された質問に行く準備ができて、答えを持っていた
ニール

これは最初に目的の数をエコーし​​、それからそれよりも大きくなった他のすべての数をエコーし​​ませんnか?
エリックアウトゴルファー

@EriktheOutgolferいいえ。を使用しない限りcall、バッチスクリプトを呼び出すと、現在のスクリプトが終了します。
ニール

5

MATL、12バイト

おかげ@AdmBorkBorkとの@Sueverどのように無効にTIOキャッシュに私に告げるために。

`30WYrqG>}2M

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

これは、使用拒否方法からランダム整数を生成する:02^30-1、入力を超えている間、繰り返しをn。これは確率で終了することが保証され1ますが、反復の平均数であり2^30/n、そしてそれはのために非常に長い時間がかかるnよりも著しく小さいです2^30

`         % Do...while
  30W     %   Push 2^30
  Yr      %   Random integer from 1 to 2^30
  q       %   Subtract 1
  G>      %   Does it exceed the input? If so: next iteration. Else: exit
}         % Finally (execute right before exiting the loop)
  2M      %   Push the last generated integer
          % End (implicit). Display (implicit)

4

JavaScript(ES6)、55 54バイト

f=(n,m=1)=>m>n?(x=Math.random()*m|0)>n?f(n):x:f(n,m*2)

[0 ... 2 k -1]の範囲の整数を生成します。ここで、k2 knよりも大きい最小の整数です。結果が[0 ... n]になるまで繰り返します。

どうして?

これは、次の前提に基づいています。

  • 内部的に、フィードするためにJSエンジンによって生成された擬似乱数整数値は、Math.random()任意の間隔[0 ... 2 k -1]k <32)で均一です。

  • 正確な2のべき乗を掛けると、IEEE 754によって返されるfloat値は、Math.random()このような間隔で一定です。

誰かがこれらの仮説を確認または反論できる場合は、コメントでお知らせください。

デモ

[0 ... 2]で100万個の値を生成し、結果の統計を表示します。


Math.floor(Math.random()*(n + 1))は、一様に分布していない結果を生成します。そのため、現実的なN <2 ^ 30が存在し、分布の異常が発生するかどうかを確認するとよいでしょう。まったく。
ツェッペリン

1
@zeppelinは、その範囲内のランダムなフロートが2 ^ 30の結果にわたって可能な限り均等に分布する2 ^ 53の値の1つを持つため、異常を特定するには試行回数が多すぎる必要があります。そのため、範囲内の数が多い場合でも、エラーは2 ^ 23分の1のようになります。つまり、とんでもない回数の試行が必要になります。おそらく、初期サンプルの数(2 ^ 53)よりも数桁多くなります。それでも、乗算器がサンプル数を均等に分割しない場合、完全に均一になることはありません。そのため、Arnouldは2のべき乗を使用します。
マーティンエンダー

4

Bash(+ coreutils)、44バイト

/ dev / urandomベースのソリューション

od -w4 -vtu4</d*/ur*|awk '($0=$2)<='$1|sed q

から符号なし32ビット整数を読み取り、指定された範囲内で1つが見つかるまで/dev/urandomフィルターで除外し、パイプを中止します。awksed q


bashのHooray :)

4

Haskell、70バイト

import System.Random
g n=head.filter(<=n).randomRs(0,2^30)<$>getStdGen

非常に効率的なアルゴリズムではありませんが、機能します。[0,2 ^ 30]で区切られた無限の整数リスト(または、Haskellの型システムのために必要に応じて浮動小数点数)を生成し、n以下の最初のものを取得します。nが小さい場合、これには長い時間がかかります。randomRのドキュメントで指定されているように、乱数は一様に分布する必要があるため、区間[0,2 ^ 30]内のすべての数値は同じ確率(1 /(2 ^ 30 + 1))を持つ必要があり、したがって[ 0、n]は同じ確率です。

代替バージョン:

import System.Random
g n=head.filter(<=n).map abs.randoms<$>getStdGen

このバージョンはひどいですが、全体のバイトを節約します。randomsタイプで定義された任意の範囲を使用して、数の無限リストを生成します。これにはネガティブが含まれる場合があるため、absポジティブ(またはゼロ)にするためにマッピングする必要があります。これは、nの値がとてつもなく大きくない場合、非常に遅くなります。編集:私は後で、このバージョンが0を取得する確率が他の数値よりも悪いために均一に分散されていないことに気付きましたabs。いくつかの番号を生成するためにm発電機を作り出すことができるm-mが、0のみ0の場合には、それ自体は動作しますが、そのためにその確率は、他の数の半分です。


Haskellにうーん(あまりにも)!

4

ゼリー、9 バイト

⁴!Ẋ’>Ðḟ⁸Ṫ

オンラインでお試しください!-上記のコードはサイズ16の範囲なのでTIOで実行されません!最初に構築する必要があります(シャッフルしてからフィルタリングする必要があることは言うまでもありません!)

どうやって?

⁴!Ẋ’>Ðḟ⁸Ṫ - Main link: n
⁴         - 16
 !        - factorial: 20922789888000
  Ẋ       - shuffle random: builds a list of the integers 1 through to 16! inclusive and
          - returns a random permutation via Python's random.shuffle (pretty resource hungry)
   ’      - decrement (vectorises - a whole pass of this huge list!)
     Ðḟ   - filter out if: (yep, yet another pass of this huge list!)
    >     -     greater than
       ⁸  -     left argument, n
        Ṫ - tail: return the rightmost remaining entry.

注:ȷ⁵単純に期待して10から10を返すのであれば、同じバイトカウントに対して1000倍以上効率的ですが、使用されるリテラル10として評価されないため、そうではありません数値リテラルによって、ȷ...むしろ2つの別個のリテラルが解析されȷます。デフォルトの指数は3で、1000が得られ、10が得られます。


フー、9文字ですが、22バイト
クリストファーサルストーガード

@ KristofferSall-Storgaard各文字はJellyのコードページの 256バイトの1つであり、通常のようにワードバイトをリンクにするのを忘れていました。
ジョナサンアラン

1
年、私はそれを調べて、同じことを見つけました
クリストファー・サル=ストールガード

4

jshellにJDK 9、75の 59バイト

n->(new Random()).ints(0,1<<30).dropWhile(x->x>n).findAny()

使用法

((IntFunction)(n->(new Random()).ints(0,1<<30).dropWhile(x->x>n).findAny())).apply(<n>)
  • -16バイト:ありがとう、ヤコブ!
  • jshellは有効なランタイム環境であると考えていると仮定します。
  • jshell自体は、ランタイム環境として、コアライブラリの明示的なインポートを必要とせず、セミコロンも必要としません。
  • を返しますOptionalInt。ルールは、戻り値の型がプリミティブでなければならないことを指定しておらずOptionalInt、結果の有効な表現であると考えています。

1
インスピレーションをくれた@ kevin-cruijssenに感謝します。私の最初のコードゴルフ!
ピートテレップ

ボックス化された出力が受け入れられるかどうかOptionalは、受け入れられるかどうかとは異なります。私があなただったらポスターで確認します。また、割り当て全体を数える必要もありません。ラムダ式だけで十分です。
ヤコブ

1
lambdaパラメーターnとの周りの括弧を削除することで4バイトを節約できますnew Random()
ヤコブ

3

PHP、30バイト

    while($argn<$n=rand());echo$n;

で実行しecho <N> | php -Rn '<code>'ます。

0からgetrandmax()(64ビットマシンでは2 ** 31-1)の間の乱数を選択します。
入力よりも大きい間、繰り返します。

これにしばらく時間かかる場合があります... AMD C-50(1 GHz)には0.3〜130秒必要でしたN=15

平均のより速い方法N46バイト):

for(;++$i<$x=1+$argn;)$n+=rand()%$x;echo$n%$x;

または

for(;++$i<$x=1+$argn;$n%=$x)$n+=rand();echo$n;

とりN+1、ランダムな整数を、それらを合計してと剰余をとりますN+1
C-50には約 100万回の実行で8秒。

19バイトの無効なソリューション:

echo rand(0,$argn);

3

PowerShell、35バイト

for(;($a=Random 1gb)-gt"$args"){}$a

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

別の拒否サンプリング方法。これは無限forループで、値をと()の間$aRandom整数に設定し、その整数がinputよりも大きい限りループを続けます。ループが完了すると、パイプラインを配置するだけで、出力は暗黙的になります。01gb= 1073741824 = 2^30-gt$args$a

注:入力が小さい場合、これには長い時間がかかります。


3

パイソン272の 69バイト

xnorのおかげで-3バイト(idビルトインを変数としてオーバーライド)

from random import*
n=input()
while id>n:id=randrange(2**30)
print id

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

randrange(2**30)範囲[0,2 30から疑似均一に分布した数(Mersenne Twister 2 19937-1)を生成します。ために下にあることが保証されている2 30、入力よりも大きくなくなるまで単に繰り返し呼び出すことができ、この。の値が非常に低い場合、予想される時間が長くかかりますが、通常、50の低い入力でも1分以内に機能します。nn


2
r=''「無限」として初期化できます。または、より良いのは、初期化せずr、代わりにをidどこでも使用することですr
XNOR


2

05AB1E、11バイト

žIÝ.rDI›_Ϥ

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

説明

žIÝ          # push the inclusive range [0 ... 2^31]
   .r        # get a random permutation (pythons random.shuffle)
     D       # duplicate this list
      I      # push input
       ›_Ï   # keep only elements from the list not greater than input
          ¤  # take the last one

リスト[0 ... 2147483648]はTIOには大きすぎるため、1.000.000代わりにリンクが使用します。

代替(平均)はるかに高速な11バイトソリューション

[žIÝ.RD¹›_#

オンラインで試す

説明

[             # start loop
 žIÝ          # push the inclusive range [0 ... 2^31]
    .R        # pick a random integer (pythons random.chiose)
      D       # duplicate
       ¹      # push input
        ›_#   # break if random number is not greater than input
              # implicitly output top of stack (the random number)

žJL.R%巨大な何かを逃していない限り、6。プッシュ2 ^ 32、0から2 ^ 32のリスト、ランダムピック。モジュロ入力。あなたが持っている効率を絶対に台無しにします。
魔法のタコUr

@carusocomputing I:モジュラスの引数を正しい順序で(および多分のÝ代わりにL)取得するために、7バイト必要です。デニスがゼリーの答えでそれをしているのを見ましたが、これが私の最初のアイデアであったため、これを保持しました。このアプローチはこれとは異なるため、別の回答として投稿することができます。
エミグナ

DI‹Ïループを回避します。
魔法のタコUr

また、現状のままでは、これが終了することは保証されていません。誤解しない限り、の入力0はほぼ常に無限ループになり、終了しにくくなります。このソリューションでは、すべてのシナリオで終了する可能性がありますが、ランダム性のために保証されていません。
魔法のタコUr

@carusocomputing:非常に小さな入力の場合、2番目のバージョンは、はいを完了するのに平均して非常に長い時間がかかりますが、十分な時間がある場合はそうなります。
エミグナ

2

Python 2、89バイト

l=range(2**31)
import random
random.shuffle(l)
n=input()
print filter(lambda x:x<=n,l)[0]

説明

L=range(2**31)      # Create a list from 0 to 2^31 exclusive. Call it <L>.
import random       # Import the module <random>.
random.shuffle(L)   # Use 'shuffle' function from <random> module,
                    # to shuffle the list <L>.
n=input()           # Take the input -> <n>.

print
    filter(         # Create a new sequence,
    lambda x:x<=n   # where each element is less than or equal to <n>.
    ,L)             # from the list <L>.
    [0]             # Take the first element.

これは、2 ^ 31個の整数を作成し、それらをシャッフルし、フィルタリングするため、非常に非効率的です。

TIOリンクを共有しても意味がありません。このような大きなリストを作成しているので、ここにn= 100のTIOリンクがあります。

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


2

Java 8、84 83 80 71 62バイト

n->{int r;for(;(r=(int)(Math.random()*(1<<30)))>n;);return r;}

@OliverGrégoireのおかげで-1バイト。@Jakobの
おかげで-3バイト。 Java 7をJava 8に変換する-9バイト。に 変更して-9バイト。

java.util.Random().nextInt(1<<30)(int)(Math.random()*(1<<30))

説明:

ここで試してみてください。

n->{        // Method with integer parameter and integer return-type
  int r;    //  Result-integer
  for(;(r=(int)(Math.random()*(1<<30)))>n;);
            //  Loop as long as the random integer is larger than the input
            //  (the random integer is in the range of 0 - 1,073,741,824 (2^30))
  return r; //  Return the random integer that is within specified range
}           // End method

注:小さな入力の場合、明らかに非常に時間がかかる場合があります。

出力例:

407594936

2
@Aaron私もこれに疑問を呈しましたが、2番目の箇条書き「組み込み関数またはライブラリランダム関数を呼び出すときの引数は定数でなければなりません。つまり、入力値から完全に独立している必要があります。」これが、max intが使用される理由です。
ポケ

1
2^30= 1073741824。使用したい-1>>>1(= 2147483647)。しかし、これは存在します:1<<30これは正確に等しい2^30です; そして、1バイト短くなります。
オリビエグレゴワール

1
どうint c(int n){int r;for(;(r=new java.util.Random().nextInt(1<<30))>n;);return r;}
ヤコブ

@Jakobありがとう。7の代わりにJava 8を使用し、のMath.random()代わりにを使用して、さらに18バイト短縮しましたjava.util.Random().nextInt
ケビンCruijssen

2

Python 3、51バイト

これは、非正統的なランダムソースを使用したpythonソリューションです。

print(list(set(map(str,range(int(input())+1))))[0])

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

これを分解するために。

int(input())+1

入力番号を取得し、それに追加1します。

set(range(...))

{0, 1, 2, 3, 4, ... n}考えられるすべての結果のセットを作成します。

print(list(...)[0])

セットを取得してリストに変換し、最初のアイテムを取得します。

これは、Python 3ではPYTHONHASHSEEDset()によって順序が確立されるためです(取得できませんが、スクリプトの実行時に確立されます)。

確かに、hash()値はランダムに割り当てられhash()hash(input())それ自体を返すのではなく、特定のでランダムに値を選択するので、これは均一な分布であると推測しています。

これが均一な分布であるかどうか、またはどのようにテストできるかを誰かが知っている場合は、コメントしてください。


1

C#、57バイト

n=>{int x=n+1;while(x>n)x=new Random().Next();return x;};

0からnまでの整数を返す無名関数。

入力値が小さいほど、ランダムな値を返す時間が長くなります。

完全なプログラム:

using System;

class RandomNumber
{
    static void Main()
    {
        Func<int, int> f =
        n=>{int x=n+1;while(x>n)x=new Random().Next();return x;};

        // example
        Console.WriteLine(f(100000));
    }
}

2
「組み込み関数またはライブラリのランダム関数を呼び出すときの引数は定数でなければなりません。つまり、入力値から完全に独立している必要があります。」への引数Nextは静的ではありません。
Yytsi

1

Bash + coreutils、20バイト

ゴルフ

seq 0 $ 1 | shuf | sed 1q

shuf-ランダムな順列を生成

Shufは次のコードを使用して、順列を生成します。

permutation = randperm_new (randint_source, head_lines, n_lines);

で終わる randint_genmax

/* Consume random data from *S to generate a random number in the range
0 .. GENMAX.  */

randint
randint_genmax (struct randint_source *s, randint genmax) 
{
      ...

      randread (source, buf, i);

      /* Increase RANDMAX by appending random bytes to RANDNUM and
         UCHAR_MAX to RANDMAX until RANDMAX is no less than
         GENMAX.  This may lose up to CHAR_BIT bits of information
         if shift_right (RANDINT_MAX) < GENMAX, but it is not
         worth the programming hassle of saving these bits since
         GENMAX is rarely that large in practice.  */
      ...
}

次に、 低レベルのランダム性のソースから数バイトのランダムデータを読み取ります。

/* Consume random data from *S to generate a random buffer BUF of size
   SIZE.  */

void
randread (struct randread_source *s, void *buf, size_t size)
{
  if (s->source)
    readsource (s, buf, size);
  else
    readisaac (&s->buf.isaac, buf, size);
}

つまり、低レベルでは、shuf入力値とランダム性のソースから読み取られたデータとの間に直接の依存関係はありません(必要なバイトバッファー容量の計算は別として)。


6
これは、乱数ジェネレータへの引数として入力を提供していませんか?
マーティンエンダー

これが有効でない場合でも、別のbash回答を送信してください!

@MartinEnderは、直接ではなく、入力を使用して、生成された整数範囲の上限を定義するだけですjot will arrange for all the values in the range to appear in the output with an equal probability(それはおそらく境界線ですが、それでも)。
ツェッペリン

2
私はに深く十分に掘る場合は任意の乱数ジェネレータ私は確信している私が直接、元の引数を使用しない低レベルのRNGへの呼び出しを見つけることができます。課題のポイントは、固定サイズの分布から任意のサイズの均一な分布を取得することですが、これはまだ実行していません。
マーティンエンダー

1

SmileBASIC、38バイト

INPUT N@L
R=RND(1<<30)ON N<=R GOTO@L?R

入力より小さい値を取得するまで乱数を生成します。


1

ルビー、23 15 23 32 29バイト

->n{1while n<q=rand(2**30);q}

使い方:

  • 1while [...];ステートメントを少なくとも1回実行します:1before whileはnopとして機能します
  • 範囲0..2 ^ 30-1(指定どおり2 ^ 30未満)の乱数を取得します
  • 数値が入力パラメーターよりも大きい場合は繰り返します(nが小さい場合は時間がかかることがあります)

1

オーム、26バイト

IΩ
D31º#╬D0[>?D-+∞;,

説明:

IΩ                 ■Main wire
IΩ                 ■Call wire below

D31º#╬D0[>?D-+∞;,  ■"Real main" wire
D                  ■Duplicate input
 31º#╬D            ■Push random_int in [0..2^31] twice
       0[          ■Push input again
         >?    ;   ■If(random_int > input){
           D-+     ■  remove the random_int
              ∞    ■  recursion
               ;   ■}
                ,  ■Print random_int

この言語の通訳はありますか?そして、コードページはどうですか?
アタコ

@ATaco:通訳者、コードページ:CP-437
Emigna

1

行く、 63 61バイト

import."math/rand"
var n=0;func R(){q:=n;for;q<n+1;n=Int(){}}

次のように使用します。

func main() {
    n = 5000
    R()
    print(n)
}

Go Playgroundでライブテストする


私たちのデフォルト、パー事前に定義された変数からの入力を取ると、あらかじめ定義された変数に出力を書き込むことが許可されていません。ただし、グローバル変数へのポインタを使用できます
デニス

1

Golang、84 78 71バイト

import."math/rand"
func R(n int)int{q:=n+1;for;q>=n;q=Int(){};return q}

単純な拒否サンプリング。

注:math / randシードは定数1であるため、定数結果が必要でない限り、呼び出し元はシードする必要があります。

テスト:https : //play.golang.org/p/FBB4LKXo1r 64ビットシステムで実際にテストできなくなりました。64ビットのランダム性を返し、拒否テストを使用しているためです。

package main

import "fmt"
import "time"

/* solution here *//* end solution */

func main() {
    Seed(time.Now().Unix())
    fmt.Println(R(1073741823))
}

1
あなたが使用している場合import."math/rand"、次にInt31グローバル名前空間で利用可能で、あなたは4つのバイトを保存することができ、また、intあなたに別の6バイトを保存し、少なくとも32ビットであることが保証されている
クリストファーのSalI-Storgaard

:=別の3バイトの構文を使用します
クリストファーサルストーガード

Int31()-3 * int +()= 11バイト対2 * int32 = 10バイトの結果をキャストする必要があるため、int32の代わりにintを使用してもバイトは保存されません。
ライキング

1
キャストする必要がないので、Int()あなたが後にスペースを削除することができ、また、ランドパッケージの機能import
クリストファーのSalI-Storgaard
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.