2014-10-13 4 views
1

기본적으로 x 주사위 굴림 = n 합계이지만 뒤로 향합니다. 그래서n을 x 개의 랜덤 부분으로 나눕니다.

다음 예를 만들 수 :

주사위 압연해야 5 배 의미 (최소 합계 5, 최대 30 합계..)

x = 5 

이기이 경우 합계에서 생각한 압연하는 수단 23 :

n = 23 

를 그래서 가능한 단일 다이 롤의 조합의 임의의 (예 6, 4, 5, 3, 5)

0을 얻을 수있다 필요

내가 지금까지 내 마음에 만들 수있는 것은 :

  1. 5 개 난수를 생성합니다.
  2. 그들을 더하고 합계를 구하십시오.
  3. 지금 합 매 난수 나누어 원하는 번호 23
  4. 결과는 23.

이 하나가 랜덤 반환 문제가있는 원하는 수와 같아야 5 개 난수이다 곱 값 (소수, 1 이하 6 이하의 값)은 난수에 따라 다릅니다. 수식을 편집하여 정수> = 1 또는 < = 6을 반환 할 수있는 방법을 찾을 수 없습니다.

+0

가능한 모든 조합을 생성하려면 난수를 사용하는 것이 해결책이라고 생각하지 않습니다. –

+0

나는 모든 가능한 조합을 필요로하지 않는다, 나는 매 달리기 주어진 수를위한 단지 1 개의 무작위 조합 만 필요로한다. – RamRick

답변

1

가장 쉬운 방법은 확대 할 때까지 다시 랜덤 화하는 것입니다. 바로 합계. 그것은 현대의 CPU에서 밀리 초 걸립니다. 귀엽지 않아.

#!/usr/local/bin/lua 

math.randomseed(os.time()) 

function divs(n,x) 
    local a = {} 

    repeat 
    local s = 0 
    for i=1,x do 
     a[i] = math.random(6) 
     s = s + a[i] 
    end 
    until s==n 

    return a 
end 

a = divs(23,5) 
for k,v in pairs(a) do print(k,v) end 
+2

프로그램 당 한 번만 'math.randomseed'를 호출하면됩니다. 따라서'divs '밖에서 호출하는 것이 현명 할 것입니다. 또한'divs '에 지역 변수'a'와's'를 사용하십시오. – lhf

1

이것은 흥미로운 문제였습니다. 여기 내 걸릴 :

편집 : 나는 당신이 주사위 롤 수있는 사실을 놓친. 새로운 시도가 있습니다. 보너스로 선택적 매개 변수에서 오지의면 수를 지정할 수 있습니다.

local function getDiceRolls(n, num_rolls, num_sides) 
    num_sides = num_sides or 6 
    assert(n >= num_rolls, "n must be greater than num_rolls") 
    assert(n <= num_rolls * num_sides, "n is too big for the number of dices and sides") 

    local rolls = {} 
    for i=1, num_rolls do rolls[i] = 1 end 

    for i=num_rolls+1, n do 
    local index = math.random(1,num_rolls) 
    while rolls[index] == num_sides do 
     index = (index % num_rolls) + 1 
    end 
    rolls[index] = rolls[index] + 1 
    end 

    return rolls 
end 

-- tests: 

print(unpack(getDiceRolls(21, 4))) -- 6 4 6 5 
print(unpack(getDiceRolls(21, 4))) -- 5 5 6 5 
print(unpack(getDiceRolls(13, 3))) -- 4 3 6 
print(unpack(getDiceRolls(13, 3))) -- 5 5 3 
print(unpack(getDiceRolls(30, 3, 20))) -- 9 10 11 
print(unpack(getDiceRolls(7, 7))) -- 1 1 1 1 1 1 1 
print(unpack(getDiceRolls(7, 8))) -- error 
print(unpack(getDiceRolls(13, 2))) -- error 
+0

이 해결책은 주사위 던지기의 결과, 즉 1과 6 사이의 가중치의 제한을 존중하지 않습니다. – lhf

+0

@lhf : 당신은 완전히 옳았습니다, 나는 그 설명을 간과했습니다. 내 대답은 그것을 구현하는 새로운 알고리즘으로 다시 작성했습니다. – kikito

0

롤 수가 급격히 변하지 않지만 합계가 변하면 주어진 합계의 조합에 대한 찾아보기 테이블을 만드는 것이 좋습니다. 모든 조합을 생성하고 각각에 대해 합계를 계산 한 다음 해당 합계와 관련된 목록에 조합을 추가하십시오. 룩업 테이블은 다음과 같이 보일 것이다 :

T = {12 = {{1,2,3,4,2},{2,5,3,1,1},{2,2,2,3,3}, ...}, 13=....} 

을 그럼 당신은 무작위 N = 23 콤보를 선택, 당신은 키 23 표에보고 할 때,리스트가 합계 모든 콤보를 가지고, 지금은 그냥 무작위로 선택 그들 중 하나. 다른 번호와 동일합니다.

관련 문제