랜덤 생성기 변경으로 인한 주사위


10

소개

다음과 같은 구현으로 임의의 정수 생성기가 제공됩니다.

  • 첫 번째 호출은 항상 1을 반환합니다.
  • 두 번째 호출은 1과 2 사이의 임의의 정수를 반환합니다.
  • 세 번째 호출은 1과 3 사이의 임의의 정수를 반환합니다.
  • n 번째 호출은 1과 n 사이의 임의의 정수를 리턴합니다.

위의 함수를 기반으로 완벽하게 무작위 인 임의의 주사위 생성기를 작성하여 동일한 확률로 1과 6 사이의 값을 반환합니다.

규칙

  • 프로그램 / 함수는 1에서 6 사이의 임의의 정수를 포함하여 사용 가능한 형태로, 즉 표준 출력 또는 함수 반환 값으로 사용해야합니다.
  • 위의 오름차순 난수 생성기는 프로그램에서 "자유로운"기능으로 정의되거나 (즉, 문자 수에 포함되지 않음) 상태 ( n)가 지속적 이라고 가정하고 필요에 따라 실행되는 별도의 스크립트 / 프로그램으로 정의 될 수 있습니다. 통화 사이.
  • 프로그램의 단일 사용 사례에서 1000 개 이하의 주사위 롤이 요청되지 않고 1000 주사위 롤 1끝에서 초기 난수 생성기를 재설정하여 오버플로를 피할 수 있다고 가정 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불법입니까 아니면 작동하지 않습니까? 세 번째 규칙을 오해하고있을 수 있습니다.
beary605

@ beary605 : 난수 생성기는 모든 주사위 롤 사이가 아니라 1000 개의 주사위 롤 전체 후에 만 ​​재설정 할 수 있습니다. 내가 언급 한 유일한 이유는 난수 생성기에서 반환 된 값의 오버플로를 처리한다는 것이이 과제의 관심사 가 아닙니다 . 편집 : 나는 규칙의 목적을 분명히 밝히고 도움이되기를 바랍니다.
mellamokb

"무작위 숫자"라고 할 때 "무작위 정수"또는 "무작위 (잘린) 실수"를 의미합니까? 아마도 내가 모르는 몇 가지 규칙이있을 것입니다.
DavidC

@DavidCarraher : 아주 좋은 지적입니다. 나는 임의의 정수를 의미했고, 그것이 명확하지 않다는 것을 알았습니다. 질문을 업데이트하겠습니다. 편집 : 업데이트되었습니다.
mellamokb

1
우리는 randomizer에게 random number를 생성 한 횟수를 물어볼 수 있습니까? 나는 우리가 할 수 없다는 인상을 받았습니다.
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}, stdin 버전 (10 문자) r'1+!. 0:` , 함수 버전 (14 문자)이 c:0;f:{r@c+:1}호출했습니다 f[].
algorithmshark

6

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

스칼라 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 개 값에 대해 동일한 분포를 생성해야합니다.


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의 거듭 제곱의 배수 일 때 적합한 엔트로피를 추출하는 사소한 접근 방식은 가능한 모드 3의 결과 수가 333 + 111 + 37 + 12 + 4 + 1 = 498이기 때문에 매우 짧습니다. 샘플 앤 리 젝트 방법을 사용하십시오. 이 방법을 사용하면에 대한 1000 번의 호출에서 2242 개의 예상 롤을 얻을 수 r있지만 부기 에는 추가 오버 헤드 base가 있으며 매우 긴 함수 이름입니다.


5
" base매우 긴 함수 이름" Mathematica를 사용하지 않는 것 같습니다 . 우리는 같은 놀라운 얻을 NegativeBinomialDistribution, ExponentialGeneratingFunction, MathieuCharacteristicExponent, InverseFourierSequenceTransform,와 SemialgebraicComponentInstances. :-)
Mr.Wizard

1

파이썬 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전에 한 번만 호출 하면 while어떨까요?
Keith Randall

@KeithRandall 주사위 롤로 반환하는 숫자는 오름차순 생성기가 반환하는 숫자의 마지막 숫자입니다. 가능한 모든 숫자에 대해 동일한 확률을 보장하기 위해 오름차순 생성기를 10 번 호출해야합니다.
Matt

왜 10 번 전화를합니까? 원칙적으로, 생성기가 무작위 인 경우, 각 통화가 10 자리 숫자에 대해 동일한 확률을 제공하지 않아야합니까? 물론 실제로는 각 숫자에 대해 동일한 수에만 접근 할 것으로 예상 할 수 있습니다.
DavidC

@DavidCarraher 생성기는 1에서 n까지의 난수를 반환합니다. 여기서 n은 호출 한 횟수입니다. 이 반환 된 숫자의 마지막 숫자를보고 있습니다. n이 10의 정수 배가 아닌 경우 확률은 일정하지 않습니다. 예를 들어, n = 13 인 경우 확률은 다음과 같이 분류됩니다. 롤 1,5,6의 경우 1/9 및 롤 2,3,4의 경우 2/9
Matt

@ 매트 : R()부동 소수점을 반환하고 가장 중요하지 않은 숫자를 잡는 것으로 가정했습니다 . 이제 R()정수 를 반환하는 것이 명확 해 졌으므로 의미가 있습니다.
Keith Randall

1

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

나는하지만 가능한 출력으로 7을 생산할 것입니다.
scleaver

오 예. 나는 그것을 놓쳤다.
Matt

mellamokb는 상승하는 랜덤 라이저에 대한 질문을 분명히했습니다. n을 요청할 수 없습니다.
Matt

1

매스 매 티카 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 번의 호출이 필요했습니다 h. Tally숫자 1-6으로 분류를 보여줍니다.

60031

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


1

펄, 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 숫자 chisquare
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과 570.432735 초에 60000042 전화를 걸었습니다.


0

x86 opcode, 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(-

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

생성기를 한 번 팝한 다음 결과를 제거합니다. 그런 다음 f2를 굴려서 3 (3 또는 6)을 곱한 다음 f3-1 (0, 1, 2)을 빼서 (3-2, 3-1, 3-0) 또는 (6-2, 6-1, 6-0) W5.

이 질문이 게시되기 전에 골프 스크립트와 임의의 기능이 존재했기 때문에 합법적 인 제출물도 있습니다.

이것은 한 번만 실행 제출입니다. 한 번의 호출로 여러 번 실행해야하는 경우

GolfScript , 12 바이트

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

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

i 호출을 0으로 재설정하므로 그에 따라 재설정됩니다. 이 TIO는 50 개의 임의 결과를 보여줍니다.


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