Advertisement
iconmaster

chembal.lua

Sep 18th, 2015
313
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 5.92 KB | None | 0 0
  1. local isSolid = {
  2.     ["Ba"]={},
  3.     ["Cl"]={},
  4.     ["Cu"]={},
  5.     ["SO_4"]={
  6.         ["Ca"]=true,
  7.         ["Ba"]=true
  8.     },
  9.     ["Ca"]={},
  10.     ["Na"]={},
  11.     ["CO_3"]={
  12.         ["Ba"]=true,
  13.         ["Cl"]=true,
  14.         ["Cu"]=true,
  15.         ["SO_4"]=true,
  16.         ["Ca"]=true,
  17.         ["CO_3"]=true,
  18.         ["OH"]=true,
  19.         ["S"]=true,
  20.     },
  21.     ["OH"]={
  22.         ["Cl"]=true,
  23.         ["Cu"]=true,
  24.         ["SO_4"]=true,
  25.         ["CO_3"]=true,
  26.         ["OH"]=true,
  27.         ["S"]=true,
  28.     },
  29.     ["S"]={
  30.         ["Ba"]=true,
  31.         ["Cl"]=true,
  32.         ["Cu"]=true,
  33.         ["SO_4"]=true,
  34.         ["Ca"]=true,
  35.         ["CO_3"]=true,
  36.         ["OH"]=true,
  37.         ["S"]=true,
  38.     },
  39.     ["NH_4"]={}
  40. }
  41.  
  42. for i,v in pairs(isSolid) do
  43.     for ii,vv in pairs(v) do
  44.         isSolid[ii][i] = vv
  45.     end
  46. end
  47.  
  48. local charges = {["Ba"]=2, ["Cl"]=-1, ["Cu"]=2, ["SO_4"]=-2, ["Ca"]=2, ["Na"]=1, ["CO_3"]=-2, ["OH"]=-1, ["S"]=-2, ["NH_4"]=1}
  49.  
  50. local complex = {["SO_4"]=true, ["CO_3"]=true, ["OH"]=true, ["NH_4"]=true}
  51.  
  52. local function gcd(a, b)
  53.     if b == 0 then
  54.         return a
  55.     else
  56.         return gcd(b, a % b)
  57.     end
  58. end
  59.  
  60. function lcm(...)
  61.     local function lcm2(a, b)
  62.         return (a * b / gcd(a, b))
  63.     end
  64.    
  65.     local args = {...}
  66.  
  67.     if #args == 2 then
  68.         return lcm2(args[1], args[2])
  69.     else
  70.         local arg0 = table.remove(args,1)
  71.         return lcm2(arg0, lcm(unpack(args)))
  72.     end
  73. end
  74.  
  75. local function chemamt(c1, c2)
  76.     local n = gcd(math.abs(charges[c1]), math.abs(charges[c2]))
  77.     return math.abs(charges[c2]/n), math.abs(charges[c1]/n)
  78. end
  79.  
  80. local function isaq(c1, c2)
  81.     return not isSolid[c1][c2]
  82. end
  83.  
  84. local function chemname(c1, c2, m)
  85.     local n1, n2 = chemamt(c1, c2)
  86.    
  87.     return  ((complex[c1] and n1 ~= 1) and "(" or "") .. c1 .. ((complex[c1] and n1 ~= 1) and ")" or "") .. (n1 == 1 and "" or ("_" .. n1))
  88.             ..
  89.             ((complex[c2] and n2 ~= 1) and "(" or "") .. c2 .. ((complex[c2] and n2 ~= 1) and ")" or "") .. (n2 == 1 and "" or ("_" .. n2))
  90.             ..
  91.             (isaq(c1, c2) and " (aq)" or " (s)")
  92. end
  93.  
  94. local function ionsname(c1, c2, m)
  95.     local n1, n2 = chemamt(c1, c2)
  96.     m = m or 1
  97.     n1 = n1 * m; n2 = n2 * m
  98.    
  99.     return  "" ..
  100.             (n1 ~= 1 and n1 or "") .. c1 .. "^{" .. (math.abs(charges[c1]) == 1 and "" or math.abs(charges[c1])) .. (charges[c1] < 0 and "-" or "+") .. "} (aq)"
  101.             .. " + " ..
  102.             (n2 ~= 1 and n2 or "") .. c2 .. "^{" .. (math.abs(charges[c2]) == 1 and "" or math.abs(charges[c2])) .. (charges[c2] < 0 and "-" or "+") .. "} (aq)"
  103. end
  104.  
  105. local function chembal(c1, c2, c3, c4)
  106.     local a, b = chemamt(c1, c2)
  107.     local c1s = {a, b, chemamt(c3, c4)}
  108.     c, b = chemamt(c3, c2)
  109.     local a, d = chemamt(c1, c4)
  110.     local c2s = {a, b, c, d}
  111.    
  112.     local mults = {1, 1, 1, 1}
  113.    
  114.     while true do
  115.         local done = true
  116.        
  117.         for i,lhs in ipairs({unpack(c1s)}) do
  118.             local rhs = c2s[i]
  119.             if lhs ~= rhs then
  120.                 done = false
  121.                
  122.                 local fact = lcm(lhs, rhs)
  123.                 local f1, f2 = fact/lhs, fact/rhs
  124.                
  125.                 if i == 1 then
  126.                     mults[1] = mults[1] * f1
  127.                     c1s[1] = c1s[1] * f1
  128.                     c1s[2] = c1s[2] * f1
  129.                    
  130.                     mults[4] = mults[4] * f2
  131.                     c2s[1] = c2s[1] * f2
  132.                     c2s[4] = c2s[4] * f2
  133.                 elseif i == 2 then
  134.                     mults[1] = mults[1] * f1
  135.                     c1s[1] = c1s[1] * f1
  136.                     c1s[2] = c1s[2] * f1
  137.                    
  138.                     mults[3] = mults[3] * f2
  139.                     c2s[2] = c2s[2] * f2
  140.                     c2s[3] = c2s[3] * f2
  141.                 elseif i == 3 then
  142.                     mults[2] = mults[2] * f1
  143.                     c1s[3] = c1s[3] * f1
  144.                     c1s[4] = c1s[4] * f1
  145.                    
  146.                     mults[3] = mults[3] * f2
  147.                     c2s[2] = c2s[2] * f2
  148.                     c2s[3] = c2s[3] * f2
  149.                 elseif i == 4 then
  150.                     mults[2] = mults[2] * f1
  151.                     c1s[3] = c1s[3] * f1
  152.                     c1s[4] = c1s[4] * f1
  153.                    
  154.                     mults[4] = mults[4] * f2
  155.                     c2s[1] = c2s[1] * f2
  156.                     c2s[4] = c2s[4] * f2
  157.                 end
  158.                
  159.                 break
  160.             end
  161.         end
  162.        
  163.         if done then
  164.             --[[mults = {
  165.                 mults[1]/gcd(mults[1],gcd(mults[2],mults[3]))/gcd(mults[1],gcd(mults[3],mults[4]))/gcd(mults[1],gcd(mults[2],mults[4])),
  166.                 mults[2]/gcd(mults[2],gcd(mults[3],mults[4]))/gcd(mults[2],gcd(mults[1],mults[4]))/gcd(mults[2],gcd(mults[1],mults[3])),
  167.                 mults[3]/gcd(mults[3],gcd(mults[2],mults[1]))/gcd(mults[3],gcd(mults[1],mults[4]))/gcd(mults[3],gcd(mults[2],mults[4])),
  168.                 mults[4]/gcd(mults[4],gcd(mults[1],mults[2]))/gcd(mults[4],gcd(mults[1],mults[3]))/gcd(mults[4],gcd(mults[2],mults[3]))
  169.             }]]
  170.             return unpack(mults)
  171.         end
  172.     end
  173. end
  174.  
  175. local function equation1(c1, c2, c3, c4)
  176.     local m1, m2, m3, m4 = chembal(c1, c2, c3, c4)
  177.     return  (m1 == 1 and "" or (m1 .. " ")) .. chemname(c1, c2)
  178.             .. " + " ..
  179.             (m2 == 1 and "" or (m2 .. " ")) .. chemname(c3, c4)
  180.             .. " \\rightarrow " ..
  181.             (m3 == 1 and "" or (m3 .. " ")) .. chemname(c3, c2)
  182.             .. " + " ..
  183.             (m4 == 1 and "" or (m4 .. " ")) .. chemname(c1, c4)
  184. end
  185.  
  186. local function equation2(c1, c2, c3, c4)
  187.     local m1, m2, m3, m4 = chembal(c1, c2, c3, c4)
  188.     return  (isaq(c1, c2) and ionsname(c1, c2, m1) or ((m1 == 1 and "" or (m1 .. " ")) .. chemname(c1, c2)))
  189.             .. " + " ..
  190.             (isaq(c3, c4) and ionsname(c3, c4, m2) or ((m2 == 1 and "" or (m2 .. " ")) .. chemname(c3, c4)))
  191.             .. " \\rightarrow " ..
  192.             (isaq(c3, c2) and ionsname(c3, c2, m3) or ((m3 == 1 and "" or (m3 .. " ")) .. chemname(c3, c2)))
  193.             .. " + " ..
  194.             (isaq(c1, c4) and ionsname(c1, c4, m4) or ((m4 == 1 and "" or (m4 .. " ")) .. chemname(c1, c4)))
  195. end
  196.  
  197. local function equation3(c1, c2, c3, c4)
  198.     local m1, m2, m3, m4 = chembal(c1, c2, c3, c4)
  199.     if not isaq(c3, c2) then
  200.         return ionsname(c3, c2, m3) .. " \\rightarrow " .. (m3 == 1 and "" or (m3 .. " ")) .. chemname(c3, c2)
  201.     elseif not isaq(c1, c4) then
  202.         return ionsname(c1, c4, m4) .. " \\rightarrow " .. (m4 == 1 and "" or (m4 .. " ")) .. chemname(c1, c4)
  203.     else
  204.         return "ERROR"
  205.     end
  206. end
  207.  
  208. local chems = {{"Ba", "Cl"}, {"Cu", "SO_4"}, {"Ca", "Cl"}, {"Na", "CO_3"}, {"Na", "OH"}, {"Na", "S"}, {"NH_4", "OH"}}
  209.  
  210. for i,v in ipairs(chems) do
  211.     for ii,vv in ipairs(chems) do
  212.         if i<ii then
  213.             local c1, c2, c3, c4 = v[1], v[2], vv[1], vv[2]
  214.             io.write(i.."+"..ii..":\t")
  215.             --if not isaq(c3, c2) or not isaq(c1, c4) then
  216.                 print(equation1(c1,c2,c3,c4))
  217.                 print("\t"..equation2(c1,c2,c3,c4))
  218.                 print("\t"..equation3(c1,c2,c3,c4))
  219.             --else
  220.             --  print("NR")
  221.             --end
  222.         end
  223.     end
  224. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement