깨진 임의 함수 수정


18

친구는 컴퓨터에 추가 카드가있어 1에서 5까지의 임의의 숫자를 생성합니다. 불행히도, 그들은 어떻게 든 그것에 콜라를 쏟았고 이제는 1에서 4까지의 모든 숫자에 대해 2를 생성합니다. 운 좋게도 무작위성은 유지되지만 2는 80 %의 확률을 가지며 5는 20 %의 확률을 가지지 않습니다. 1, 3 또는 4가 생성됩니다. 이 임의의 소스를 사용하여 ( BrokenRand()또는 이와 유사한 것으로 부르기 ) 원래의 소스와 동일한 완벽한 임의성으로 20 % 확률로 각각 1에서 5까지의 숫자를 생성하는 작동하는 난수 생성기를 작성하십시오.

최단 프로그램이 이깁니다. BrokenRand인구 통계적으로 선택된 고객 서비스 포커스 컨설팅에 의해 공평하게 전화를 걸 때 보너스 포인트가 적립 됩니다. 나이와 성별, 즉 나로 분류됩니다.

답변:


10

자바 스크립트-69 자

이것은 von Neumann 추출기 를 사용하여 바이어스되지 않은 비트를 생성합니다. 일반적인 알고리즘은 HotBits 웹 사이트 에서도 설명합니다 . 0에서 7까지의 숫자를 형성하는 데 3 비트가 사용됩니다. 5 이상의 숫자는 모두 버려지고 나머지는 인쇄되기 전에 1이 추가됩니다. 나는 이것이 매우 치우 치지 않음을 보여주기 위해 시뮬레이션을 만들었다 .

r()RNG에 액세스하려면 고유 한 기능을 제공해야합니다 .

 for(;;v<5&&alert(v+1))for(v=i=0;i<3;a-b&&(v*=2,v+=a<b,i++))b=r(a=r())

이것은 정말 잘되었습니다! 증분 값을 단락시키는 방법이 마음에 듭니다.
snmcdonald

BrokenRand에 대한 호출을 줄이기 위해 7 비트를 생성하고 3 개의 임의의 숫자를 추출 할 수 있지만 스트로크가 약간 더 소요될 수 있습니다.
gnibbler

5

스칼라 79 자 :

// preparation: 
val r = util.Random 
def defektRNG = if (r.nextInt (5) == 0) 5 else 2 

(1 to 20).foreach (_ => print (" " + defektRNG))
// first impression:
// 2 2 2 2 2 2 2 5 2 2 5 2 2 2 5 2 2 2 2 2

def rnd : Int = { val k = (1 to 5).map (_ => defektRNG)
  if (k.sum == 13) k.findIndexOf (_ == 5) + 1 else rnd } 

// first impression:
(1 to 20).foreach (_ => print (" " + rnd))             
// 3 3 2 3 5 2 2 5 1 1 3 4 3 2 5 3 3 1 5 4
// control:
(1 to 50000).map (_ => rnd).groupBy (identity) .map (_._2.length) 
// scala.collection.immutable.Iterable[Int] = List(10151, 9997, 9971, 9955, 9926)

이제 실제 골프에서는 defektRNG 별칭 brokenRand의 이름이 b로 변경되었습니다.

def r:Int={val k=(1 to 5).map(_=>b)
if(k.sum==13)k.findIndexOf(_==5)+1 else r} 

작동 방식 : 대부분의 경우 b는 2의 시퀀스를 반환합니다. 그러나 b를 5 번 호출하면 4x2와 1x5의 결과로 끝나는 경우가 많으며 두 번째로 가장 가능성이 높은 이벤트이며 5-2-2-2-2, 2-5-2-2 일 수 있습니다. -2, 2-2-5-2-2, 2-2-2-5-2 및 2-2-2-2-5.

이것들은 합이 4 * 2 + 5 = 13이라는 공통점이 있습니다. 처음 5의 색인을 사용하여 유효한 난수를 정의 할 수 있습니다. 5보다 크거나 작은 합계가 13보다 크거나 작은 경우 반복하십시오.

'rnd'일명 'r'의 카운터는 숫자를 생성하기 위해 평균적으로 얼마나 많은 호출이 필요한지를 표시 할 수 있습니다. 50 000 개의 난수에 대해 r에 121 200 번의 호출이 있는데, 이는 인상적이지 않습니다. :)


3

> <> (물고기) -55 바이트

스칼라 답변에서 @user unknown과 동일한 알고리즘을 사용하도록 업데이트되었습니다.

<v? = d + & : i & + & : i & + & : i & + & : i & : i
 0
 > 1 + $ 5 (? vnao;
 ^ <

고장난 발전기는 표준 입력에 연결될 것으로 예상된다. 여기 내가 사용한 파이썬 스크립트가 있습니다. 코드는 현재 Fish 사양과 일치하지만 이전 인터프리터 의 수정 된 버전 을 사용했습니다 .

bash:$ for i in $(seq 1000); do ./bad_rand.py | ./myfish.py rand.fish; done >res.txt
bash:$ for i in $(seq 5); do echo -n "$i : "; grep -c $i res.txt; done
1 : 193
2 : 204
3 : 198
4 : 206
5 : 199

나는 더 큰 샘플을 할 것이지만 느리다.


2

GolfScript, 23 바이트

늦게 대답했지만 이것이 방금 첫 페이지에 팝업 된 이후 ...

0{;[{r}5*].5?)\5-,4-}do

사용자 unknown의 Scala 솔루션 과 동일한 알고리즘을 사용합니다 . 바이어스 된 난수 생성기가 이름이 GolfScript 서브 루틴으로 제공되었다고 가정합니다 r. 다음과 같이 적합한 바이어스 RNG를 직접 정의 할 수 있습니다.

{5rand!3*2+}:r;

다음은 편견이 없다는 것을 보여주는 빠른 테스트입니다. 불행히도 온라인 GolfScript 서버는 속도가 느리므로 데모를 제 시간에 완료하기 위해 샘플을 100 개로 줄였습니다. GolfScript 인터프리터를 사용하여 로컬에서 테스트를 실행하는 경우 100*to 1000*또는 even을 늘려보십시오 10000*.

(GolfScript 서버는 때때로 무작위로 멈추고 시간이 초과되는 경우도 있습니다. 이런 경우에는 보통 다시 시도하면 해결됩니다. 다른 코드에서도 발생하며 내 컴퓨터가 아닌 서버에서만 발생하므로 확신합니다. 내 코드가 아니라 서버에 문제가 있음을 나타냅니다.)


-1

자바 스크립트, 가독성을 줄이지 않고 160 자 ( 일명 최적화)

function giveRandom(){
    var result = Math.floor(5 * Math.random()) + 1;
    while(BrockenRand() != 5){
        result = Math.floor(5 * Math.random()) + 1;
    }
    return result;
}

@ snmcdonald - 일부 그것의 오타가 아니다, 그것은 결과 (! 완전히 랜덤) 20 % 만 승인 완벽한 랜덤 발생기에 의한 무작위 JS 향상시킬 수있는 방법
www0z0k

그렇다면 무엇을 설명해야 BrockenBand()합니까?
Mateen Ulhaq

6
나는 당신이 요점을 놓쳤다 고 생각합니다
cthom06

@muntoo-의미BrockenRand
www0z0k

이 방법으로 몇 바이트를 저장하십시오.function giveRandom(){return Math.ceil(Math.random()*5)}
user300375
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.