임의의 정수를 생성


17

프로그램 / 기능은

  • 정확히 하나의 정수를 출력
  • 출력 어떤 긍정적 확률 정수
  • 적어도 50 % 확률로 1.000.000보다 크거나 -1.000.000보다 작은 정수를 출력합니다.

출력 예 (모두 가능해야 함) :

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

설명 :

  • 후행 줄 바꿈이 허용됩니다.
  • 선행 0은 허용되지 않습니다.
  • -0 허용됩니다.

가장 짧은 코드가 승리합니다.


2
@Optimizer 왜 당신은 균일 한 확률을 가정합니까? 질문은 그것을 진술하지 않습니다. 사실 그 분포의 50 % 이상이 [-1 백만, 1 백만]을 벗어나지 않는 한 분포 가 균일 하지 않아도 된다는 것이 분명해 보입니다 .
— hobbs December

10
" 모든 정수에 균일 한 분포 "를 생성하는 솔루션 은 불가능합니다. 무한정의 정수가 많으므로 각 개별 정수는 확률이 0으로 나타납니다. (또는 유한 수를 출력하면 무한정 많은 것을 무시한다는 의미입니다!) P (total ) = 1.
— joeytwiddle

2
@Ypnypn 컴퓨터의 RAM도 제한이 없습니다. 부분 출력을 어디에도 저장할 필요가 없습니다.
— jimmy23013

4
@GiantTree-- 32/64 비트 아치 의 데이터 유형 way too long to fit in an integer을 integer의미 한다고 가정하는 경우에만 해당되며 int, 반드시 유효한 가정은 아닙니다. "정수"는 크기 제약이없는 수학 용어 로 시작되었습니다 .
— 가짜 이름

5
의사 난수 생성기를 사용하여 출력을 결정하는 사람은 거의 모든 정수를 제외하고 생성 할 수있는 정수의 크기에 상한을 설정합니다 (PRNG에 유한 기간이 있다고 가정). 답변에서 이것을 무시할 수 있습니까? 아니면 유효한 답변에 진정한 난수 생성기가 필요합니까?
— trichoplax

답변:


12

CJam, 16 14 13 바이트

0{Kmr(+esmr}g

루프가 종료되어야하는지 여부를 판별 하기 위해 현재 시간 소인 (10 12 )을 사용하므로 매우 오랜 시간 동안 실행 됩니다. 가장 짧기 때문에 이것을 제출물로 사용하고 있지만 두 가지 14 바이트 대안이 있으며 자체 장점이 있습니다.

0{esmr(+esmr}g

이 하나되어 있지 범위 때문에, PRNG의주기에 의해 제한 모든 임의의 숫자가 현재의 타임 스탬프에 따라 달라집니다. 따라서 음수 또는 심지어 작은 양수에 대한 확률은 거의 작지만 숫자를 생성 할 수 있어야합니다.

아래는 3e5타임 스탬프 대신 사용하는 동등한 버전입니다 . 그리고 20첫 번째 범위 (13 바이트 제출). 훨씬 빠르며 모든 규칙을 준수합니다. 합리적인 런타임과 작은 코드 크기를 유지하면서 1,000,000 이상의 숫자에 대해 50 % 확률을 얻는 것은 일종의 제한적인 사례입니다. 설명과 수학적 칭의는이 버전을 참조하십시오.

0{Kmr(+3e5mr}g

실행하는 데 보통 몇 초가 걸립니다. 를 더 빠르게 실행하기 위해 5를 a 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. 따라서 사례의 약 2/3에서 더 많은 117,647 개의 단계를 거치게되며 각 1,000,000 개를 쉽게 수행 할 수 있습니다.

  • (이것은 정확한 확률이 아니라는 점에 유의하십시오. 평균 8.5에 대해서는 약간의 변동이있을 것이지만 50 %에 도달하려면 117,646을 넘어 약 210,000 단계를 거쳐야합니다.)
  • 의심 스러우면 9e9바이트를 추가하지 않고도 (그러나 몇 년의 런타임) 종료 확률의 분모를 쉽게 부 풀릴 수 있습니다 .

... 또는 11 바이트?

마지막으로 11 바이트 버전이 있는데, 이는 PRNG 기간에 의해 제한되지 않지만 매번 메모리가 거의 소모됩니다. 각 반복마다 하나의 난수 (타임 스탬프에 따라)를 생성하고 증가 및 종료에 모두 사용합니다. 각 반복의 결과는 스택에 남아 있으며 끝에서만 요약됩니다. 이 아이디어에 대해 Dennis에게 감사합니다.

{esmr(}h]:+

나는 규칙에 진정한 난수 생성기가 필요한지 확인하기 위해 질문에 의견을 추가했지만, 당신은 pedantry에 감사 할 것이라고 생각합니다. 여기에 무작위 소스가 의사 랜덤입니까? 그러면 가능한 출력 세트의 크기가 최대 PRNG 기간으로 제한됩니다.
— trichoplax

(간단한 우아함에 관계없이 +1)
— trichoplax

예, 지금까지 추측하고 있습니다. 나는 누군가가 그 문제없이 답변을 게시하는지 궁금합니다 ...
— trichoplax

OP가 난수 생성기를 실제 난수 생성기라고 가정 할 수 있다고 말 했으므로 이제 중복됩니다 ... :)
— trichoplax

Kmr기간 의 합계 는 여전히 기간보다 항상 큰 양수일 가능성이 높습니다. 이 경우 가능한 모든 숫자를 생성 할 수는 없습니다.
— jimmy23013

11

자바, 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 %
— 여야합니다.

@Optimizer Redone.
— Ypnypn

이진 리터럴을 사용하는 경우을 인쇄 할 필요가 없습니다 -.
— TheNumberOne

4

매스 매 티카-47

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

기본적으로 1500000과 같은 분산을 갖는 정규 분포를 사용하여 난수를 생성합니다. 이렇게하면 확률이 49.5015 % 인 -10 ^ 6과 10 ^ 6 사이의 정수가 생성됩니다.


"이것은 -10 ^ 6에서 10 ^ 6 사이의 정수를 50.4985 %의 확률로 생성합니다." -충분하지 않습니다. 사양을 잘못 읽었습니까? 아마도 10 ^ 7을 분산으로 사용하려고 했습니까?
— John Dvorak

@JanDvorak 잘못된 가능성, 죄송합니다. 이제는 맞습니다.
— swish

Mathematica에서 이것을 구현하면 모든 정수를 실제로 포함합니까? 나는 소스에 접근 할 수 없지만 추측하지 않을 것입니다 ...
— trichoplax

@githubphagocyte 전류 정밀도에 의존합니다.
— swish

4
내 말은, 특정 정밀도를 지정 하면 그보다 큰 숫자는 제외됩니다. 그것이 작동 할 수있는 유일한 방법은 무제한 정밀도를 지정할 수있는 것입니다.
— trichoplax 2014

4

파이썬 2, 75 69 바이트

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

중간에있는 while 루프가 모든 정수를 생성 할 수 있는지 확인하는 것은 사소한 일입니다 (0쪽으로 바이어스 됨). "10"은 ± 10 6을 초과하는 숫자의 대략 절반이 있도록 선택 됩니다.


이전 솔루션 :

파이썬 2, 44 바이트

Mathematica 솔루션을 기반으로합니다 .

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

파이썬의 float정밀도는 유한 하기 때문에 실제로 작동하지 않습니다 .


의사 난수 생성기는 유한 한 양의 내부 상태를 갖기 때문에 모든 정수를 생성 할 수는 없습니다. 문서에 따르면 Python은 Mersenne Twister를 사용하므로 상태가 상당히 큽니다. 그러나 무한하지 않으므로 모든 정수의 유한 하위 집합 만 생성 할 수 있습니다.
— starblue

@starblue : OP에서 : "언어의 난수 생성기는 그렇지 않은 경우에도 진정한 난수 생성기라고 가정 할 수 있습니다."
— kennytm

3

루비, 70

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

매우 큰 숫자를 생성하기 위해 String람다에서 숫자를 반환합니다 . 이것이 허용되지 않으면 8 문자를 더 세어 (for puts f[]) 함수 대신 프로그램으로 만드십시오.

설명

-1,000,000와 사이의 숫자를 생성하십시오 1,000,000. 숫자가 1크면 숫자가로 반환됩니다 String.

숫자가보다 작 으면 1숫자 범위 밖의 숫자를 반환하기 위해 함수가 재귀 적으로 호출됩니다. 음수도 생성 할 수 있도록 초기 숫자가보다 큰 경우 -결과 앞에 접두사가 붙 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를 임의의 정밀도로 대체합니다.


그래, 내가 사양을 잘못 읽은 것을 깨달았다. 그리고 나는 그것이 같은 티카와 기계 정밀도에 한계가 상상
— shadowtalker을

흠 .. 잘 모르겠어요. 나는 그것을 조사해야 할 것이다. 이 답변을 "보류"상태로 고려하십시오
— shadowtalker

MartinBüttner @ 내가 생각하는 고정
— shadowtalker

흥미 롭군 나는 당신이 전체적인 sample(c(1,-1),1)생각 을 필요로한다고 생각하지 않습니다 . 1e6을 중심으로하는 것만으로도 충분합니다.
— Martin Ender

@ MartinBüttner 아 양쪽 끝이 50 % 일 필요는 없습니까? 명확하지 않다
— shadowtalker

2

펄, 53 자

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

나는 확실히 어떤 이유도 보지 못한다 하나를 인쇄 할 때 정수 작업 :)

앞에 "-"가 있거나없는 숫자를 인쇄 할 확률이 동일합니다.

1 자리 숫자 10 %, 2 자리 숫자 9 %, 3 자리 숫자 8.1 %, 4 자리 숫자 7.29 %, 5 자리 숫자를 인쇄합니다. 시간의 6.56 %, 시간의 6 자리 숫자 5.9 % 등. 확률이 감소함에 따라 모든 길이가 가능합니다. 1 ~ 5 자리 숫자는 출력 사례의 약 41.5 %를 차지하고 1,000,000 (또는 -1,000,000)은 6 백만 퍼센트에 불과하므로 출력 숫자는 -1,000,000-1,000,000 범위에서 약 54.6입니다. % 그 시간의.

"0"과 "-0"은 모두 가능한 출력이므로 문제가되지 않기를 바랍니다.


이 번호는 -00000000167과 같은 "숫자"를 인쇄하지 않습니까? 그것은 실제로 정수가 아닙니다.
— isaacg 2014

1
@isaacg 왜 정수가 아닌지 모르겠습니다.
— Optimizer

2
@Optimizer 그러나 OP는 0을 선행으로 명시 적으로 금지했습니다.
— Martin Ender

루프 앞에 0이 아닌 임의의 선행 숫자를 -9에서 +9까지 생성 할 수 있습니다. print int(rand(20)-10)||1. 그래도 0을 출력으로 생성하는 방법이 필요합니다. 0 이후의 후미 쓰레기가 허용되면 || die 0 일 수 있습니다. 그렇지 않으면 0을 인쇄하고 추가 출력없이 종료하는 짧은 방법이 필요합니다 int(rand(20)-10)==0.
— Peter Cordes

@PeterCordes는 이것이 괜찮은 접근 방법이라고 동의했지만 작성하는 것이 마음에 들지 않으며 길이 방향으로 경쟁 할 것이라고 생각하지 않습니다. 자유롭게 제출하십시오 :)
— hobbs

2

펄, 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 사이의 값을 얻을 확률은 0으로 향하는 경향이 있지만 가능합니다.

참고 :이 서브 루틴은 오랫동안 실행되어 "메모리 부족!"으로 오류가 발생할 수 있습니다. 오류이지만 기술적으로 질문에 명시된 바와 같이 정수를 생성 합니다 .

펄, 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

백만 개의 샘플로 테스트 :

~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를 위반합니다.
— Optimizer

@Optimizer 나에게 정수는 많은 프로그래밍 언어에서와 같이 정의됩니다 : -2^31및 +2^31-1(32 비트) 범위 내의 숫자 . 더 큰 정수를 생성하려는 경우 지수를 쉽게 늘릴 수 있지만 Perl의 구현에 따라 실패 할 수 있습니다.
— GiantTree

방금 엄청나게 큰 정수도 생성해야한다는 것을 알았습니다. 코드를 빠르게 편집하겠습니다.
— GiantTree

@ MartinBüttner 나는 질문의 사양을 충족시키기 위해 최선을 다했습니다. 나에게 (적어도 도움이 없으면) 무한히 큰 정수를 생성하는 것은 불가능합니다. Perl의 가장 큰 정수는 약 1.7e308이며 제어 할 수없는 한계입니다.
— GiantTree

@ MartinBüttner 둘 다 가능하지만 예를 들어. 문자열은 2GB의 데이터 후에 오버플로되어 다시 유한하게 만듭니다. 메모리에 문제가 있으면 숫자가 무한히 커야한다고 말하기는 어렵습니다. BigInts를 사용하여 다른 접근 방식을 곧 제안 할 것입니다. 또한 정수는 1.7e308에서 오버플로되지 않습니다. 단지 infite로 변환됩니다 ( 1.#INF정확히)
— GiantTree

2

씨#, 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입니다.또한 선행 0을 생성하여 원래 질문이나 주석에서 허용되지 않는 것 같습니다.


를 사용할 때 두 번 using System;필요하지 않지만 그렇습니다. System.RandomRandom
— Charlie

@Charlie 이것은 함수이므로 using명령문을 사용할 수 없습니다 . 어쨌든 1 문자 만 저장합니다.
— LegionMammal978

1
에서 공백을 제거하여 1 개의 문자를 저장할 수 있습니다 -1E6, 1E6+1.
— ProgramFOX

2

펄, 62 바이트

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

나는 한 번에 숫자를 생성한다는 @Hobbs와 같은 아이디어를 가지고 있었지만 그의 코드는 0이 아닌 추가 요구 사항을 충족시키지 못했습니다. 부호 대신 첫 번째 숫자를 생성하면 문제가 해결되었습니다. 그리고 0을 인쇄하면 더 짧은 종료 방법이나 선행 -9 ~ 9를 생성하는 더 짧은 방법이 없다면 크기를 지정해야합니다.

쉘 루프에서 : while perl -e '...'; do echo;done |less

나는 이것이 문제를 만족시키기 위해 무한 RAM을 필요로하지 않는 가장 짧은 것 중 하나라고 생각합니다. 보너스로, 출력은 어떤 것에도 치우 치지 않으며 런타임은 매우 빠릅니다.

비트 조건을 사용하고 while 조건에서 문자를 저장하려고 시도했지만 이것이 더 자주 사실이라고 생각하므로 루프가 더 빨리 종료됩니다. abs (output)> 1M 생성 가능성을 유지하기 위해 다른 것들을 조정하려면 더 많은 문자가 필요합니다.


니스, 당신은 내가 생각하지 않았을 것들을 짜서 :)
— hobbs

1

자바 스크립트 (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가 아닌 경우에도 PRNG가 실제로 임의라고 가정 할 수 있음을 확인했습니다.
— trichoplax 2014

1

GolfScript, 20 바이트

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

예, 이것도 느립니다.

CJam 및 Pyth와 같은 언어에 비해 GolfScript는 자세한 난수 생성 키워드 ( rand)로 어려움을 겪고 있습니다 . 이 장애를 극복하기 위해 한 번만 사용할 수있는 방법을 찾아야했습니다.

이 코드는 반복적으로 0 내지 8의 난수를 선택하여 작동 8 -1 = 16,777,215 각각 포함하고, 난수 생성 된 카운터 값이 가지고 0으로 일어날 때까지 카운터를 증분 기하 분포 A의 중앙값을 약 -1 / 로그인 2 (1 − 1/8 8 ) ≈ 11,629,080이므로 "시간의 50 % 이상 1,000,000 이상"테스트를 충족합니다.

아아, 이렇게 생성 된 난수는 항상 엄격하게 양수입니다. 따라서 .2&(*4/음수 또는 0이 되려면 추가 부분이 필요합니다. 그것은 숫자의 두 번째로 낮은 비트 (0 또는 2)를 추출하여 -1 또는 1로 감소시키고 원래 숫자와 곱한 다음 결과를 4로 나눕니다 (제거하려면) 가장 낮은 두 비트, 이제 부호와 상관이 있으며 결과가 0이됩니다). 4로 나눈 후에도 난수의 절대 값은 여전히 ​​-1 / log 2 ( 1-1/ 8 8 ) / 4 ≈ 2,907,270의 중앙값을 가지므로 여전히 50 % 테스트를 통과합니다.


1

자바 스크립트, 81 바이트

이 코드는 모든 규칙을 충족합니다.

  • 양의 확률로 정수를 출력합니다
  • 최소 50 % 확률로 +/- 1000000 범위를 벗어난 정수를 출력합니다
  • 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 %입니다. 나는 단지 시간의 50 % 이상 6 자리 이후에 멈추어야한다.

@nutki의이 방정식은 위 조건을 기반으로 정지 확률 백분율의 최대 값을 설명합니다.

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

따라서 0.1은 문제의 세 가지 규칙을 모두 만족시키는 범위 내에 있습니다.


이 답변에 대해 나를 혼란스럽게하는 몇 가지가 있습니다. 스펙에 따르면 구현에 따라 달라 지므로 Math.random ()은 임의의 숫자로 구성된 균일 한 분포를 생성한다고 가정 했습니까? 분포가 균일하다고 가정하면 P (Math.random ()> 0.1) = 0.9이므로 각 반복 사이에 종료 될 확률이 큽니다. 파이어 폭스 34.0 우분투 알고리즘 실행의 구현은 나에게 ~ 0.47 (<0.5) 나는 그것을 테스트마다의 확률을 제공합니다 jsfiddle.net/WK_of_Angmar/dh8gq4pb
— Wk_of_Angmar에게

또한 입력없이 알고리즘의 시간 복잡성을 어떻게 계산 했습니까?
— Wk_of_Angmar

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"를 생성 할 수 있습니까?
— kennytm


1
OK 코드를 잘못 읽습니다 :. 그러나 20 자리 이상의 숫자를 생성 할 수 있습니까?
— kennytm

출력으로 임의의 긴 정수가 가능합니까? 이 범위에 의해 제한되지 randNorm않습니까?
— Optimizer

"분포는 제한이 없으므로 이론적으로는 정수를 생성 할 수 있습니다." 범위가 없습니다.
— Timtech

1

배쉬, 66

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

거의 항상 5000000을 인쇄합니다. 그러나 유효한 숫자를 찾으면 /dev/random, it will print that number instead.

그리고 이것은 더 빠릅니다.

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

1
@Optimizer It is supposed to be slow. That's because it is a real random source. But you can test it with /dev/urandom which is less random.
— jimmy23013

@Optimizer How would that be taking manual input? It's reading a file, but everything's a file.
— Nit

@Optimizer I simply don't understand the point you're going for.
— Nit

/dev/urandom쉘 스크립트에서 읽는 것은 기본적으로 rand()다른 언어 로 호출하는 것과 같습니다 . POSIX sh가 아닌 bash를 실제로 사용하고 있지만에서 임의의 숫자를 얻을 수 있습니다 echo $RANDOM. wiki.ubuntu.com/DashAsBinSh 는 hexdump /dev/urandombare-POSIX-minimum과 동등한 것으로 제공합니다 /bin/dash.
— Peter Cordes

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] 간격에서 시작하고 첫 번째 숫자가 0이면 함수는 선행 0을 피하기 위해 종료해야합니다). d의 값을 d = rand () % 10으로 지정할 수 있지만 첫 번째 숫자는 음수 일 수 없습니다. d는 대신 d = (rand () % 19 + d + 9) % 10으로 할당되고 -18에서 초기화되므로 d의 첫 번째 값의 범위는 [-9, 9]이며 다음 값의 범위는 항상 [0 , 9].

변수 s의 범위는 [0, 9]에서 무작위로되며, s가 9와 같으면 함수가 종료되므로 첫 번째 숫자를 인쇄 한 후 다음 숫자는 90 %의 확률로 인쇄됩니다 (rand ()가 실제로 임의라고 가정하고, 세 번째 조건을 충족시키기 위해). s를 s = rand () % 10으로 쉽게 지정할 수 있지만 예외는 있지만 첫 번째 숫자가 0이면 함수가 종료되어야합니다. 이러한 예외를 처리하기 위해 s는 s = 9-rand () % 10 * min (d * d + s + 1,1)로 지정되었고 -1로 초기화되었습니다. 첫 번째 숫자가 0이면 최소값은 0을 반환하고 s는 9-0 = 9와 같습니다. 변수의 할당 범위는 항상 [0, 9]의 범위이므로 첫 번째 숫자에서만 예외가 발생할 수 있습니다.

특징 (rand ()가 실제로 무작위라고 가정)

  • 정수는 한 자릿수로 인쇄되며 마지막 숫자를 인쇄 한 후 다른 숫자를 인쇄 할 확률은 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은 두 가지 사실에서 파생됩니다. y, 시퀀스에서 호출 될 때 검정력 함수이며 입력의 모든 하위 집합 목록을 구성합니다. 입력 G은 26 자 길이이므로이 전원 세트 yG에는 2 ^ 26 개의 항목이 있습니다. OyG2 ^ 26 항목에서 임의의 요소를 선택합니다. 해당 항목 중 하나 인 빈 문자열은 전달 될 때 잘못된 것으로 평가됩니다.W 은 while 루프로 . 따라서 매번 루프를 종료 할 확률은 2 ^ -26입니다.

고정 된 수의 루프 사이클 K에서, K * 3.5 + m의 숫자를 얻을 확률과 K * 3.5-m의 확률은 동일하다. 왜냐하면 하나의 총합을 달성하는 각각의 덧셈 시퀀스는 역전 될 수 있기 때문이다. -1-> 8, 0 -> 7, 등을 달성하십시오. 또한, K * 3.5에 가까운 숫자는 더 먼 숫자보다 명확합니다. 따라서 K> 2000000 / 3.5 = 571428.5 인 경우 1000000을 초과하는 숫자를 얻을 확률은 75 %보다 큽니다. 해당 숫자 이상의 결과 중 일부는 아래의 모든 결과와 일대일로 대응할 수 있기 때문입니다. 숫자와 1/2보다 작은 상위는 1000000 미만의 숫자와 일대일로 대응할 수 있습니다. 571429 개 이상의 루프를 얻을 확률은 (1-2 ^ -26) ^ 571429입니다. (1-2 ^ -26 * 571429) 미만, 처음 571429 회 시도에서 루프를 벗어나는 예상 횟수는 99.1 %입니다. 따라서 99.1 % 이상의 시도에서 1000000 이상을 얻을 확률이 75 % 이상이므로 1000000 이상을 얻을 확률이 50 % 이상입니다.

This code relies on a behavior of O where a bug was accidentally introduced 3 days ago and was fixed today. It should work on any version of Pyth 3 from before Dec 22nd, or after today. The following code is equivalent, and has always worked:

WOyG~ZtOUT)Z

What happened to the online compiler ?
— Optimizer

@Optimizer Issues with the website, I'll work on it.
— isaacg

Ah.. cool. Wanted to work on the Pyth translation of my CJam answer yesterday and found that it gives 404.
— Optimizer

0

Java, 113 bytes

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

This program prints a binary number to standard output stream. You might have to wait a while because the probability of it ending the number (or it being positive) is approximately 0. The idea that the absolute value of a number generated is less than 1 million is amusing, yet possible.

Ungolfed:

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
}

Sample output: Will post when a number is done being generated.


0

Java (JDK), 140 127 bytes

()->{int i;var o=System.out;for(o.print(i=(int)(19*Math.random())-10);i!=0&Math.random()<.9;)o.print((int)(11*Math.random()));}

-13 bytes by sneaking more logic into the loop header - thanks to @ceilingcat

Try it online!

당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.