모듈:Random: 두 판 사이의 차이
둘러보기로 이동
검색으로 이동
imported>Hsl0 잔글 (Hsl0의 252740판 편집을 되돌림) |
>Hsl0 편집 요약 없음 |
||
(사용자 3명의 중간 판 30개는 보이지 않습니다) | |||
1번째 줄: | 1번째 줄: | ||
local p = {} | local p = {} | ||
function p.randomseed() | |||
return math.floor(os.time() * os.clock() % 1000000) | |||
end | |||
function p._rand(m, n, o) | |||
local seed, key | |||
if type(m) == "table" then | |||
seed = tonumber(m.seed) | |||
key = tonumber(m.key) | |||
m = nil | |||
n = nil | |||
elseif type(n) == "table" then | |||
seed = tonumber(n.seed) | |||
key = tonumber(n.key) | |||
m = tonumber(m) | |||
n = nil | |||
elseif type(o) == "table" then | |||
seed = tonumber(o.seed) | |||
key = tonumber(o.key) | |||
m = tonumber(m) | |||
n = tonumber(n) | |||
else | |||
m = tonumber(m) | |||
n = tonumber(n) | |||
end | |||
if (seed or 0) == 0 then | |||
seed = p.randomseed() | |||
elseif (key or 0) ~= 0 then | |||
seed = seed * (key or p.randomseed()) | |||
end | |||
math.randomseed(seed) | |||
return math.random(unpack{m, n}) | |||
end | |||
function p.rand(frame) | function p.rand(frame) | ||
return p._rand(frame.args[1], frame.args[2], frame.args) | |||
end | |||
function p._choose(frame) | |||
local len = 0 | |||
for index, value in ipairs(frame.args) do | |||
len = index | |||
end | end | ||
return frame.args[p._rand(len, frame.args)] | |||
end | |||
function p.choose(frame) | |||
return p._choose(frame:getParent()) | |||
end | |||
-- 테이블을 문자열로 변환 | |||
function p.str_join(list, delimiter) | |||
local len = #list | |||
if len == 0 then | |||
return "" | |||
end | |||
local string = list[1] | |||
for i = 2, len do | |||
string = string .. delimiter .. list[i] | |||
end | |||
return string | |||
end | |||
-- 테이블의 일부를 추출 | |||
function p.table_slice(arr,start,stop) | |||
local res = {} | |||
local n = #arr | |||
start = start or 1 | |||
stop = stop or n | |||
-- 음수 | |||
if start < 0 then | |||
start = n + start + 1 | |||
end | |||
if stop < 0 then | |||
stop = n + stop + 1 | |||
end | |||
-- start보다 stop이 큰 경우 | |||
if stop < start then | |||
stop = start | |||
end | |||
-- 루프 | |||
for i = start, stop, 1 do | |||
res[#res+1] = arr[i] | |||
end | |||
return res | |||
end | |||
-- n개의 숫자를 무작위로 뽑아서 반환 | |||
function p._sampling(n, total) | |||
local numbers = {} | |||
for i = 1, total do | |||
numbers[i] = i | |||
end | |||
-- 숫자를 무작위로 섞기 | |||
math.randomseed(p.randomseed()) | |||
for i = total, 1, -1 do | |||
local r = math.random(i) | |||
numbers[i], numbers[r] = numbers[r], numbers[i] | |||
end | |||
-- 처음 n개 숫자 선택 | |||
local sampled = {} | |||
for i = 1, n do | |||
table.insert(sampled, numbers[i]) | |||
end | |||
return sampled | |||
end | |||
-- {{#invoke:random|lotto}} | |||
function p.lotto(frame) | |||
local n = tonumber(frame.args[1]) or 6 | |||
local total = tonumber(frame.args[2]) or 45 | |||
local bonus = tonumber(frame.args[3]) or 1 | |||
local sep = frame.args[4] or ", " | |||
local bonusSep = frame.args[5] or " + " | |||
local sort = frame.args[6] or "true" | |||
if n and total and n <= total and n > 0 then | |||
local allNums = p._sampling(n + bonus, total) | |||
-- 추출한 숫자들 중 n개 추출 및 정렬 | |||
local nums = p.table_slice(allNums, 1, n) | |||
if sort == "true" then | |||
table.sort(nums) | |||
end | |||
-- bonus만큼 추출 | |||
local bonusNums = p.table_slice(allNums, n + 1, n + bonus) | |||
if sort == "true" then | |||
table.sort(bonusNums) | |||
end | |||
-- 문자열로 변환 | |||
local result = p.str_join(nums, sep) | |||
-- 보너스 번호가 있으면 추가 | |||
if bonus > 0 then | |||
result = result .. bonusSep .. p.str_join(bonusNums, sep) | |||
end | |||
return result | |||
else | |||
return "{{색깔|Error: 파라미터가 올바르지 않습니다. 1 <= n <= total를 만족해야 합니다.|red}}" | |||
end | |||
end | |||
-- text에서 sep로 구분된 문자열 중 하나를 무작위로 반환합니다. 각 항목의 앞뒤 공백은 제거됩니다. | |||
function p.sample(frame) | |||
local text = frame.args[1] or "" | |||
local sep = frame.args[2] or "," -- 기본 구분자는 콤마입니다. | |||
-- sep로 문자열을 분할하여 테이블로 변환하고 앞뒤 공백 제거 | |||
local items = {} | |||
for item in mw.text.gsplit(text, sep, true) do | |||
local trimmedItem = mw.text.trim(item) -- 앞뒤 공백 제거 | |||
table.insert(items, trimmedItem) | |||
end | |||
-- 테이블에서 무작위로 하나의 항목을 선택하여 반환 | |||
local index = p._rand(1, #items) | |||
return items[index] | |||
end | end | ||
return p | return p |
2023년 10월 23일 (월) 00:12 기준 최신판
난수를 다루는 lua함수를 모아둔 모듈입니다.
리버티위키를 비롯한 미디어위키 사이트는 구문분석기 캐싱이 허용되어 있기에 별도의 설정을 거치지 않으면 아무리 새로고침을 해도 같은값이 나오게끔 되어있습니다.
해당 모듈을 래핑하는 틀을 만들거나 {{#invoke:random}}
를 사용하는 문서에 {{캐싱방지}}를 추가해주세요.
rand
- 이 부분의 본문은 틀:rand입니다.
choose
- 이 부분의 본문은 틀:choose입니다.
lotto
{{#invoke:random|lotto|a|b}}일 때, 1부터 b까지의 자연수 중 a개를 중복 없이 추출합니다.
사용법
파라미터별 설명
{{#invoke:random|lotto|추출할 표본수|전체갯수|추출할 보너스 갯수|표본 구분자|보너스 구분자|정렬 여부}}
파라미터 기본값
{{#invoke:random|lotto|6|45|1|, | + |true}}
예시
기본 예시
code_blocks 코드
{{#invoke:random|lotto}}
code
description 결과
4, 7, 9, 18, 33, 42 + 5
보너스를 추출하지 않는 예시
code_blocks 코드
{{#invoke:random|lotto|||0}}
code
description 결과
3, 13, 25, 29, 30, 39
0부터 10까지 숫자를 랜덤나열한 예시
code_blocks 코드
{{#invoke:random|lotto|10|10|0|-||false}}
code
description 결과
5-2-8-4-6-1-7-9-3-10
sample
가중치를 설정할 수 없고 문자열로 구분 가능한 choose입니다.
사용법
파라미터별 설명
{{#invoke:random|sample|텍스트|구분할 문자열}}
파라미터 기본값
{{#invoke:random|sample||,}}
예시
기본 예시
code_blocks 코드
{{#invoke:random|sample|1,2,3,4,5}}
code
description 결과
4
구분자를 변경하는 예시
code_blocks 코드
{{#invoke:random|sample|1-2-3-4-5|-}}
code
description 결과
4
특정 분류의 랜덤 게임을 출력하는 예시
code_blocks 코드
{{#invoke:random|sample|{{#dpl:|category=함정 피하기 게임|namespace|format=,%PAGE%//}}|//}}
code
description 결과
위 설명은 모듈:Random/설명문서의 내용을 가져와 보여주고 있습니다. (편집 | 역사) 이 모듈에 대한 수정 연습과 시험은 연습장 (만들기 | 미러)과 시험장 (만들기)에서 할 수 있습니다. 분류는 /설명문서에 넣어주세요. 이 모듈에 딸린 문서. |
local p = {}
function p.randomseed()
return math.floor(os.time() * os.clock() % 1000000)
end
function p._rand(m, n, o)
local seed, key
if type(m) == "table" then
seed = tonumber(m.seed)
key = tonumber(m.key)
m = nil
n = nil
elseif type(n) == "table" then
seed = tonumber(n.seed)
key = tonumber(n.key)
m = tonumber(m)
n = nil
elseif type(o) == "table" then
seed = tonumber(o.seed)
key = tonumber(o.key)
m = tonumber(m)
n = tonumber(n)
else
m = tonumber(m)
n = tonumber(n)
end
if (seed or 0) == 0 then
seed = p.randomseed()
elseif (key or 0) ~= 0 then
seed = seed * (key or p.randomseed())
end
math.randomseed(seed)
return math.random(unpack{m, n})
end
function p.rand(frame)
return p._rand(frame.args[1], frame.args[2], frame.args)
end
function p._choose(frame)
local len = 0
for index, value in ipairs(frame.args) do
len = index
end
return frame.args[p._rand(len, frame.args)]
end
function p.choose(frame)
return p._choose(frame:getParent())
end
-- 테이블을 문자열로 변환
function p.str_join(list, delimiter)
local len = #list
if len == 0 then
return ""
end
local string = list[1]
for i = 2, len do
string = string .. delimiter .. list[i]
end
return string
end
-- 테이블의 일부를 추출
function p.table_slice(arr,start,stop)
local res = {}
local n = #arr
start = start or 1
stop = stop or n
-- 음수
if start < 0 then
start = n + start + 1
end
if stop < 0 then
stop = n + stop + 1
end
-- start보다 stop이 큰 경우
if stop < start then
stop = start
end
-- 루프
for i = start, stop, 1 do
res[#res+1] = arr[i]
end
return res
end
-- n개의 숫자를 무작위로 뽑아서 반환
function p._sampling(n, total)
local numbers = {}
for i = 1, total do
numbers[i] = i
end
-- 숫자를 무작위로 섞기
math.randomseed(p.randomseed())
for i = total, 1, -1 do
local r = math.random(i)
numbers[i], numbers[r] = numbers[r], numbers[i]
end
-- 처음 n개 숫자 선택
local sampled = {}
for i = 1, n do
table.insert(sampled, numbers[i])
end
return sampled
end
-- {{#invoke:random|lotto}}
function p.lotto(frame)
local n = tonumber(frame.args[1]) or 6
local total = tonumber(frame.args[2]) or 45
local bonus = tonumber(frame.args[3]) or 1
local sep = frame.args[4] or ", "
local bonusSep = frame.args[5] or " + "
local sort = frame.args[6] or "true"
if n and total and n <= total and n > 0 then
local allNums = p._sampling(n + bonus, total)
-- 추출한 숫자들 중 n개 추출 및 정렬
local nums = p.table_slice(allNums, 1, n)
if sort == "true" then
table.sort(nums)
end
-- bonus만큼 추출
local bonusNums = p.table_slice(allNums, n + 1, n + bonus)
if sort == "true" then
table.sort(bonusNums)
end
-- 문자열로 변환
local result = p.str_join(nums, sep)
-- 보너스 번호가 있으면 추가
if bonus > 0 then
result = result .. bonusSep .. p.str_join(bonusNums, sep)
end
return result
else
return "{{색깔|Error: 파라미터가 올바르지 않습니다. 1 <= n <= total를 만족해야 합니다.|red}}"
end
end
-- text에서 sep로 구분된 문자열 중 하나를 무작위로 반환합니다. 각 항목의 앞뒤 공백은 제거됩니다.
function p.sample(frame)
local text = frame.args[1] or ""
local sep = frame.args[2] or "," -- 기본 구분자는 콤마입니다.
-- sep로 문자열을 분할하여 테이블로 변환하고 앞뒤 공백 제거
local items = {}
for item in mw.text.gsplit(text, sep, true) do
local trimmedItem = mw.text.trim(item) -- 앞뒤 공백 제거
table.insert(items, trimmedItem)
end
-- 테이블에서 무작위로 하나의 항목을 선택하여 반환
local index = p._rand(1, #items)
return items[index]
end
return p