일정한 랜덤 소스를 사용하여 0에서 n 사이의 난수를 선택하십시오.


26

태스크

원하는 방식으로 입력으로 지정된 n양보다 작은 양의 정수가 주어지면 2^30코드는 0및 사이의 임의의 정수를 출력해야 n합니다. 생성하는 숫자 는 무작위로 균일하게 선택해야합니다 . 즉, 각 값 0n동일한 확률로 발생한다 (규칙 및주의 사항 참조).

규칙과주의 사항

귀하의 코드는 귀하의 언어 또는 표준 라이브러리에 내장 된 임의의 난수 생성기가 균일하게 임의라고 가정 할 수 있습니다. 즉, 사용중인 임의 소스의 품질에 대해 걱정할 필요가 없습니다. 하나,

  • 사용하는 임의의 소스가 균일하면 코드가에서 0로 균일 한 임의의 정수를 올바르게 출력하도록 설정 해야 n합니다.
  • 내장 또는 라이브러리 임의 함수를 호출 할 때 모든 인수는 일정해야합니다. 즉, 입력 값과 완전히 독립적이어야합니다.
  • 귀하의 코드는 종료 가 보장되지 않고 확률 1로 종료 될 수 있습니다 .

노트

  • randInt(0,n) 입력을 내장 또는 라이브러리 함수의 인수로 사용하므로 유효하지 않습니다.
  • rand()%n것입니다 하지 일반적으로 균일 난수를 제공합니다. betseg에 의해 주어진 예를 들어, 경우 intmax == 15n = 10, 당신은 얻을 훨씬 더 가능성이있을 것 0-5보다 6-10.
  • floor(randomfloat()*(n+1)) 또한 0과 1 사이의 다른 가능한 부동 소수점 값의 유한 수로 인해 일반적으로 균일 한 난수를 제공하지 않습니다.

출력이 균일하게 무작위임을 어떻게 확인합니까? 주어진 언어 / 라이브러리는 균일 한 난수를 출력하지만 조작은 불균일 한 출력을 초래할 수 있습니다. (예 : - , 기능을 rng()제공 하면 0-25가 더 일반적입니다.)0100n = 75rng()%75
Baldrickk

1
@Baldrickk 군중의 지혜로 :) 우리는 코드를 읽고 그것에 대해서만 생각할 수 있습니다.

가장 간단한 가능한 확률 이론적 질문을하는 슬픈 결론 : 무작위성과 확률은 매우 잘 이해되지 않습니다. : ((그리고 규칙을 읽는 것은 어렵습니다.)
Martin Ender

이것은 마음에 오는 : 난수를
BgrWorker

세 개의 짧은 답변이 있는데 왜 x86 답변을 수락 했습니까?
Dennis

답변:


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은 인텔에서 설명합니다

RDRAND암호로 안전한 결정 성 임의 비트 생성기 DRBG에서 제공하는 난수를 반환합니다. DRBG는 NIST SP 800-90A 표준 을 충족하도록 설계되었습니다 .

CSRNG를 다루는 것은 NIST SP 800-90A를 인용하여 분포가 균일하다는 것을 암시합니다.

난수는 편향되지 않은 난수 변수, 즉 균일하게 분포 된 난수 처리에 의해 생성 된 결과 입니다.


프로시 저는 난수를 생성하며 입력보다 엄격하지 않으면 리턴됩니다.
그렇지 않으면 프로세스가 반복됩니다.

eax32 비트 이므로 rdrand0과 2 32 -1 사이의 숫자를 반환 하므로 [0, 2 32 -1]의 모든 n 에 대해 예상되는 반복 횟수는 2 32 / (n + 1)이며 모든 n에 대해 정의됩니다. [0, 2 30 ).


훌륭하게 낮은 수준. 고맙습니다.

무엇입니까 jnc?
l4m2

@ l4m2 rdrandCF반환 된 데이터가 유효한 iif를 설정 합니다. 너무 많은 요청이 엔트로피 풀을 비워서 데이터가 유효하지 않을 수 있습니다. rdrandthis에 대한 수동 항목을 참조하십시오 .
마가렛 블룸

20

젤리 , 7 6 바이트

⁴!!X%‘

1 바이트를 골프로 해준 @JonathanAllan에게 감사합니다!

(16!) 때문에 TIO에서 실행할 수 없습니다 ! A는 거대한 수.

작동 원리

⁴!!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

죄송합니다. 게시하기 전에 보지 않았습니다.
Dennis

상관 없습니다. 어쨌든 고칠 계획은 없었습니다. 젤리와 함께 놀기에는 너무 불편합니다.
orlp

1
"여러분이 왜 화가 났는지 모르겠습니다. 알고리즘은 일정한 시간입니다. 좋은 일입니다. 보안과 HR이 왜 문 밖에 있습니까?"
corsiKa

1
동의했다. 8 자리 숫자와 417 개의 quintillion 숫자 숫자의 차이 : p
Jonathan Allan

11

매스 매 티카, 29 바이트

Dennis의 Jelly 답변을 기반으로 합니다.

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

실제로 이것을 실행하지 않는 것이 좋습니다. 2e9!꽤 큰 숫자입니다 ...

가능한 모든 입력으로 나눌 수있는 거대한 수를 생성하고 간단한 모듈러스를 사용하여 필요한 범위로 결과를 매핑하는 것이 가장 짧습니다.

거부 샘플링, 34 바이트

다소 흥미로운 코드로 이어진 나의 오래된 접근법 :

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

기본 거부 샘플링. 출력을 13으로 초기화합니다 ! (최대 입력 2 30 보다 큼 ) 그리고 013 사이의 임의의 정수로 반복해서 대체하십시오 ! 값이 입력보다 큰 한.


1
"입력보다 작거나 같다"는 뜻입니까?

1
@Lembik 아니요. 원하는 범위에 속하지 않는 한 값을 재생성하려고합니다.
Martin Ender

아 알 겠어요 어떤 이유로 나는 우리가 원하는 범위에서 반복적으로 샘플링하고 있다고 생각했습니다. 감사.

1
다음에 시간 제한을 추가하도록 상기시켜주십시오. :)


7

프롤로그 (SWI) , 38 바이트

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

거부 샘플링으로 작동합니다.

입력 값보다 작거나 같은 것을 찾을 때까지 02 ^ 31-1 = 2147483647 사이의 난수를 생성하십시오 .

다른 것 대신 컷을 사용해야 할 것 같은 느낌이 들지만 어떻게 볼 수 없습니다.


1
else를 사용하여 피할 수는 repeat있지만 3 바이트 더 길어집니다 ... 반복보다 무한한 선택 포인트를 갖는 짧은 방법이 있는지 확실하지 않습니다.
Fatalize

@ Fatalize : 그래 나는 반복을 시도했다. ,!.역 추적을 강요하는 것과 같은 것을 사용 하는 기억이 있었지만 잘못 기억 하거나이 솔루션에 적용되지 않습니다.
Emigna

7

미로 , 63 바이트

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

(여기서 무거운 골프에 도움을 주신 @MartinEnder에게 감사합니다.)

Labyrinth는 2D 언어이며 유일한 무작위 소스는 다음과 같은 상황에 있습니다.

   x
  "<)
 " "
 " "

지시 포인터가 위에 있고 x아래쪽으로 이동 한다고 가정하십시오 . 그런 다음 <스택 상단에 0이 있으면 (위의 실제 프로그램에서 항상 그러함) 현재 행을 왼쪽으로 1만큼 이동합니다.

   "
 "<)
 " "
 " "

지시 포인터가 이제 <아래쪽으로 이동합니다. 정션에서 Labyrinth는 스택 상단을 기준으로 회전합니다. 음수는 왼쪽으로, 양수는 오른쪽으로, 0은 앞으로 이동합니다. 이 시점에서 스택 상단이 여전히 0이면 경로가 없기 때문에 앞뒤로 이동할 수 없으므로 Labyrinth는 왼쪽 또는 오른쪽으로 같은 확률로 우회전합니다.

본질적으로 위의 프로그램은 임의성 기능을 사용하여 100 비트 숫자 ( #00여기에서 100으로 지정 )를 생성하고 숫자를 생성 할 때까지 계속 반복합니다 <= n.

테스트를 위해서는 아마도 #0"10 비트 숫자 대신 사용하는 것이 도움이 될 것입니다 ". 온라인으로 사용해보십시오!

대략적인 설명 :

 ?            <--- ? 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

파이썬, 61 바이트

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

편집 : 금지 된 양식을 피하기 위해 업데이트되었습니다.

EDIT2 : 저장된 2 바이트, 감사 @ JonathanAllan

Edit3 : 완전한 기능을 갖춘 솔루션을 위해 2 바이트를 지불했습니다-다시 감사합니다 @JonathanAllan

편집 4 : 제거 f=되어 2 바이트 저장

Edit5 : @ JonathanAllan 덕분에 1 바이트 더 절약되었습니다.

Edit6 : @ JonathanAllan 덕분에 2 바이트 더 절약

지금까지 git blame은 나에게 나쁜 것들을 지적하고 JonathanAllan은 도움이되는 것들을 지적 할 것입니다.

Edit7 : 비가 오면 쏟아져-2 바이트

Edit8 : 그리고 다른 2 바이트


1
이것은 절대 출력 n되지 않지만을 사용 from random import*하여 삭제 하면 2 바이트를 절약 할 수 있습니다 r..
Jonathan Allan

1
예, 그렇지 않으면 필요한 괄호를 피하기 때문에하는 "올챙이 연산자"를 사용할 수 있습니다 ...*(-~n*1.0/2**30))보다는...*((n+1)*1.0/2**30))
조나단 앨런

1
정말? 단! 숫자 70에 대한 오랜 원한이 있습니까? 도와 주셔서 감사합니다
iwaseatenbyagrue

1
실제로 randrangefloat를 받아들이는 것처럼 보이므로 lambda n,x=2.**30:int(randrange(x)*-~n/x)다른 두 [edit ...]을 저장합니다.
Jonathan Allan

1
^ 괄호 제거와 함께 거기에 또 다른 두. 당신의 곱셈이가는 길임을 보여주기 위해갑니다!
Jonathan Allan

6

파이썬 2 , 61 바이트

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

이 의사 - 랜덤 선택의 정수 0K를 모든 값 K02 31 - 2 , 그 다음에 대응하는 소요 정수 (k)를 N = .


5

배치, 64 바이트

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

%random%15 비트의 난수 만 제공하므로 두 개의 난수를 결합해야합니다. 임의의 값이 원하는 범위 내에있을 때까지 반복되므로 낮을 때는 느립니다 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 나는 당신의 삭제 된 질문에 갈 준비가되었습니다 ...
Neil

이것은 원하는 숫자를 먼저 반향하지 않고 다른 모든 숫자는 n?
Outgolfer Erik

@EriktheOutgolfer 아니오; 을 사용하지 않으면 call배치 스크립트를 호출하면 현재 스크립트가 종료됩니다.
Neil

5

MATL , 12 바이트

TIO 캐시를 비활성화하는 방법을 알려 주신 @AdmBorkBork@Suever 에게 감사드립니다 .

`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

자바 스크립트 (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의 거듭 제곱을 곱한 Math.random()후에도 반환 된 IEEE 754 float 값 은 이러한 간격 동안 균일합니다.

이 가설을 확인하거나 반박 할 수있는 사람은 의견에 알려주십시오.

데모

[0 ... 2] 에서 백만 개의 값을 생성 하고 결과 통계를 표시합니다.


Math.floor (Math.random () * (n + 1))은 나에게 덜 균일하게 분포 된 결과를 생성하므로 분포에 이상이있는 현실적인 N <2 ^ 30이 있는지 확인하는 것이 좋습니다 조금도.
zeppelin

1
@zeppelin이 범위의 임의의 부동 소수점은 2 ^ 53 값 중 하나를 가지므로 2 ^ 30 결과에 가능한 한 균등하게 분배되기 때문에 모든 이상을 찾아 내기 위해 너무 많은 시험 실행이 필요합니다. 따라서 범위 내에서 많은 수의 경우에도 오류는 2 ^ 23의 1과 같으며 엄청나게 많은 시도가 필요합니다. 초기 샘플 수 (2 ^ 53)보다 몇 배 더 큰 크기를 원할 것입니다. 그럼에도 불구하고 승수가 샘플 수를 균등하게 나누지 않으면 Arnauld가 2의 거듭 제곱을 사용하는 경우 완벽하게 균일 할 수 없습니다.
Martin Ender

4

배쉬 (+ coreutils), 44 바이트

/ dev / urandom 기반 솔루션

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

에서 부호없는 32 비트 정수를 읽고 주어진 범위 내 에서 정수를 찾을 때까지 /dev/urandom걸러 내고 파이프를 중단합니다.awksed q


bash 용 Hooray :)

4

하스켈, 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양수 (또는 0)로 설정 하려면 음화를 사용해야합니다 . 터무니없이 크지 않은 n 값에 대해서는 매우 느립니다. 편집 : 나중에 0을 사용할 확률이 다른 숫자보다 사용하기 때문에이 버전이 균일하게 배포되지 않는다는 것을 나중에 깨달았습니다 abs. m생성기가 생성 할 수 있는 숫자를 생성 m하거나 -m0의 경우 0 만 작동하므로 확률은 다른 숫자의 절반입니다.


하스켈을위한 만세 (너무)!

4

젤리 , 9 바이트

⁴!Ẋ’>Ðḟ⁸Ṫ

온라인으로 사용해보십시오! -위의 코드는 크기 16의 범위 이후 TIO에서 실행되지 않습니다! 먼저 작성해야합니다 (그런 다음 섞고 필터링해야한다는 사실은 말할 것도 없습니다). 이것은 훨씬 작은 규모로 똑같은 것입니다 .3의 입력에 대해 10의 경계를 가진 30 번 반복됩니다.

방법?

⁴!Ẋ’>Ðḟ⁸Ṫ - 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으로 반환하고 반환 하는 것을 수행 하면 동일한 바이트 수에 대해 천 시간이 더 효율적 일 것입니다.하지만 문자 그대로 10으로 평가되지 않기 때문에 그렇지 않습니다. 숫자 리터럴에 의해 ȷ...두 개의 별도 리터럴이 구문 분석되며, ȷ기본 지수는 3이며 천은 10 이며 항복은 10입니다.


허, 9 자이지만 22 바이트
Kristoffer Sall-Storgaard

@ KristofferSall-Storgaard 각 문자는 Jelly의 코드 페이지 에서 256 바이트 중 하나입니다 . 나는 평소처럼 링크를 단어 바이트로 만드는 것을 잊었습니다.
Jonathan Allan

1
년, 나는 그것을 찾아 같은 것을 발견
크리스토퍼 Sall-Storgaard

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 바이트 : 감사합니다 Jakob!
  • jshell이 ​​유효한 런타임 환경이라고 가정합니다.
  • 런타임 환경으로서 jshell 자체는 핵심 라이브러리에 대한 명시적인 가져 오기가 필요하지 않으며 세미콜론이 필요하지 않습니다.
  • 을 반환합니다 OptionalInt. 규칙은 리턴 유형이 기본이어야한다고 지정하지 않으며 OptionalInt결과의 올바른 표현을 고려 하고 있습니다.

1
영감을 주신 @ kevin-cruijssen에게 감사합니다. 내 첫 번째 코드 골프!
Pete Terlep

박스 출력의 승인 여부 Optional는의 승인 여부와 다릅니다 . 내가 너라면 포스터로 확인하겠다. 또한 전체 과제를 세지 않아도됩니다. 람다 식이면 충분합니다.
Jakob

1
람다 매개 변수 n와로 괄호를 제거하여 4 바이트를 절약 할 수 있습니다 new Random().
Jakob

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.

평균을위한 더 빠른 방법 N( 46 바이트 ) :

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은 약 필요합니다. 백만 번 8 초

19 바이트에 대한 잘못된 솔루션 :

echo rand(0,$argn);

3

PowerShell , 35 바이트

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

온라인으로 사용해보십시오!

또 다른 거부 샘플링 방법. 이것은 무한 for의 값을 설정하는 루프 $aRandom정수 사이 01gb( = 1073741824 = 2^30) 등이 긴 정수로 반복 계속 -greater t한 입력 $args. 루프가 완료되면 $a파이프 라인을 씌우고 출력은 암시 적입니다.

참고 : 입력이 작은 경우 시간 이 오래 걸립니다.


3

파이썬 2 , 72 69 바이트

xnor 덕분에 -3 바이트 ( id내장 변수를 재정의 )

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

온라인으로 사용해보십시오!

randrange(2**30)의사 - 균일하게 분포 된 수 (메르 센 트위스터 생산 2 19937-1를 범위에서) [0,2 30 ) . 2 30n 미만으로 보장 되므로 입력보다 크지 않을 때까지 간단히 반복해서 호출 할 수 있습니다. 값이 매우 낮은 경우 예상 시간이 오래 걸리지 만 입력이 50 인 경우에도 1 분 이내에 작동합니다.n


2
r=''"무한대"로 초기화 할 수 있습니다 . 또는 더 나은 아직 초기화하지 않고에 대한 모든 곳에서 r사용하십시오 . idr
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까지 나열하고 무작위로 선택합니다. 모듈로 입력. 당신이 가진 효율성을 절대적으로 망칠 것입니다.
Magic Octopus Urn

I올바른 순서로 (그리고 Ý대신에 L) 모듈러스에 대한 인수를 얻으려면 거기에 7 바이트가 필요 하지만 그렇지 않으면 분명히 더 짧은 해결책입니다. 나는 그의 젤리 답변에서 Dennis가 그 일을하는 것을 보았습니다. 그 접근 방식이 이것과 다르기 때문에 별도의 답변으로 게시 할 수 있습니다.
Emigna

DI‹Ï루프를 피하십시오.
Magic Octopus Urn 17

또한, 이것은 그대로 종료되지 않을 수도 있습니다. 내가 실수하지 않으면 0거의 항상 무한 루프가 발생하여 종료하기가 어렵습니다. 솔루션이 모든 시나리오에서 종료 될 가능성을 허용하지만 임의성으로 인해 보장되지는 않습니다.
Magic Octopus Urn 17

@carusocomputing : 매우 작은 입력의 경우 두 번째 버전은 평균적으로 예를 마치는 데 시간이 오래 걸리지 만 시간이 충분합니다.
Emigna

2

파이썬 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

자바 8, 84 83 80 71 62 바이트

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

@ OliverGrégoire 덕분에 -1 바이트 . @Jakob
덕분에 -3 바이트 . -9 바이트는 Java 7을 Java 8 로 변환 합니다 .

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 나는 이것에 대해서도 의문을 제기했지만 두 번째 글 머리 기호를 참조하십시오. "내장 또는 라이브러리 임의 함수를 호출 할 때의 모든 인수는 일정해야합니다. 즉, 입력 값과 완전히 독립적이어야합니다." 이것이 max int가 사용되는 이유입니다.
Poke

1
2^30= 1073741824. -1>>>1(= 2147483647) 를 사용하는 것이 좋습니다 . 그러나 이것은 존재 1<<30합니다 2^30. 1 바이트 더 짧습니다.
Olivier Grégoire

1
어때요 int c(int n){int r;for(;(r=new java.util.Random().nextInt(1<<30))>n;);return r;}?
Jakob

@Jakob 감사합니다. 7 대신 Java 8을 사용하고 대신을 사용하여 18 바이트를 더 줄 Math.random()였습니다 java.util.Random().nextInt.
Kevin Cruijssen

2

파이썬 3, 51 바이트

정통 무작위 소스가있는 파이썬 솔루션입니다.

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

집합을 가져 와서 목록으로 변환하고 첫 번째 항목을 가져옵니다.

파이썬 3에서는 PYTHONHASHSEED에set() 의해 순서 가 설정 되기 때문에 작동합니다 ( 구할 수는 없지만 스크립트 실행시 설정 됨).

분명히, 나는 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

배쉬 + 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
이것은 입력을 난수 생성기에 대한 인수로 제공하지 않습니까?
Martin Ender 2012

이것이 유효하지 않더라도 다른 bash 답변을 제출하십시오!

@MartinEnder는 직접 입력 된 것이 아니라 입력을 사용하여 생성 된 정수 범위의 상한을 정의합니다 jot will arrange for all the values in the range to appear in the output with an equal probability(아마 경계선 일지 모르지만 여전히).
zeppelin 's

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 하기 전에 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

@ATaco : 통역사 , 코드 페이지 : CP-437
Emigna


1

골랑, 84 78 71 바이트

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

간단한 거부 샘플링.

참고 : math / rand seed는 상수 1이므로 상수 결과를 원하지 않는 한 호출자는 seed해야합니다.

테스트 : 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 비트로 보장됩니다
크리스토퍼 Sall이-Storgaard을

:=다른 3 바이트에 대한 구문 사용
Kristoffer Sall-Storgaard

int32 대신 int를 사용하면 Int31 ()-3 * int + () = 11 바이트와 2 * int32 = 10 바이트의 결과를 캐스트해야하므로 바이트가 절약되지 않습니다.
Riking

1
캐스팅 할 필요가 없으며 Int()랜드 패키지에 기능이 있습니다. 또한 공간을 제거 할 수 있습니다.import
Kristoffer Sall-Storgaard
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.