模組:Number/docUtil
本模組會自動讀取Module:Number/data並輸出示例,用於自動產生Module:Number/doc和Module:Number/data/doc的某些示例。
local p = { PrimeTable = {} }
local numlib = require("Module:Number")
local numdata = require("Module:Number/data")
function p.printDoc(frame)
local body = ''
temp_frame = frame
for key,value in pairs(numdata.numberFormat) do
body = body .. p._printDocRow(value, key) ..'\n'
end
return mw.text.trim(body)
end
function p._printDocRow(num_data_row, namekey)
local body = "|- \n| "
body = body .. "-{" .. namekey .. "}- || "
if num_data_row.page then body = body .. "[[" .. num_data_row.page .. "]]" end
body = body .. "\n| "
if temp_frame and num_data_row.info then
body = body .. temp_frame:callParserFunction{name = "#tag:code", args = {mw.text.nowiki(num_data_row.info)}}
end
body = body .. "\n| \n"
if num_data_row.arg_desc then
for key,value in pairs(num_data_row.arg_desc) do
local keystr = tostring(key)
if temp_frame then
keystr = temp_frame:callParserFunction{name = "#tag:code", args = {mw.text.nowiki("{{{ ") .. '\'\'\'' .. keystr .. '\'\'\'' .. mw.text.nowiki(" }}}")}}
end
body = body .. '*' .. keystr .. '\n'
body = body .. "*:" .. tostring(value) .. '\n'
end
end
body = body .. "| \n"
if num_data_row.example then
body = body .. ';' .. tostring(num_data_row.example) .. '\n'
body = body .. _number_example_row(num_data_row, namekey) .. '\n'
end
body = body .. '|'
if num_data_row.name == "質數" then
body = body .. "前1000項<br/>2 ~ 7919"
elseif num_data_row.list then
local count, val_max, id_max, val_min = 0, 0, 0, nil
for key,value in pairs(num_data_row.list) do
if tonumber(key) > tonumber(val_max) then val_max,id_max = key,value end
if val_min == nil then val_min = key end
if tonumber(key) < tonumber(val_min) then val_min = key end
count = count + 1
end
if val_min then
body = body .. '前' .. tostring(count) .."項<br/>" .. val_min .. " ~ " .. val_max
end
end
body = body .. "\n|"
if num_data_row.name == "半完全數" then
if temp_frame then
body = body .. temp_frame:expandTemplate{title = "Partial_success", args = {"速度慢"}}
else
body = body .. "速度慢"
end
elseif num_data_row.check then
if temp_frame then
body = body .. temp_frame:expandTemplate{title = "Yes", args = {"支援"}}
else
body = body .. "支援"
end
else
if temp_frame then
body = body .. temp_frame:expandTemplate{title = "No", args = {"不支援"}}
else
body = body .. "不支援"
end
end
return body
end
function p.single_property_example(frame)
local body = ''
temp_frame = frame
local to_display = mw.text.trim(frame.args[1] or '')
if to_display == '' then return '' end
local num_data_row = numdata.numberFormat[frame.args[1]]
if num_data_row == nil then return '' end
if num_data_row.example then
body = body .. ';' .. tostring(num_data_row.example) .. '\n'
body = body .. _number_example_row(num_data_row, to_display) .. '\n'
end
return mw.text.trim(body)
end
function _number_example_row(num_data_row, namekey)
if numlib == nil then numlib = require("Module:Number") end
local body = ''
if temp_frame then can_math = true end
local number = tonumber(num_data_row.example)
--因數分解
if p.PrimeTable.table_max == nil then p.PrimeTable = require('Module:Factorization') end
local primedata = p.PrimeTable._factorization(number)
local divdata = p.PrimeTable._findDivisorByPrimeFactor(primedata)
--因數分解發生錯誤,停止執行並返回錯誤
if primedata.has_err ~= nil or divdata.has_err ~= nil then
local Error = require("Module:Error")
if primedata.has_err ~= nil then return body .. '\n' .. Error.error({[1]="錯誤:" .. primedata.has_err})
else return body .. '\n' .. Error.error({[1]="錯誤:" .. divdata.has_err}) end
end
local is_prime = true --表示數字是否為質數
local num_sqrt = math.sqrt(number) --表示數字的平方根
local admirable_div = nil --表示佩服數的相減因數
local is_unusual = nil --表示數字是否有大於平方根的質因數
local div_sum = 0 --因數和
local prime_count = 0 --相異質因數個數
local div_sum_harmonic = 0 --因數調和總和
local div_harmonic_avg = 0.001 --因數調和平均數
local div_count = 0 --因數數量
local exp_num = 0 --質因數總指數 (Ω)
local prime_digits = 0
local buffer_text = ''
local mersenne_prime_for_perfect_number = ''
--掃描質因數
for first,second in pairs(primedata) do
if first ~= 'has_err' then
if first ~= 1 and first ~= number then
is_prime = false
end
if first ~= 1 then
--判斷是否為不尋常數 (是否有大於平方根的質因數)
if first > num_sqrt then is_unusual = first end
--計算質因數總指數 (Ω)
exp_num = exp_num + second
--計算相異質因數數量
prime_count = prime_count + 1
prime_digits = prime_digits +
mw.ustring.len( mw.ustring.format( "%d",math.floor(math.abs(first)) ) )
if second > 1 then prime_digits = prime_digits +
mw.ustring.len( mw.ustring.format( "%d",math.floor(math.abs(second)) ) ) end
end
end
end
--計算因數和
for first,second in pairs(divdata) do
if first ~= 'has_err' then
if second ~= number then div_sum = div_sum + second end
div_sum_harmonic = div_sum_harmonic + (1.0 / second)
div_count = div_count + 1
end
end
--計算因數的調和平均數
div_harmonic_avg = (div_count + 0.000000) / div_sum_harmonic
for first,second in pairs(divdata) do
if first ~= 'has_err' then
--判斷數字是否為佩服數
if div_sum - second * 2 == number then admirable_div = second end
end
end
--產生<math>格式,以印出質因數分解於條目
local times = " x "
local pow_h = "<sup>"
local pow_f = "</sup>"
local left_ = "("
local right_ = ")"
if can_math then
times = "\\times "
pow_h = "^{"
pow_f = "} "
left_ = "\\left( "
right_ = "\\right) "
end
local is_gprime = true
local gfactors_str = ''
if mw.text.trim(namekey) == "高斯整數分解" then
if cmath==nil then cmath = require("Module:Complex Number").cmath.init() end
local cnum = cmath.toComplexNumber(tostring(number))
is_gprime = cmath.is_prime_quadrant1(cnum)
if is_gprime ~= nil then
if not is_gprime then
local gprimedata, gfactors = p.PrimeTable._gaussianFactorization(tostring(number)), {}
for first,second in pairs(gprimedata) do
if first ~= 'has_err' then
local complex_num = cmath.toComplexNumber(first)
if complex_num.real ~= 0 and complex_num.imag ~= 0 then
gfactors[left_ .. tostring(first) .. right_] = second
else
gfactors[first] = second
end
end
end
--印出質因數分解於條目
gfactors_str = p.PrimeTable.create_factorization_string(gfactors, times, pow_h, pow_f)
if mw.text.trim(gfactors_str) == '' then is_gprime = true end
if can_math then
gfactors_str = temp_frame:callParserFunction{name = "#tag:math", args = {gfactors_str}}
end
end
end
end
--印出質因數分解於條目
local factors_str = p.PrimeTable.create_factorization_string(primedata, times, pow_h, pow_f)
if can_math then
factors_str = temp_frame:callParserFunction{name = "#tag:math", args = {factors_str}}
if div_sum == number then
mersenne_prime_for_perfect_number= "2^{" .. tostring(primedata[2]) .. "}\\times\\left( 2^{" ..
tostring(primedata[2]+1) .. "}-1\\right)"
mersenne_prime_for_perfect_number = temp_frame:callParserFunction{name = "#tag:math", args = {mersenne_prime_for_perfect_number}}
end
end
local simi_div = {}
if div_sum > number and number > 0 then
if #divdata <= 32 then
--此為指數時間複雜度演算法,因此當因數超過32個時則放棄計算
simi_div = numlib._checkSemiperfectNumberByDivisor(divdata)
end
end
local printer = numdata.getIntegerInfoPrinter()
printer:init({
number=number,
is_prime=is_prime,
admirable_div=admirable_div,
is_unusual=is_unusual,
div_sum=div_sum,
prime_count=prime_count,
div_sum_harmonic=div_sum_harmonic,
div_harmonic_avg=div_harmonic_avg,
div_count=div_count,
exp_num=exp_num,
prime_digits=prime_digits,
divdata=divdata,
primedata=primedata,
simi_div=simi_div,
factors_str=factors_str,
mersenne_prime_for_perfect_number=mersenne_prime_for_perfect_number,
is_gprime=is_gprime,
gfactors_str=gfactors_str,
});
local text = ''
local args = {}
args = printer:getValue(namekey)
if num_data_row.value then num_data_row.value(printer, args) end
body = numdata._getFormatingStringByArgument(' ' .. num_data_row.info, args)
return mw.text.trim(body)
end
return p