Advertisement
King0fGamesYami

[WIP]Solver

Oct 23rd, 2015
198
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 3.55 KB | None | 0 0
  1. local LCF, constant
  2.  
  3. --Thanks to Xtansia for synthetic division function!
  4. --https://gist.github.com/Xtansia/e4e30318b890ea1dfdfe
  5. local function synthetic_division (polynomial, divisor_factor)
  6.     local degree = table.maxn(polynomial)
  7.     local work_table = {
  8.         [degree] = polynomial[degree]
  9.     }
  10.  
  11.     for i = degree - 1, 0, -1 do
  12.         work_table[i] = (polynomial[i] or 0) + work_table[i + 1] * divisor_factor
  13.     end
  14.  
  15.     local result = {}
  16.     local remainder = work_table[0]
  17.  
  18.     for i = 1, table.maxn(work_table) do
  19.         result[i - 1] = work_table[i]
  20.     end
  21.  
  22.     return result, remainder
  23. end
  24.  
  25. local function polynomial_tostring(polynomial)
  26.     local degree = table.maxn(polynomial)
  27.     local str = ""
  28.     for i = degree, 0, -1 do
  29.         local coeff = polynomial[i] or 0
  30.         local abs_coeff = math.abs(coeff)
  31.         if abs_coeff > 0 then
  32.             if i == degree then
  33.                 str = str .. (coeff < 0 and "-" or "")
  34.             else
  35.                 str = str .. " " .. (coeff > 0 and "+" or "-") .. " "
  36.             end
  37.             if i > 0 then
  38.                 str = str .. (abs_coeff > 1 and abs_coeff or "") .. "x"
  39.                 if i > 1 then
  40.                     str = str .. "^" .. i
  41.                 end
  42.             else
  43.                 str = str .. abs_coeff
  44.             end
  45.         end
  46.     end
  47.     return str
  48. end
  49.  
  50. local tArgs = {...}
  51. local equation = table.concat( tArgs, "" ):gsub( " ", "" )
  52. local synthetic_equation = {}
  53.  
  54. equation = equation:gsub( "%-x", "-1x" ):gsub( "^%d?x", "1x" ):gsub( "%+x", "+1x" )
  55.  
  56. local degree = 0
  57.  
  58. for sign, coef, x, power in equation:gmatch( "([%+%-]?)(%d+)(x?)%^?(%d*)" ) do
  59.     power = tonumber( power ) or (x == "x" and 1 or 0)
  60.     if sign == "-" then
  61.         coef = -tonumber( coef )
  62.     else
  63.         coef = tonumber( coef )
  64.     end
  65.     if power and (power > degree) then
  66.         degree = power
  67.         LCF = coef
  68.     end
  69.     if tonumber( power ) == 0 then
  70.         constant = coef
  71.     end
  72.     synthetic_equation[ power ] = coef
  73. end
  74.  
  75. constant = constant or 0
  76.  
  77. print( "Generating Factors of LCF" )
  78. local LCF_factors = {}
  79. for i = 1, math.abs( LCF ) do
  80.     if LCF % i == 0 then
  81.         LCF_factors[ #LCF_factors + 1 ] = i
  82.     end
  83. end
  84.  
  85. print( "Generating Factors of constant" )
  86. local constant_factors = {}
  87. for i = 1, math.abs( constant ) do
  88.     if constant % i == 0 then
  89.         constant_factors[ #constant_factors + 1 ] = i
  90.     end
  91. end
  92. if constant == 0 then
  93.     constant_factors[ # constant_factors + 1 ] = 0
  94. end
  95.  
  96. print( "Generating Possible Real Solutions" )
  97. local real_solutions = {}
  98. local _real = {}
  99. for k, l in pairs( LCF_factors ) do
  100.     for k, c in pairs( constant_factors ) do
  101.         if not _real[ c/l ] then
  102.             real_solutions[ #real_solutions + 1 ] = c/l
  103.             _real[ c/l ] = true
  104.         end
  105.     end
  106. end
  107.  
  108. print( "Generating Solutions" )
  109. solutions = {}
  110.  
  111. for k, v in pairs( real_solutions ) do
  112.     local e = equation:gsub( 'x', '*(' .. v .. ')' )
  113.     local eneg = equation:gsub( 'x', '*(' .. -v .. ')' )
  114.     if loadstring( "return " .. e )() == 0 then
  115.         solutions[ #solutions + 1 ] = v
  116.         print( v )
  117.     end
  118.    
  119.     if v ~= 0 and loadstring( "return " .. eneg )() == 0 then
  120.         solutions[ #solutions + 1 ] = -v
  121.         print( -v )
  122.     end
  123. end
  124.  
  125. if #solutions ~= degree then
  126.     print( "Generating Imaginary Soltions" )
  127.     local eq, rem = synthetic_equation
  128.     local deg = degree
  129.     for k, v in pairs( solutions ) do
  130.         eq, rem = synthetic_division( eq, v )
  131.     end
  132.     print( polynomial_tostring( eq ) )
  133.     if table.maxn( eq ) ~= 2 then
  134.         error( "Unable to compute imaginary solutions", 0 )
  135.     end
  136.     local a, b, c = eq[ 2 ] or 0, eq[ 1 ] or 0, eq[ 0 ] or 0
  137.     --[[ (-b +- sqrt( b^2 - 4*a*c ) ) / 2 *a ]]--
  138.     local root = math.sqrt( math.abs(b^2 - 4*a*c) )
  139.     solution1 = -b / (2*a) .. "+" .. root / (2*a) .. "i"
  140.     solution2 = -b / (2*a) .. "-" .. root / (2*a) .. "i"
  141.     print( solution1 )
  142.     print( solution2 )
  143. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement