ランダムな整数を生成します


17

あなたのプログラム/機能は

  • 正確に1つの整数を出力します
  • 正の確率で整数を出力します
  • 少なくとも50%の確率で、1.000.000より大きい整数または-1.000.000より小さい整数を出力します。

出力例(すべてが可能である必要があります):

59875669123
12
-42
-4640055890
0
2014
12
24
-7190464664658648640055894646646586486400558904644646646586486400558904646649001

明確化:

  • 末尾の改行が許可されます。
  • 先行ゼロは許可されません。
  • -0 許可されています。

最短のコードが優先されます。


2
@Optimizer なぜ一様な確率を仮定しているのですか?質問はそれを述べていません。実際、そのポイントから、分布の少なくとも50%が[-1百万、100万]の範囲外にある限り、分布均一である必要はないことが明らかです。
ホッブズ14

10
「すべての整数にわたる均一な分布」を生成するソリューションは不可能です。無限に多数の整数があるので、個々の整数は確率0で表示されます。(または、有限数を出力すると、他の無限に多くを無視していることになります!)P(total )= 1。
joeytwiddle 14

2
@YpnypnコンピューターのRAMも制限ではありません。部分的な出力をどこかに保存する必要はありません。
jimmy23013 14

4
@GiantTree-- way too long to fit in an integerこれは、32/64ビットアーチのデータ型をinteger意味すると仮定した場合にのみ当てはまりますがint、これは必ずしも有効な仮定ではありません。「整数」は数学用語として始まり、サイズの制約はありません。
偽名14

5
疑似乱数ジェネレーターを使用して出力を決定すると、ほとんどすべての整数が除外され、生成可能な整数のサイズに上限が設定されます(PRNGの期間が有限であると仮定)。これは回答で無視できますか、または有効な回答には真の乱数ジェネレーターが必要ですか?
trichoplax 14

回答:


12

CJam、16 14 13バイト

0{Kmr(+esmr}g

これは、現在のタイムスタンプ(10 12のオーダー)を使用してループを終了する必要があるかどうかを判断するため、非常に長時間実行されます。これは最も短いので、これを提出として使用していますが、2つの14バイトの選択肢があり、それぞれにメリットがあります。

0{esmr(+esmr}g

この1はされないの範囲以来、PRNGの期間によって制限され、すべての乱数は現在のタイムスタンプに依存します。したがって、これは任意の数を生成できるはずです。ただし、負の数、または小さな正の数の確率はゼロになります。

以下は3e5、タイムスタンプの代わりに使用する同等のバージョンです。そして20、最初の範囲(13バイトの提出として)。それははるかに高速であり、すべてのルールにも準拠しています。妥当な実行時間と小さなコードサイズを維持しながら、1,000,000を超える数値に対して50%の確率を得るのは、一種の制限的なケースです。説明と数学的正当化は、このバージョンを参照しています。

0{Kmr(+3e5mr}g

通常、これには数秒かかります。をに置き換える5と、2さらに高速に実行できます。ただし、50%の確率に関する要件は、1,000,000ではなく1,000でのみ満たされます。

私は0から始めています。それからループがあり、確率1 /(3 * 10 5)で抜け出します。そのループ内で、実行中の合計に-1〜18(両端を含む)のランダムな整数を追加します。正の整数は負の整数よりも可能性が高いため、各整数が出力される確率は(小さいながらも)有限です(生涯に負の整数が表示されるとは思わない)。このような小さな確率でブレークアウトし、ほとんどの時間をインクリメント(および減算よりも多く加算)することで、通常1,000,000を超えることが保証されます。

0              "Push a 0.";
 {          }g "Do while...";
  Kmr          "Get a random integer in 0..19.";
     (         "Decrement to give -1..18.";
      +        "Add.";
       3e5mr   "Get a random integer in 0..299,999. Aborts if this is 0.";

数学的正当化:

  • 各ステップで、平均で8.5を追加します。
  • 1,000,000に到達するには、これらのステップのうち117,647が必要です。
  • このステップ数よりも少ない確率で、

    sum(n=0..117,646) (299,999/300,000)^n * 1/300,000
    

    これはに評価され0.324402ます。したがって、ケースの約3分の2で、117,647のステップが増え、1,000,000ごとに簡単になります。

  • (これは正確な確率ではないことに注意してください、それらの平均8.5に多少の変動があるためですが、50%に到達するには、117,646を超えて約210,000ステップに進む必要があります。)
  • 疑わしい場合は、終了確率の分母を簡単に爆破できます。 9e9バイトを追加せずに(ただし、実行時間は何年も)ます。

...または11バイト?

最後に、11バイトのバージョンがあります。これもPRNGの期間によって制限されませんが、ほとんど毎回メモリ不足になります。反復ごとに(タイムスタンプに基づいて)乱数を1つだけ生成し、インクリメントと終了の両方に使用します。各反復の結果はスタックに残り、最後にのみ集計されます。このアイデアをありがとうデニス:

{esmr(}h]:+

ルールに真の乱数ジェネレーターが必要かどうかを確認するために質問にコメントを追加しましたが、ペダントリーに感謝すると思います。あなたのランダムソースはここで擬似ランダムですか?そうすると、可能な出力のセットのサイズがPRNGの最大期間に制限されますよね?
センモウヒラムシ

(関係なく、単純なエレガンスのための+1)
センモウヒラムシ

はい、私はこれまでのところ推測しています。私は...誰かのポストしかし、その問題のない答えかどうかを確認するために好奇心が強い
センモウヒラムシ

私はあなたの乱数ジェネレーターが真の乱数ジェネレーターであるかどうかを仮定できると述べているので、これは今では冗長です... :)
trichoplax 14

Kmr期間内の合計は、その期間よりも常に大きな正の数である可能性があります。そして、その場合、すべての可能な数を生成することはできません。
jimmy23013 14

11

Java、133 149

void f(){String s=x(2)<1?"-":"";for(s+=x(9)+1;x(50)>0;s+=x(10));System.out.print(x(9)<1?0:s);}int x(int i){return new java.util.Random().nextInt(i);}

出力例

-8288612864831065123773
0
660850844164689214
-92190983694570102879284616600593698307556468079819964903404819
3264

非ゴルフ

void f() {
    String s = x(2)<1 ? "-" : "";       // start with optional negative sign
    s+=x(9)+1;                          // add a random non-zero digit
    for(; x(50)>0; )                    // with a 98% probability...
        s+=x(10)                        // append a random digit
    System.out.print(x(9)<1 ? 0 : s);   // 10% chance of printing 0 instead
}

int x(int i) {
    return new java.util.Random().nextInt(i);
}

古い回答(ルール変更前)

void f(){if(Math.random()<.5)System.out.print('-');do System.out.print(new java.util.Random().nextInt(10));while(Math.random()>.02);}

あなたはどちらも正しいですが、問題は確率がなければならないと述べている少なくとも +/- 1.000.000の範囲で50%ないし
GiantTree

@Optimizerやり直し。
Ypnypn 14

バイナリリテラルを使用する場合、-。を印刷する必要はありません。
TheNumberOne

4

Mathematica-47

Round@RandomVariate@NormalDistribution[0,15*^5]

基本的には、分散が1500000に等しい正規分布を使用して乱数を生成します。これにより、確率49.5015%で-10 ^ 6〜10 ^ 6の整数が生成されます。


「これにより、確率が50.4985%の-10 ^ 6〜10 ^ 6の整数が生成されます。」-それだけでは十分ではありません。仕様を読み間違えましたか?おそらく、分散として10 ^ 7を使用するつもりでしたか?
ジョン・ドヴォルザーク

@JanDvorak間違った確率、ごめんなさい。今では正しいものです。
スウィッシュ

Mathematicaでのこれの実装はすべての整数を本当にカバーしていますか?...私は、ソースへのアクセスを持っていないが、私はないと思うだろう
センモウヒラムシ

@githubphagocyte現在の精度に依存します。
スウィッシュ

4
つまり特定の精度を指定すると、それより大きい数値は除外されます。動作する唯一の方法は、無制限の精度を指定できる場合です。
trichoplax 14

4

Python 2、 75 69バイト

from random import*;s=0;j=randrange
while j(12):s=s*9+j(-8,9)
print s

真ん中のwhileループがすべての整数を生成できることを確認するのは簡単です(ただし、ゼロに偏っています)。「12」は、±10 6を超える数の約半分が存在するように選択されます。


古いソリューション:

Python 2、44バイト

Mathematicaソリューションに基づいています

from random import*;print int(gauss(0,8**7))

Pythonのfloat精度は有限であるため、実際には機能しません。


これは、すべての整数を生成することはできません。これは、擬似乱数ジェネレーターの内部状態の量が有限であるためです。ドキュメントによると、PythonはMersenne Twisterを使用しているため、状態は非常に大きくなっています。しかし、それは無限ではないため、すべての整数の有限サブセットのみを生成できます。
starblue

@starblue:OPから:「あなたの言語の乱数ジェネレーターは、そうでなくても真の乱数ジェネレーターであると仮定できます。」
ケニー14

3

ルビー、70

f=->{m=10**6
r=rand -m..m
r<1?(r>-5e5??-:'')+r.to_s+f[][/\d+/]:r.to_s}

非常に大きな数を生成できるようにするためにString、ラムダからa として数を返します。それが許可されていない場合puts f[]は、関数ではなくプログラムにするために、8文字余分にカウントします(for )。

説明

-1,000,000との間の数値を生成し1,000,000ます。数値が1それ以上の場合、数値はとして返されますString

数値がより小さい場合1、関数は再帰的に呼び出され、数値範囲外の数値を返します。負の数も生成できるように、初期数がより大きい場合、-結果の前にa が付けられます。String-500,000

課題を正しく理解できたと思います!


3

R、38

library(Rmpfr)
round(rnorm(1,2e6,1e6))

ランダムに選択された平均2,000,000、標準偏差1,000,000のガウス分布からの描画。描画の約2/3が1,000,000および3,000,000以内に収まります。分布は制限されていないため、理論上は任意の整数を生成できます。Rmpfrパッケージは、Rに組み込まれたdouble floatを任意の精度で置き換えます。


仕様を読み間違えていることに気付きました。そして、私はそれは同じMathematicaを使った機械の精度には限界があると想像
shadowtalkerを

うーん、その場合はわかりません。調べなければなりません。今のところ、この答えを「保留」と考えてください
シャドウトーカー14

MartinBüttner@私は思うの固定
shadowtalker

面白い。sample(c(1,-1),1)しかし、全体を考える必要はないと思います。ただ、1E6を中心とするだけでは十分でなければなりません。..
マーティン・エンダー

@MartinBüttnerああ、両端で50%である必要はありませんか?それは明確ではありませんでした
シャドウトーカー14

2

Perl、53文字

print"-"if rand>.5;do{print int rand 10}while rand>.1

私は確かに何らかの理由で表示されていない作品を 1を印刷するときに、整数で:)

先頭に「-」が付いていても付いていなくても、数字を印刷する確率は同じです。

1桁の数字で10%、2桁の数字で9%、3桁の数字で8.1%、4桁の数字で7.29%の数字で、5桁の数字で印刷します。時間の6.56%、時間の5.9%の6桁の数字など。確率は低下しますが、任意の長さが可能です。1から5桁の数字は出力ケースの約41.5%を占め、1,000,000(または-1,000,000)の数字はわずか6百万分の1であるため、出力数は-1,000,000から1,000,000の約54.6の範囲外になります時間の割合。

「0」と「-0」の両方が出力される可能性がありますが、問題ないことを願っています。


これは-00000000167のような「数字」を印刷しませんか?それは実際には整数ではありません。
isaacg 14

1
@isaacgなぜ整数ではないのかわかりません。
オプティマイザー14

2
それはですが、OPを明示的に0をリード禁じられています@Optimizer
マーティン・エンダー

ループの前に、-9から+9までのランダムなゼロ以外の先頭桁を生成できます。 print int(rand(20)-10)||1。ただし、出力として0を生成する方法が必要です。多分|| die 0、ゼロの後のゴミが許可されている場合。それ以外の場合は、ゼロを出力し、さらに出力せずに終了する短い方法が必要ですint(rand(20)-10)==0
ピーターコーデス14

@PeterCordesは同意しました、それはまともなアプローチですが、私はそれを書く気はなく、長さに関して競争力があるとは思いません。自分で提出してください:)
hobbs 14

2

Perl、114文字

use Math::BigInt;sub r{$x=Math::BigInt->new(0);while(rand(99)!=0){$x->badd(rand(2**99)-2**98);}print($x->bstr());}

壊す:

use Math::BigInt;               -- include BigIntegers
  sub r{                        -- Define subroutine "r"
    $x=Math::BigInt->new(0);    -- Create BigInteger $x with initial value "0"
      while(rand(99)!=0){       -- Loop around until rand(99) equals "0" (may be a long time)
        $x->badd(               -- Add a value to that BigInt
          rand(2**99)-2**98);   -- Generate a random number between -2^98 and +2^98-1
        }print($x->bstr());}    -- print the value of the BigInt

-1.000.000と1.000.000間の値を得る確率はゼロに向かって傾向にあるしかしそれが可能です。

注:このサブルーチンは長時間実行され、「Out of Memory!」というエラーが出力される場合があります。エラーですが、質問で述べられているように、技術的に整数を生成しています。

Perl、25

sub r{rand(2**99)-2**98;}

+/- 2 ^ 99の範囲内でランダムな整数を生成します。

壊す

sub r{                    -- Define subroutine "r"
     rand(2**99)          -- Generate a random integer between 0 and 2^99
                -2**98;}  -- Subtract 2^98 to get negative values as well

100万個のサンプルでテスト済み:

~5 are inside the range of +/-1.000.000
~999.995 are outside that range
= a probability of ~99,99% of generating an integer outside that range.
Compare that number to the probability of 2.000.000 in 2^99: It is approx. the same.

これはすべてのルールを満たしています。

  • 1つの整数
  • 任意の整数が可能です
  • 生成されたすべての整数の少なくとも50%(私の場合は99,99%)は+/- 1.000.000の範囲外です。

これは、基礎となる乱数ジェネレーターが生成されるすべてのビットに等しい確率を定義し、生成された整数でも同様の確率を定義するために機能します。
すべての整数は、1/2 ^ 99の確率で生成されます。

編集:

大きな整数が生成されるように、指数を増やす必要がありました。コードをできるだけ短くするため、99を選択しました。


上限/下限はないことに同意しませんでしたか?たとえば、整数2 ^ 31 + 1の確率は0であり、規則2を破る
オプティマイザー14

@Optimizer for me整数は、多くのプログラミング言語のように定義されています:-2^31および+2^31-1(32ビット)の範囲内の数値。大きな整数を生成したい場合、指数を簡単に増やすことができますが、Perlの実装によっては失敗する場合があります。
ジャイアントツリー14

途方もなく大きな整数も生成しなければならないことがわかりました。コードをすばやく編集します。
ジャイアントツリー

@MartinBüttner質問の仕様を満たすために全力を尽くしました。私が無限に大きな整数を生成することは(少なくとも助けなしでは)不可能です。Perlの最大整数は約1.7e308であり、これは制御できない制限です。
ジャイアントツリー14

@MartinBüttnerどちらも可能ですが、たとえば 2GBのデータの後に文字列がオーバーフローし、再び有限になります。メモリに問題がある場合、数値が無限に大きいとは言い難いです。BigIntsを使用して、すぐに別のアプローチを考えます。また、整数オーバーフロー1.7e308でそれはちょうど(infiteに変換されますない1.#INF正確に)
GiantTree

2

C#、 126 107バイト

string F(){var a=new System.Random();var b=a.Next(-1E6,1E6+1)+"";while(a.Next(1)>0)b+=a.Next(10);return b;}

ゴルフをしていない:

string F()
{
    System.Random rand = new System.Random();
    string rtn = rand.Next(-1E6, 1E6 + 1) + "";
    while (rand.Next(1) > 0)
         rtn += a.Next(10);
    return rtn;
}

nを生成するチャンス桁のは1/2 ^(n-10)であり、これはすべての正のnに対して0より大きく、n = 11に対して1/2です。また、元の質問またはそのコメントのいずれでも禁止されていないように見える先行ゼロを作成します。


を使用する場合using System;System.Random2回は必要ありませんが、ちょうどRandomいいですか?
チャーリー14

@Charlieこれは関数なので、usingステートメントを使用することはできません。とにかく1文字しか保存しません。
LegionMammal978 14

1
でスペースを削除すると、1文字節約できます-1E6, 1E6+1
ProgramFOX 14

2

Perl、62バイト

print $n=int rand(20)-10;while($n&&rand>.1){print int rand 10}

一度に数字を生成するという@Hobbsと同じ考えがありましたが、彼のコードは追加された先行ゼロの要件を満たしていませんでした。符号だけではなく、最初の数字を生成することで解決しました。また、ゼロを出力した場合に終了する短い方法、または先頭の-9から9を生成する短い方法がない限り、サイズに対してこれを行う必要があります。

シェルループ内: while perl -e '...'; do echo;done |less

これは、問題を満たすために無限のRAMを必要としない最短の1つだと思います。おまけとして、出力は何にも強く偏っておらず、実行時間は非常に高速です。

私はビット単位を使用してwhile条件で文字を保存しようとしましたが、これはより頻繁に真実になると思うので、ループはより早く終了します。それに対抗するために、abs(output)> 1Mを生成する確率を維持するために、他のものを調整するためにより多くの文字が必要になるでしょう。


ニース、あなたは私が考えていなかったいくつかのことを絞り出しました:)
hobbs 14

1

Javascript(73)

このソリューションでは、前の数値にnを乗算し、ベースnに数字を追加することにより、ベースnの数値を作成できることを使用します。すべての負の整数を作成できるようにするための追加機能があります。次のコードは、ブラウザコンソールでテストする必要があります。..?..:..

b=Math.round;c=Math.random;x=0;while(b(c()*99)){x*=b(c())?2:-2;x+=b(c())}

整数> = 2^1(または<= -(2^1))を取得する確率は、ループが2回実行される確率に等しくなります。その可能性は(98/99)^2です。したがって、より大きい2^20(または<= -(2^20))数値が得られる可能性は(98/99)^21 = 0.80881%です。ただし、これは理論上すべてであり、Math.randomが真にランダムであると仮定しています。明らかにそうではありません。


このコードをテストするスニペット。また、より読みやすい方法で。


1
OPは、たとえそうでなくても、PRNGは本当にランダムであると仮定できることを確認しました。
センモウヒラムシ

1

GolfScript、20バイト

0{)8.?rand}do.2&(*4/

ええ、これもちょっと遅いです。

CJamやPythなどの言語と比較して、GolfScriptは冗長な乱数生成キーワード(rand)に悩まされています。このハンディキャップを克服するには、一度だけ使用する方法を見つける必要がありました。

このコードは、0〜8 8 -1 = 16,777,215の範囲の乱数を繰り返し選択し、乱数が0になるまでカウンターを増分することで機能します。結果のカウンター値は、中央値が約-1 / log 2の幾何分布になります。(1 − 1/8 8)≈11,629,080であるため、「少なくとも1時間の1,000,000を超える」テストに適合します。

残念ながら、こうして生成された乱数は常に厳密に正です。したがって、追加の.2&(*4/部分は、負またはゼロになるために必要です。数値の2番目に低いビット(つまり0または2)を抽出し、-1または1になるようにデクリメントして、元の数値と乗算し、結果を4で除算することで(削除する)最下位2ビット。現在は符号と相関しており、結果がゼロになることも可能です。4で除算した後でも、乱数の絶対値の中央値は-1 / log 2(1-1/ 8 8)/ 4≈2,907,270なので、50%テストに合格します。


1

JavaScript、81バイト

このコードはすべてのルールを満たします:

  • 正の確率で整数を出力します
  • +/- 1000000の範囲外の整数を少なくとも50%の確率で出力します
  • 0出力に先行なし

ボーナスとして、アルゴリズムはO(log 10 n)の時間計算量で実行されるため、ほぼ瞬時に整数を返します。

for(s="",r=Math.random;r()>.1;s+=10*r()|0);r(s=s.replace(/^0*/,"")||0)<.5?"-"+s:s

これはREPL環境を前提としています。ブラウザのコンソールで上記のコードを実行するか、以下のスタックスニペットを使用してください。

D.onclick = function() {
  for(s="", r=Math.random;r()>.1; s+=10*r()|0);
  P.innerHTML += (r(s=s.replace(/^0*/,"") || 0) <.5 ?"-" + s : s) + "<br>"
}
<button id=D>Generate a random number</button><pre id=P></pre>

アルゴリズム

  • saまでランダムな数字を文字列に追加し続けますMath.random() > 0.1
  • に基づいてMath.random() > 0.5、数字を負にします(文字列の先頭にをs付けて-)。

このアルゴリズムには、すべての整数にわたる均一な分布はありません。桁数が多い整数は、低い桁よりも確率が低くなります。各forループの反復では、現在の桁で停止する可能性が10%あります。6桁の時間の50%以上後に停止することを確認する必要があります。

@nutkiによるこの方程式は、上記の条件に基づいた停止確率の最大値を説明しています。

1 - 50%^(1/6) ≈ 0.11

したがって、0.1は問題の3つのすべてのルールを満たす範囲内にあります。


この答えについて私を混乱させるいくつかのことがあります。Math.random()が乱数の均一な分布を生成すると仮定しました。これは、仕様に実装依存であると記載されているためです。均一な分布であると仮定すると、P(Math.random()> 0.1)= 0.9なので、各反復の間に終了する可能性が非常に高くなります。Firefox 34.0 Ubuntuで実行されるアルゴリズムの実装により、テストするたびに〜0.47
Wk_of_Angmar 14

また、入力なしのアルゴリズムの時間の複雑さをどのように計算しましたか?
Wk_of_Angmar 14

1

TI-BASIC、14バイト

1-2int(2rand:randNorm(AnsE6,9

@ssdecontrolのRの回答と同様に、これは平均-1,000,000または1,000,000のガウス分布から無作為に選択され、標準偏差9を使用します。分布は無制限なので、理論上は任意の整数を生成できます。

説明

1-2int(2rand     - get a random integer 0 or 1, then multiply by 2 and subtract 1
:                - this gives the number 1 or -1 (with equal probability) to Ans
randNorm(AnsE6,9 - displays Gaussian distribution with mean (Ans * 1,000,000) and std. dev. 9

しかし、「2」または「-2」を生成できますか?
ケニー14


1
OKはコードを間違って読みました(:説明がどのように表示されるかにより、思考は「印刷」を意味します)。しかし、20桁以上の数字を生成できますか?
ケニー14

出力として任意の長整数が可能ですか?これは範囲によって制限されていませんrandNormか?
オプティマイザー14

「分布は無限であるため、理論的には任意の整数を生成できます。」範囲はありません。
ティムテック14

1

バッシュ、66

LANG=C sed -r '/^-?(0|[1-9][0-9]*)$/q;s/.*/5000000/;q'</dev/random

ほとんど常に5000000を出力します。ただし、で有効な数値が見つかった場合は/dev/random、代わりにその数値が出力されます。

そして、これは高速です:

LANG=C sed -r '/^-?(0|[1-9][0-9]*)$/q;s/.*/5000000/;q'</dev/urandom

1
@Optimizer遅いはずです。それは本当のランダムなソースだからです。ただし、/dev/urandomランダム性が低い方でテストできます。
jimmy23013 14

@Optimizer手動入力はどのように行われますか?ファイルを読み込んでいますが、すべてがファイルです。
Nit 14

@Optimizer私は単純にあなたが目指すポイントを理解していません。
NIT

/dev/urandomシェルスクリプトからの読み取りは、基本的rand()に他の言語での呼び出しと同じです。POSIX shではなくbashを実際に使用している場合は、から乱数を取得できますecho $RANDOMwiki.ubuntu.com/DashAsBinShhexdump /dev/urandombare-POSIX-minimumに相当するものとして提供します/bin/dash
ピーターコーデス14

1

C ++、95バイト

void f(){int d=-18,s=-1;while(s<9){d=(rand()%19+d+9)%10;cout<<d;s=9-rand()%10*min(d*d+s+1,1);}}

拡張:

void f() {
    int d=-18,s=-1;
    while(s<9) {
        d=(rand()%19+d+9)%10;
        cout<<d;
        s=9-rand()%10*min(d*d+s+1,1);
    }
}

説明:

この関数は、ランダムな値のスイッチが関数を停止するために必要な値を取得するまで、連続したランダムな数字を出力し続けます。dは、印刷される次の数字の値を保持する変数です。sは、間隔[0、9]でランダムな整数値をとるスイッチ変数です。s== 9の場合、これ以上数字は出力されず、機能は終了します。

変数dおよびsは、最初の桁に特別な処理を与えるために初期化されます(区間[-9、9]から取得し、最初の桁がゼロの場合、先行ゼロを避けるために関数を終了する必要があります)。dの値はd = rand()%10として割り当てることができますが、最初の数字は負の値にできません。dは代わりにd =(rand()%19 + d + 9)%10として割り当てられ、-18で初期化されるため、dの最初の値の範囲は[-9、9]で、次の値の範囲は常に[0 、9]。

変数sの範囲は[0、9]からランダムであり、sが9に等しい場合、関数は終了するため、最初の数字を印刷した後、次の数字が90%の確率で印刷されます(rand()が本当にランダムであると仮定し、 3番目の条件を満たすため)。sはs = rand()%10として簡単に割り当てることができますが、例外があります。最初の桁がゼロの場合、関数は終了する必要があります。このような例外を処理するために、sはs = 9-rand()%10 * min(d * d + s + 1,1)として割り当てられ、-1として初期化されています。最初の桁がゼロの場合、minは0を返し、sは9-0 = 9に等しくなります。s変数の割り当ては常に[0、9]の範囲であるため、例外は最初の桁でのみ発生します。

特性(rand()が本当にランダムであると仮定)

  • 整数は1桁ずつ印刷され、最後の数字を印刷した後、別の数字を印刷する確率が90%に固定されます。

  • 0は、印刷される可能性が最も高い整数で、約5.2%の確率です。

  • 間隔[-10 ^ 6、10 ^ 6]に整数を印刷する確率は、ほぼ44%です(計算はここには書かれていません)。

  • 正の整数と負の整数は同じ確率(〜47.4%)で出力されます。

  • すべての数字が同じ確率で印刷されるわけではありません。たとえば、整数の印刷中に、最後の数字が5だった場合、数字3が次に印刷される可能性がわずかに低くなります。一般に、最後の数字がdの場合、数字(d + 18)%10は次に印刷される可能性がわずかに低くなります。

出力例(10回の実行)

-548856139437
7358950092214
507
912709491283845942316784
-68
-6
-87614261
0
-5139524
7

Process returned 0 (0x0)   execution time : 0.928 s
Press any key to continue.

1

バッシュ、42バイト

printf "%d\n" 0x$(xxd -p -l5 /dev/random)
OSXの/ dev / randomは単なるランダムバイトで、xxd -p -l55つのASCII文字を16 printf進数に変換し、10進数形式に変換します。


0

Pyth、11バイト

WOyG~ZtOT)Z

注:このプログラムは、実際のコンピューターではメモリエラーでクラッシュする可能性があります。それをテストするには、G次のコードのように短い文字列で置き換えてみてください。平均すると28000前後の数値が生成されます。

pyth -c 'WOy"abcdefghijklm"~ZtOUT)Z'

このコードは、-1から8までの乱数を追加しZてループし、各繰り返しで2 ^ -26の確率でループを終了します。2 ^ -26の確率は、アルファベットのOすべてのサブセット(y)のセットのランダム要素()を選択することにより達成されます(G)ます。

技術的な詳細と正当化:

確率2 ^ -26は、2つの事実から導き出さyれます。シーケンスで呼び出された場合、パワーセット関数であり、入力のすべてのサブセットのリストを作成します。入力のG長さは26文字なので、このパワーセットにyGは2 ^ 26のエントリがあります。OyGそれらの2 ^ 26エントリからランダムな要素を選択します。それらのエントリの1つである空の文字列Wは、whileループに渡されると偽と評価されます。したがって、毎回ループを抜ける確率は2 ^ -26です。

ループサイクルKの任意の固定数では、合計K * 3.5 + mを取得し、K * 3.5-mを取得する確率は等しくなります。これは、合計1つを達成する加数の各シーケンスを反転できるため、-1-> 8、0 -> 7など、他を達成します。さらに、K * 3.5に近い数字は、遠くの数字よりも明らかに高い可能性があります。したがって、K> 2000000 / 3.5 = 571428.5の場合、1000000を超える数が得られる確率は75%を超えます。これは、その数を超える結果の一部が、その下のすべての結果と1対1で対応できるためです。数値、および半分未満は、1000000未満のものと1対1で対応できます。少なくとも571429ループを取得する確率は、(1-2 ^ -26)^ 571429です。 (1-2 ^ -26 * 571429)未満、最初の571429回の試行でループを抜ける予想回数は99.1%です。したがって、試行の99.1%以上では、少なくとも1000000を獲得する可能性が75%以上あり、したがって1000000を超える可能性は50%以上あります。

このコードは、O3日前に誤ってバグが導入され、今日修正された場合の動作に依存しています。12月22日以前、または今日以降のPyth 3のどのバージョンでも動作するはずです。次のコードは同等であり、常に機能しています。

WOyG~ZtOUT)Z

オンラインコンパイラはどうなりましたか?
オプティマイザー14

@OptimizerのWebサイトに関する問題、私はそれに取り組みます。
isaacg 14

ああ、かっこいい。昨日CJam応答のPyth翻訳の仕事したかったし、それが404を与えることが判明
オプティマイザ

0

Java、113バイト

void g(){String a=Math.random()>0?"10":"01";for(;Math.random()>0;)a+=(int)(Math.random()*2);System.out.print(a);}

このプログラムは、バイナリ出力を標準出力ストリームに出力します。数値が終了する(または正の値になる)確率が約0であるため、しばらく待つ必要があります。生成された数値の絶対値が100万未満であるという考えは面白いですが、可能です。

ゴルフをしていない:

void g(){
    String a=Math.random()>0?"10":"01";             //Make sure there are no trailing zeroes.
    for(;Math.random()>0;)a+=(int)(Math.random()*2);//Add digits
    System.out.print(a);                            //Print
}

サンプル出力:数値の生成が完了すると投稿します。


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