Module:JI ratios: Difference between revisions
Reworked products search as a BFS algorithm |
Moar cleanup; refined subgroup-search code to implement bfs |
||
| Line 96: | Line 96: | ||
-------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- | ||
-- | -- Subgroup-based search | ||
-- Can support higher int limits than int-limit search can, provided the sub- | |||
-- | -- group is sufficiently small (about 10 members) | ||
-- | |||
function p.search_by_subgroup(subgroup, int_limit, equave) | function p.search_by_subgroup(subgroup, int_limit, equave) | ||
local subgroup = subgroup or { 2, 3, 7, 11 } | local subgroup = subgroup or { 2, 3, 7, 11 } | ||
local int_limit = int_limit or 50 | local int_limit = int_limit or 50 | ||
local equave = equave or | local equave = equave or {2,1} | ||
local | local possible_values = p.find_products(subgroup, int_limit) | ||
local ratios = p.find_ratios_using_values(possible_values, equave) | |||
local ratios = | |||
-- Convert to ratios that Module:Rational can work with | -- Convert to ratios that Module:Rational can work with | ||
| Line 163: | Line 115: | ||
end | end | ||
-- | -- Helper function | ||
-- Finds all eligible values for the numerator and denominator | |||
function p.find_products(factors, max_product) | function p.find_products(factors, max_product) | ||
local factors = factors or { 2, 3 | local factors = factors or { 2, 3, 7, 11 } | ||
local max_product = max_product or | local max_product = max_product or 50 | ||
-- Perform a breadth-first-search | -- Perform a breadth-first-search. | ||
-- Starting with the number 1 at the root node of a (simulated) search tree, | -- Starting with the number 1 at the root node of a (simulated) search tree, | ||
-- explore the possible products (child nodes) of multiplying that number | -- explore the possible products (child nodes) of multiplying that number | ||
| Line 176: | Line 129: | ||
-- plying by one of each factor. The search on any one branch stops if the | -- plying by one of each factor. The search on any one branch stops if the | ||
-- resulting products exceed that of the max product. | -- resulting products exceed that of the max product. | ||
-- Products are stored as a jagged array, where the index of each inner | |||
-- array is the search depth. Duplicate products are excluded. | |||
-- NOTE: the search starts with the number 1 for this operation to work. To | |||
-- make sense of this, this operation can be thought of a BFS for powers | |||
-- pi raising factors fi (f1^p1 * f2^p2 * ... * fn^pn), so 1 is where each | |||
-- factor fi is raised by zero, thus BFS increases the exponents by 1. | |||
local products = {{1}} | local products = {{1}} | ||
local new_products_found = true | local new_products_found = true | ||
| Line 184: | Line 143: | ||
local new_product = products[#products][j] * factors[i] | local new_product = products[#products][j] * factors[i] | ||
if new_product <= max_product then | if new_product <= max_product then | ||
local product_already_added = false | local product_already_added = false | ||
for k = 1, #new_products do | for k = 1, #new_products do | ||
| Line 216: | Line 173: | ||
return products | return products | ||
end | end | ||
-- Finds all potential ratios whose numerator and denominator is from the list | |||
-- of given values, and whose value, as a float, is between 1 and a given | |||
-- equave. | |||
function p.find_ratios_using_values(values, equave) | |||
local values = values or p.find_products() | |||
local equave = equave or { 2, 1 } | |||
local equave_as_float = equave[1]/equave[2] | |||
local ratios = {} | |||
for i = 1, #values do | |||
local denominator = values[i] | |||
for j = i, #values do | |||
local numerator = values[j] | |||
local gcd = utils._gcd(numerator, denominator) | |||
if gcd == 1 then | |||
local within_equave = numerator / denominator <= equave_as_float | |||
if within_equave then | |||
table.insert(ratios, {numerator, denominator}) | |||
else | |||
break | |||
end | |||
end | |||
end | |||
end | |||
return ratios | |||
end | |||
-------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- | ||
| Line 411: | Line 398: | ||
-- are present in the subgroup) takes several seconds to return only 1563 | -- are present in the subgroup) takes several seconds to return only 1563 | ||
-- results using these params: factors 2, 3, 7, 11; max product: 10 million. | -- results using these params: factors 2, 3, 7, 11; max product: 10 million. | ||
local factors = { 2, | local factors = { 2, 3 } | ||
local max_product = | local max_product = 5000 | ||
return p.ratios_as_text(p.search_by_subgroup(factors, max_product)) | return p.ratios_as_text(p.search_by_subgroup(factors, max_product, {3,1})) | ||
--return p.find_products(factors, max_product) | |||
end | end | ||
return p | return p | ||