Editing
Module:Combination
Jump to navigation
Jump to search
Warning:
You are not logged in. Your IP address will be publicly visible if you make any edits. If you
log in
or
create an account
, your edits will be attributed to your username, along with other benefits.
Anti-spam check. Do
not
fill this in!
local p = {} local getArgs, yesno function p.getCombinationGenerator() local CombinationGenerator = { list = {}, nums = {}, count = 0, number_count={}, factors={}, factor_index={} } function CombinationGenerator:init(prime_factors,fill_count) self.count=fill_count self.nums = {} for first,second in pairs(prime_factors) do if first ~= 'has_err' then self.nums[#(self.nums) + 1] = first self.number_count[first] = 0 self.factors[first] = second end end table.sort(self.nums) for i = 1,#(self.nums) do self.factor_index[self.nums[i]]=i end end function CombinationGenerator:fill() if self.count <= 0 then return end local iterator = 1 local now_number = self.nums[iterator] if #(self.list) > 0 then iterator = self.factor_index[self.list[#(self.list)]] now_number = self.nums[iterator] end while #(self.list) < self.count do --test a number 'now_number' if self.number_count[now_number] < self.factors[now_number] then --if number 'now_number' can be put self.list[#(self.list) + 1] = now_number self.number_count[now_number] = self.number_count[now_number] + 1 else --if number 'now_number' can NOT be put if iterator + 1 > #(self.nums) then break end iterator = iterator + 1 now_number = self.nums[iterator] end end end function CombinationGenerator:checkNumberCount() if self.count <= 0 then return end for i = 1,#(self.nums) do self.number_count[self.nums[i]] = 0 end for i = 1,#(self.list) do self.number_count[self.list[i]] = self.number_count[self.list[i]] + 1 end end function CombinationGenerator:set(input) local result = {} if xpcall(function()_=#input pairs(input) end,function(_)end) == true then for key,value in pairs(input) do if tostring(tonumber(tostring(key)) or 0) == tostring(key) then result[key] = value end end self.list = result end self:checkNumberCount() end function CombinationGenerator:next() if #(self.list) > 0 then local iterator = self.factor_index[self.list[#(self.list)]] local now_number = self.nums[iterator] if iterator + 1 > #(self.nums) then return false end self.number_count[now_number] = self.number_count[now_number] - 1 iterator = iterator + 1 now_number = self.nums[iterator] self.number_count[now_number] = self.number_count[now_number] + 1 self.list[#(self.list)] = now_number return true end return false end function CombinationGenerator:copyListTo(newlist) if xpcall(function()_=#newlist pairs(newlist) end,function(_)end) == true then for key,value in pairs(self.list) do if tostring(tonumber(tostring(key)) or 0) == tostring(key) then newlist[key] = value end end end end function CombinationGenerator:findSubset(min_ele,max_ele) local outside_flag = true; local result = {} local end_val = tonumber(max_ele) or -1 if (tonumber(min_ele) or -1) <= 0 then self.count = 0 else self.count = min_ele end if end_val >= 0 and self.count > end_val then return result end if #(self.nums) <= 0 then if self.count <= 0 then result[#result + 1] = {} end return result end self:set({nil}) while outside_flag == true and (end_val < 0 or self.count <= end_val) do result, outside_flag = self:findCombination(nil, result, outside_flag) self.count = self.count + 1 end return result end function CombinationGenerator:findCombination(item_count, input_array, outside_flag) local result = input_array or {} if item_count ~= nil then self.count = item_count end if #(self.nums) <= 0 then if self.count <= 0 then result[#result + 1] = {} end return result end if self.count <= 0 then self:set({nil}) result[#result+1] = {} self:copyListTo(result[#result]) else self:set({nil}) self:fill() local middle_flag = true; while middle_flag == true do local inside_flag = true; while inside_flag == true do if (#(self.list) < self.count) then outside_flag = false break end result[#result+1] = {} self:copyListTo(result[#result]) inside_flag = self:next() end local backtrack_flag = true; while backtrack_flag == true do local recursive_test = {value = tostring(table.concat(self.list,','))} local delete_num = self.list[#(self.list)] self.number_count[delete_num] = self.number_count[delete_num] - 1 self.list[#(self.list)] = nil recursive_test.count = #(self.list) if #(self.list) <= 0 then break end middle_flag = self:next() self:fill() local in_check,_ = mw.ustring.sub( tostring(table.concat(self.list,',')), 1, #tostring(recursive_test.value)) if ( tostring(in_check) == recursive_test.value ) == true then while #(self.list) > recursive_test.count do self.list[#(self.list)] = nil self:checkNumberCount(); end end backtrack_flag = (#(self.list) < self.count) or #(self.list) <= 0 end if #(self.list) <= 0 then break end end end return result, outside_flag end return CombinationGenerator end function p.subset(inputstr) --#invoke ζ―ζ΄ if not getArgs then getArgs = require('Module:Arguments').getArgs end local args = getArgs(inputstr, {parentFirst=true}) local t_vals = {} local t_args = {} for arg_name, arg_value in pairs( args ) do if tostring(mw.ustring.sub(arg_name,1,1)) == '\\' then if tostring(mw.ustring.sub(arg_name,2,2)) == '\\' then if (tonumber(arg_value)~=nil) then t_vals[tostring(mw.ustring.sub(arg_name,2))] = tonumber(arg_value) else t_args[tostring(mw.ustring.sub(arg_name,2))] = arg_value end else t_args[tostring(mw.ustring.sub(arg_name,2))] = arg_value end else if (tonumber(arg_value)~=nil) then t_vals[arg_name] = tonumber(arg_value) else t_args[arg_name] = arg_value end end end local empty_set = "[[η©Ίι|η©Ίιε]]"; local format = "*{{{1}}}\n"; local no_output, min_val, max_val for arg_name, arg_value in pairs( t_args ) do if arg_name == "format" then format = arg_value or "*{{{1}}}\n"; elseif arg_name == "min" then min_val = tonumber(arg_value) or 0; elseif arg_name == "max" then max_val = tonumber(arg_value); elseif arg_name == "empty" or arg_name == "empty set" or arg_name == "empty_set" then empty_set = arg_value or "[[η©Ίι|η©Ίιε]]"; elseif arg_name == "no_output" or arg_name == "no output" then no_output = arg_value; end end if not yesno then yesno = require('Module:Yesno') end no_output = yesno( no_output or 'no' ) format = mw.ustring.gsub(format or "*{{{1}}}\n", "%{%{%{.-%}%}%}", "%%s" ); local it = mw.ustring.find(format, "%%s", 1) if(not no_output) then if it == nil then format = format .. "%s" end end format = mw.ustring.gsub(format, "\\n", "\n") local result = {} local gened=p.getCombinationGenerator() gened:init(t_vals,0) local combination = gened:findSubset(min_val,max_val) local body = '' for i, result_str in pairs( combination ) do if(not no_output) then if #result_str <= 0 then body = body .. mw.ustring.gsub(format, "%%s", empty_set) else body = body .. mw.ustring.gsub(format, "%%s", table.concat(result_str,'')) end else body = body .. format end end return body end return p
Summary:
Please note that all contributions to wiki may be edited, altered, or removed by other contributors. If you do not want your writing to be edited mercilessly, then do not submit it here.
You are also promising us that you wrote this yourself, or copied it from a public domain or similar free resource (see
Wiki:Copyrights
for details).
Do not submit copyrighted work without permission!
Cancel
Editing help
(opens in new window)
Navigation menu
Personal tools
Not logged in
Talk
Contributions
Create account
Log in
Namespaces
Page
Discussion
English
Views
Read
Edit
View history
More
Search
Navigation
Main page
Recent changes
Random page
Help about MediaWiki
Tools
What links here
Related changes
Special pages
Page information