模組:沙盒/a2569875/Test

维基百科,自由的百科全书
文档图示 模块文档[创建]
local p={}
local lib_arg={}

function p.stringWarp(input_str)
	local char_count = mw.ustring.len(input_str)
	local result = ''
	local string_list = {}
	local in_string = ''
	local buffer = ''
	for i = 1,char_count do
		local it = mw.ustring.sub(input_str,i,i)
		if in_string == '' then
			if it == "'" or it == '"' then
				buffer, in_string = '', it
			else
				result = result .. it
			end
		else
			if it == "\\" then
				i=i+1
				buffer = buffer .. mw.ustring.sub(input_str,i,i)
			elseif it == in_string then
				string_list[#string_list+1] = buffer
				result = result .. ' STRINGID' .. tostring(#string_list) .. ' '
				buffer, in_string = '', ''
			else
				buffer = buffer .. it
			end
		end
	end
	if in_string ~= '' then result = result .. in_string .. buffer end
	return result, string_list
end


local lib_eis = require("Module:Complex_Number")
local numdata = require("Module:Number/data")
function p._is_eisenstein_quadrant1(eis_real, omega)
	if eis_real == 0 and omega == 0 then return false end
	local sqre_norm = eis_real * eis_real - eis_real * omega + omega * omega
	if sqre_norm == 1 then return false end
	if not numdata._is_integer(eis_real) or not numdata._is_integer(omega) then return false end
	local eReal, eImag = 'reω', 'ω'
	local one, n_one, p_omega, n_omega, omegasq, n_omegasq = 
		lib_eis._eisenstein_integer(1,0), lib_eis._eisenstein_integer(-1,0), 
		lib_eis._eisenstein_integer(0,1), lib_eis._eisenstein_integer(0,-1), 
		lib_eis._eisenstein_integer(-1,-1), lib_eis._eisenstein_integer(1,1)
	local _eisenstein_unit = {one, n_omegasq, p_omega, n_one, omegasq, n_omega}
	local current = lib_eis._eisenstein_integer(eis_real,omega)
	if math.abs(omega) <= 1e-8 then
		if numdata._is_integer((eis_real + 1.0) / 3.0) then
			if (PrimeTable or {}).table_max == nil then PrimeTable = require('Module:Factorization') end
			PrimeTable.primeIndexOf({(eis_real or 0)+2})
			if PrimeTable.lists[eis_real] ~= nil then return true end
		end
		return false
	end
	for i=1,#_eisenstein_unit do
		local checker = current / _eisenstein_unit[i]
		mw.log('' .. tostring(current) .. " divide by " .. tostring(_eisenstein_unit[i]) .. " = " .. tostring(checker))
		if math.abs(checker[eImag]) <= 1e-8 then
			if numdata._is_integer((checker[eReal] + 1.0) / 3.0) then
				mw.log('' .. tostring(checker[eReal]) .. " is 3n-1")
				if (PrimeTable or {}).table_max == nil then PrimeTable = require('Module:Factorization') end
				PrimeTable.primeIndexOf({(checker[eReal] or 0)+2})
				if PrimeTable.lists[checker[eReal]] ~= nil then return true end
			end
		end
		if sqre_norm % 3 < 2 then
			mw.log('|' .. tostring(current) .. "| = ".. (sqre_norm % 3) .. ' mod 3; ' .. (sqre_norm % 3) .. ' < 2')
			if (PrimeTable or {}).table_max == nil then PrimeTable = require('Module:Factorization') end
			PrimeTable.primeIndexOf({(sqre_norm or 0)+2})
			if PrimeTable.lists[sqre_norm] ~= nil then return true end
		end
	end
	return false
end

function p.can_not_edit_title(frame)--{{#invoke:沙盒/a2569875/Test|find_TTTT}}
	local args, working_frame
    if frame == mw.getCurrentFrame() then
        -- We're being called via #invoke. The args are passed through to the module
        -- from the template page, so use the args that were passed into the template.
        if lib_arg.getArgs == nil then lib_arg = require('Module:Arguments') end
        args = lib_arg.getArgs(frame, {
        	parentFirst=true,
        	trim = false,
			removeBlanks = false
        })
        working_frame = frame
    else
        -- We're being called from another module or from the debug console, so assume
        -- the args are passed in directly.
        args = frame
        working_frame = mw.getCurrentFrame()
        if type(args) ~= type({}) then args = {frame} end
    end
    local h_lvl = args[1] or args['1'] or '2'
    h_lvl = tonumber(h_lvl) or 2
	local body = ''
	for i=1,h_lvl do body = body .. '=' end
	local strip_marker = mw.ustring.gsub(working_frame:preprocess( body .. ' ' ..body),'=','')
    return strip_marker .. (args[2] or args['2'] or '') .. strip_marker
end

local function _swap(x,i,y,j) local t = x[i]; x[i] = y[j]; y[j] = t end
local function _fo(a,b,func) for i=a,b do func(i) end end
local function _fd(a,b,func) for i=a,b,-1 do func(i) end end
local lib_bit=require('bit32');local bit={lS=lib_bit.lshift,rS=lib_bit.rshift,Or=lib_bit.bor,And=lib_bit.band}
function bit.rev(x,_len)
	local ans = 0
	for i=1,_len do ans=bit.lS(ans,1);ans=bit.Or(ans,bit.And(x,1));x=bit.rS(x,1) end
	return ans
end
p.bit = bit

local function _FFT(reA, inA, num, flag)
	local lgn = math.floor(math.log(num) / math.log(2))
	for i=0,num-1 do
		local j = bit.rev(i,lgn)
		if j > i then _swap(reA, i+1, reA, j+1); _swap(inA, i+1, inA, j+1) end
	end
	for s=1,lgn do
		local m = bit.lS(1,s)
		local reWm, inWm = math.cos(2*math.pi/m), math.sin(2*math.pi/m)
		if flag==true then inWm = -inWm end
		local k = 0 while k < num do
			local reW, inW = 1.0, 0.0
			for j=0,math.floor(m/2)-1 do
				local tag = k + j + math.floor(m / 2);
                local reT = reW * (reA[tag+1]or 0) - inW * (inA[tag+1]or 0);
                local inT = reW * (inA[tag+1]or 0) + inW * (reA[tag+1]or 0);
                local reU, inU = (reA[k+j+1]or 0), (inA[k+j+1]or 0);
                reA[k+j+1] = reU + reT; inA[k+j+1] = inU + inT;
                reA[tag+1] = reU - reT; inA[tag+1] = inU - inT;
                local reWt = reW * reWm - inW * inWm;
                local inWt = reW * inWm + inW * reWm;
                reW = reWt; inW = inWt;
			end
		k=k+m end
	end
end
local function _char2byte(ch) return mw.ustring.codepoint(ch) end
local function _getchar(str,i) return mw.ustring.sub(str,i,i) end
local _base, _strlen, _char0  = 10, mw.ustring.len, _char2byte(0)
local function _check_str_sign(in_str)
	local str = tostring(in_str)
	local check, result, result_str = _getchar(str,1), 1, str
	if check == '+' or check == '-' then result_str = mw.ustring.sub(str, 2, -1) 
		result = (check == '-' and -1) or (check == '+' and 1) or result
	end
	return result, result_str
end
--九九乘法表 O(8N)
local function _times_table(in_num1)
	local num1 = in_num1
	local res_sign = 1
	local a, res = {0}, {nil,{0},{0},{0},{0},{0},{0},{0},{0}};
	res_sign, num1 = _check_str_sign(in_num1)

	local a_is_zero = true
	local _len, len1;
	len1 = _strlen(num1); _len = len1 + len1;
    for i = 0,len1-1 do 
    	a[i+1] = _char2byte(_getchar(num1,len1-i)) - _char0 
    	a_is_zero = a_is_zero and a[i+1] < 1e-14
    end
    
    if a_is_zero then local pre_res = {} for i=1,9 do pre_res[i] = (res_sign < 0 and '-' or '') .. '0' end return pre_res end
    for b=2,9 do for i=1,len1 do res[b][i] = a[i] * b end end
    
    for b=2,9 do for i=1,_len+2 do
    	res[b][i+1] = (res[b][i+1]or 0) + math.floor((res[b][i]or 0) / _base)
    	res[b][i] = (res[b][i]or 0) % _base
    end end
    local clear_zero = #res
	for b=2,9 do 
		local clear_zero = #(res[b])
		for i=clear_zero,1,-1 do
			if res[b][i] > 1e-14 then break end
			if i~=1 then res[b][i] = nil end
		end 
	end
	local result = {in_num1}
	for b=2,9 do 
		result[b] = ''
		for i=#(res[b]),1,-1 do result[b] = result[b] .. string.format("%d",(res[b][i]or 0))end
		result[b] = (res_sign < 0 and '-' or '') .. result[b]
	end
    return result
end
--p._TEST001('99',99)
function p._TEST001(in_num1, in_num2)
	local num1, num2 = in_num1, tonumber(in_num2) or 0
	local a_sign, b_sign = 1 ,1
	local a, b, res = {0}, math.floor(math.abs(num2)), {0};
	a_sign, num1 = _check_str_sign(in_num1)
	b_sign = _check_str_sign(in_num2)

	local a_is_zero, b_is_zero = true, false
	if b < 1e-14 then b_is_zero = true end
	local _len, len1;
	len1 = _strlen(num1);
	_len = len1 + math.ceil(math.log10(b)) + 2
    for i = 0,len1-1 do 
    	a[i+1] = _char2byte(_getchar(num1,len1-i)) - _char0 
    	a_is_zero = a_is_zero and a[i+1] < 1e-14
    end
    
    local res_sign = a_sign * b_sign
    if a_is_zero or b_is_zero then return (res_sign < 0 and '-' or '') .. '0' end
    
    for i=1,len1 do res[i] = a[i] * b end
    for i=1,_len+2 do
    	res[i+1] = (res[i+1]or 0) + math.floor((res[i]or 0) / _base)
    	res[i] = (res[i]or 0) % _base
    end
    local clear_zero = #res
	for i=clear_zero,1,-1 do
		if res[i] > 1e-14 then break end
		if i~=1 then res[i] = nil end
	end
	local result = ''
	for i=#res,1,-1 do result = result .. string.format("%d",(res[i]or 0))end
    return (res_sign < 0 and '-' or '') .. result
end


--p._TEST002('425731578351266','948700000017358')
--403891548389235902937021275228
function p._TEST002(in_num1, in_num2)
	local num1, num2 = in_num1, in_num2
	local a_sign, b_sign = 1,1
	local in1, in2
	a_sign, in1 = _check_str_sign(in_num1)
	b_sign, in2 = _check_str_sign(in_num2)
	local a_is_zero, b_is_zero = true, true
	local res,rea,ina,reb,inb,ret,intt = {0},{0},{0},{0},{0},{0},{0}
	local len1,len2,lent,lenres,_len;
	local s1, s2 = tostring(in1), tostring(in2)
	len1 = _strlen(s1); len2 = _strlen(s2);
	if len1 > len2 then lent = len1 else lent = len2 end; _len=1
	while _len < lent do _len = bit.lS(_len,1) end _len = bit.lS(_len,1)
    for i = 0,_len-1 do
		if i < len1 then rea[i+1] = _char2byte(_getchar(s1,len1-i)) - _char0 end
		if i < len2 then reb[i+1] = _char2byte(_getchar(s2,len2-i)) - _char0 end
		a_is_zero = a_is_zero and (rea[i+1]or 0) < 1e-14
		b_is_zero = b_is_zero and (reb[i+1]or 0) < 1e-14
		ina[i+1],inb[i+1] = 0,0;
	end
	
	local res_sign = a_sign * b_sign
    if a_is_zero or b_is_zero then return (res_sign < 0 and '-' or '') .. '0' end
	
	_FFT(rea,ina,_len,false); _FFT(reb,inb,_len,false);
    for i=0,_len-1 do
		local rec = rea[i+1] * reb[i+1] - ina[i+1] * inb[i+1];
		local inc = rea[i+1] * inb[i+1] + ina[i+1] * reb[i+1];
		rea[i+1] = rec; ina[i+1] = inc;
	end
	_FFT(rea,ina,_len,true);
    for i=0,_len-1 do rea[i+1] = rea[i+1] / _len; ina[i+1] = ina[i+1] / _len end

    for i=0,_len-1 do res[i+1] = math.floor(rea[i+1] + 0.5)end
    for i=0,_len-1 do res[i+2] = (res[i+2]or 0) + math.floor((res[i+1]or 0) / _base) ; res[i+1] = (res[i+1]or 0) % _base end

    lenres = len1 + len2 + 2;
    while (res[lenres+1]or 0) == 0 and lenres > 0 do lenres=lenres-1 end
    local result = ''
    for i=lenres,0,-1 do result = result .. string.format("%d",(res[i+1]or 0))end
    return (res_sign < 0 and '-' or '') .. result
end
--p._TEST003("125774", "-521145")
function p._TEST003(in_num1, in_num2)
	local num1, num2 = in_num1, in_num2
	local a_sign, b_sign = 1,1
	local in1, in2
	a_sign, in1 = _check_str_sign(in_num1)
	b_sign, in2 = _check_str_sign(in_num2)
	local len1,len2,lenres,_len;
	local s1, s2 = tostring(in1), tostring(in2)
	len1 = _strlen(s1); len2 = _strlen(s2);
	_len = math.max(len1,len2) + 2
	local a, b, res = {0}, {0}, {0};
    for i = 0,_len-1 do
		if i < len1 then a[i+1] = _char2byte(_getchar(s1,len1-i)) - _char0 end
		if i < len2 then b[i+1] = _char2byte(_getchar(s2,len2-i)) - _char0 end
	end
	for i=1,_len do res[i] = a_sign * (a[i]or 0) + b_sign * (b[i]or 0) end
    lenres = _len + 2;
    while (res[lenres]or 0) == 0 and lenres > 0 do lenres=lenres-1 end
    local resign = 1
    if res[lenres] == -0 or res[lenres] < 0 then resign = -1 end
    
    for i=1,_len+2 do
    	local this_dig = (res[i]or 0) * resign
    	local carry = math.floor(this_dig / _base)
    	res[i+1] = (res[i+1]or 0) + carry * resign
    	if this_dig < 0 then this_dig = this_dig + (math.ceil(math.abs(this_dig) / _base) + 1) * _base end
    	res[i] = this_dig % _base
    end
    lenres = _len + 2;
    while (res[lenres+1]or 0) == 0 and lenres > 0 do lenres=lenres-1 end
    local result = ''
    for i=lenres,0,-1 do result = result .. string.format("%d",(res[i+1]or 0))end
    return (resign < 0 and '-' or '') .. result
end

local function _spilt_num(in_num)
	local num = tostring(in_num)
	local pt = mw.ustring.find(num,'%.')
	local _int, _fac
	_int = mw.ustring.sub(num, 1, (pt or 0) -1)
	_fac = pt and mw.ustring.sub(num, pt+1, -1) or ''
	pt = mw.ustring.find(_fac,'%.')
	local _nonloop, _loop
	_nonloop = mw.ustring.sub(_fac, 1, (pt or 0) -1)
	_loop = pt and mw.ustring.sub(_fac, pt+1, -1) or ''
	pt = mw.ustring.find(_loop,'%.')
	_loop = mw.ustring.sub(_loop, 1, (pt or 0) -1)
	return _int, _nonloop, _loop
end
function p._find_repeat_part(cur, rp_part)
	local _rp_part = rp_part
	if type(_rp_part) ~= type({"table"}) then _rp_part = {}end
	_rp_part[#_rp_part+1] = {_rep='',_buf='',str='',j=1,k=1}
	local found, rep_string = false
	for i=1,#_rp_part do
		local it = _rp_part[i]
		local pat, r_len = _getchar(it._rep, it.j), _strlen(it._rep)
		if r_len>0 and it.j>r_len then
			pat = _getchar(it._rep,it.k)
			it._buf = it._buf .. cur
			if cur ~= pat then
				it.j,it.k = 1,1
				it._rep = it._rep .. it._buf
				it._buf = ''
			else
				it.k = it.k+1 if it.k>r_len then it.k = 1 end
			end
		else
			if cur ~= pat then
				it._rep = it._rep .. it._buf .. cur
				it._buf = ''
				it.j,it.k = 1,1
			else
				it._buf = it._buf .. cur
				it.j = it.j+1
			end
		end
		_rp_part[i] = it
		if it.j ~= 1 and it.j > _strlen(it._rep) then
			rep_string = rep_string or it._rep
			found = true
		end
	end
	return _rp_part, rep_string
end

function p.test_find_repeat_part(str)
	local _len = _strlen(str)
	local rp_part, rep_string
	for i=1,_len do
		rp_part, rep_string = p._find_repeat_part(_getchar(str,i), rp_part)
		mw.logObject(rp_part)
		mw.log(rep_string)
		mw.log("----")
	end
end
function p._find_repeat(in_str)
	local str = tostring(in_str)
	local _repeat,_buf,j,k = '','',1,1
	local _len = _strlen(str)
	local found, rep_start, rep_end = false
	local start=1 while start < _len-4 do --dynamic iterator count
		local find_endpos = 0
		if found then break end
		--mw.log("start="..start)
		_repeat,_buf,j,k = '','',1,1
		local i=start while i <= _len do --dynamic iterator count
			local cur, pat, r_len = _getchar(str,i), _getchar(_repeat,j), _strlen(_repeat)
			if found then break end
			if start==1 and cur ~= '0' then find_endpos=i end
			if r_len>0 and j>r_len then
				pat = _getchar(_repeat,k)
				_buf = _buf .. cur
				if cur ~= pat then
					j,k = 1,1
					_repeat = _repeat .. _buf
					_buf = ''
				else
					k = k+1 if k>r_len then k = 1 end
				end
			else
				if cur ~= pat then
					_repeat = _repeat .. _buf .. cur
					_buf = ''
					j,k = 1,1
				else
					_buf = _buf .. cur
					j = j+1
				end
			end
			--mw.log(mw.ustring.sub(str,start,_len))
			--mw.log(_repeat..'\t'..j..','..k..'\tcur=\''..cur..'\', pat=\''..pat..'\', buf=\''.._buf..'\'')
			i = i + 1
		end
		if start == 1 then
			if find_endpos <= 0 then return 0 end
			_len = find_endpos
		end
		if _repeat ~= mw.ustring.sub(str,start,_len) and j > _strlen(_repeat) then
			rep_start, rep_end = start, start + _strlen(_repeat) - 1
			found = true
		end
		start = start + 1
	end
	if _repeat ~= mw.ustring.sub(str,start,_len) and j > _strlen(_repeat) then
		return rep_start, rep_end
	end
	return nil
end

--big float add
function p._TEST004(in_num1, in_num2, op)
	local num1, num2 = tostring(in_num1), tostring(in_num2)
	local int01, int02, nonloop01, nonloop02, loop01, loop02
	int01, nonloop01, loop01 = _spilt_num(num1)
	int02, nonloop02, loop02 = _spilt_num(num2)
	local len_non1, len_non2, len_non, len_lo1, len_lo2
	len_non1 = _strlen(nonloop01); len_lo1 = _strlen(loop01)
	len_non2 = _strlen(nonloop02); len_lo2 = _strlen(loop02)
	len_non = math.max(len_non1+len_lo1, len_non2+len_lo2)
	local tail1, tail2
	local find_loop = (len_lo1 + len_lo2) * 2 + 16
	tail1 = mw.ustring.rep(loop01=='' and '0' or loop01 ,math.ceil((len_non+find_loop) / math.max(len_lo1, 1))+1)
	tail2 = mw.ustring.rep(loop02=='' and '0' or loop02 ,math.ceil((len_non+find_loop) / math.max(len_lo2, 1))+1)
	local f_res1, f_res2 = nonloop01 .. tail1, nonloop02 .. tail2
	f_res1 = mw.ustring.sub(f_res1, 1, len_non + find_loop - 2) .. '9'
	f_res2 = mw.ustring.sub(f_res2, 1, len_non + find_loop - 2) .. '9'
	--add
	local result = p._TEST003(int01..f_res1, int02..f_res2)
	local int_res = mw.ustring.sub(result,1,-len_non-find_loop)
	local int_fac = mw.ustring.sub(result,-len_non-find_loop-1+2,-1)
	local rep_start, rep_end = p._find_repeat(mw.ustring.sub(int_fac,1,len_non + find_loop - 3))
	local num_tail = ''
	if rep_start then
		if rep_start == 0 then return int_res==''and'0'or int_res end
		num_tail = '.'..mw.ustring.sub(int_fac, rep_start, rep_end)..'.'
		int_fac = rep_start==1 and '' or mw.ustring.sub(int_fac, 1, rep_start-1)
	else
		int_fac = mw.ustring.sub(int_fac,1,len_non)
	end
	return (int_res==''and'0'or int_res) ..'.'.. int_fac .. num_tail
end
--[[
int fibonacci(int num){
    if(num<2){
    	return num;
    }else {
    	int local_var = fibonacci(num-1);
    	return local_var + fibonacci(num-2);
    }
}
]]
function p.fibonacci(input)
	local stack = { {
		mode=0, 
		returned=0, 
		num=input, 
		local_var=0
	} }
	while #stack > 0 do
		local stack_top = stack[#stack]
		if stack_top.mode == 0 then
			mw.log('call fibonacci(' .. stack_top.num ..')')
			if stack_top.num<2 then
				--//return num;
				stack[#stack].returned = stack_top.num
				stack[#stack].mode = 3
			else
				--call fibonacci(num-1)
				--stack push
				stack[#stack].mode = 1 --will go next block
				stack[#stack + 1] = {
					mode=0, 
					returned=0, 
					num=stack_top.num-1, 
					local_var=0
				}
				--mw.logObject(stack)
			end
		elseif stack_top.mode == 1 then
			--int local_var = fibonacci(num-1);
			mw.log('result fibonacci(num-1)',stack_top.returned)
			stack[#stack].local_var = stack_top.returned
			--call fibonacci(num-2)
			--stack push
			stack[#stack].mode = 2 --will go next block
			stack[#stack + 1] = {
				mode=0, 
				returned=0, 
				num=stack_top.num-2, 
				local_var=0
			}
		elseif stack_top.mode == 2 then
			--return local_var + fibonacci(num-2);
			stack[#stack].returned = stack_top.local_var + stack_top.returned
			mw.log('result fibonacci(num-2)',stack_top.returned)
			stack[#stack].mode = 3
		else --do return
			mw.log('return fibonacci(' .. stack_top.num ..') as ' .. stack[#stack].returned)
			if #stack == 1 then return stack[#stack].returned end
			stack[#stack-1].returned = stack[#stack].returned
			stack[#stack] = nil
		end
	end
end

local qrencode=require( 'Module:EncoderUtil' )._get_libqrcode()
local color_table = require( 'Module:PeriodicTable' ).renderClassTable
function p.show_qr(input_text)
	local str = ""
	if type(input_text) == type(str) then
		str = input_text
	else
		if lib_arg.getArgs == nil then lib_arg = require('Module:Arguments') end
        local args = lib_arg.getArgs(input_text) 
		str = args[1] or args["1"] or '{{{1}}}'
	end
	local ok, endata = qrencode.qrcode(str,4)
	if not ok then return "" end

	return color_table("","",endata,',',{"black-block","black-block","black-block",[0]="white-block",[-1]="white-block",[-2]="white-block"},"")
end
return p