Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- local isSolid = {
- ["Ba"]={},
- ["Cl"]={},
- ["Cu"]={},
- ["SO_4"]={
- ["Ca"]=true,
- ["Ba"]=true
- },
- ["Ca"]={},
- ["Na"]={},
- ["CO_3"]={
- ["Ba"]=true,
- ["Cl"]=true,
- ["Cu"]=true,
- ["SO_4"]=true,
- ["Ca"]=true,
- ["CO_3"]=true,
- ["OH"]=true,
- ["S"]=true,
- },
- ["OH"]={
- ["Cl"]=true,
- ["Cu"]=true,
- ["SO_4"]=true,
- ["CO_3"]=true,
- ["OH"]=true,
- ["S"]=true,
- },
- ["S"]={
- ["Ba"]=true,
- ["Cl"]=true,
- ["Cu"]=true,
- ["SO_4"]=true,
- ["Ca"]=true,
- ["CO_3"]=true,
- ["OH"]=true,
- ["S"]=true,
- },
- ["NH_4"]={}
- }
- for i,v in pairs(isSolid) do
- for ii,vv in pairs(v) do
- isSolid[ii][i] = vv
- end
- end
- 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}
- local complex = {["SO_4"]=true, ["CO_3"]=true, ["OH"]=true, ["NH_4"]=true}
- local function gcd(a, b)
- if b == 0 then
- return a
- else
- return gcd(b, a % b)
- end
- end
- function lcm(...)
- local function lcm2(a, b)
- return (a * b / gcd(a, b))
- end
- local args = {...}
- if #args == 2 then
- return lcm2(args[1], args[2])
- else
- local arg0 = table.remove(args,1)
- return lcm2(arg0, lcm(unpack(args)))
- end
- end
- local function chemamt(c1, c2)
- local n = gcd(math.abs(charges[c1]), math.abs(charges[c2]))
- return math.abs(charges[c2]/n), math.abs(charges[c1]/n)
- end
- local function isaq(c1, c2)
- return not isSolid[c1][c2]
- end
- local function chemname(c1, c2, m)
- local n1, n2 = chemamt(c1, c2)
- return ((complex[c1] and n1 ~= 1) and "(" or "") .. c1 .. ((complex[c1] and n1 ~= 1) and ")" or "") .. (n1 == 1 and "" or ("_" .. n1))
- ..
- ((complex[c2] and n2 ~= 1) and "(" or "") .. c2 .. ((complex[c2] and n2 ~= 1) and ")" or "") .. (n2 == 1 and "" or ("_" .. n2))
- ..
- (isaq(c1, c2) and " (aq)" or " (s)")
- end
- local function ionsname(c1, c2, m)
- local n1, n2 = chemamt(c1, c2)
- m = m or 1
- n1 = n1 * m; n2 = n2 * m
- return "" ..
- (n1 ~= 1 and n1 or "") .. c1 .. "^{" .. (math.abs(charges[c1]) == 1 and "" or math.abs(charges[c1])) .. (charges[c1] < 0 and "-" or "+") .. "} (aq)"
- .. " + " ..
- (n2 ~= 1 and n2 or "") .. c2 .. "^{" .. (math.abs(charges[c2]) == 1 and "" or math.abs(charges[c2])) .. (charges[c2] < 0 and "-" or "+") .. "} (aq)"
- end
- local function chembal(c1, c2, c3, c4)
- local a, b = chemamt(c1, c2)
- local c1s = {a, b, chemamt(c3, c4)}
- c, b = chemamt(c3, c2)
- local a, d = chemamt(c1, c4)
- local c2s = {a, b, c, d}
- local mults = {1, 1, 1, 1}
- while true do
- local done = true
- for i,lhs in ipairs({unpack(c1s)}) do
- local rhs = c2s[i]
- if lhs ~= rhs then
- done = false
- local fact = lcm(lhs, rhs)
- local f1, f2 = fact/lhs, fact/rhs
- if i == 1 then
- mults[1] = mults[1] * f1
- c1s[1] = c1s[1] * f1
- c1s[2] = c1s[2] * f1
- mults[4] = mults[4] * f2
- c2s[1] = c2s[1] * f2
- c2s[4] = c2s[4] * f2
- elseif i == 2 then
- mults[1] = mults[1] * f1
- c1s[1] = c1s[1] * f1
- c1s[2] = c1s[2] * f1
- mults[3] = mults[3] * f2
- c2s[2] = c2s[2] * f2
- c2s[3] = c2s[3] * f2
- elseif i == 3 then
- mults[2] = mults[2] * f1
- c1s[3] = c1s[3] * f1
- c1s[4] = c1s[4] * f1
- mults[3] = mults[3] * f2
- c2s[2] = c2s[2] * f2
- c2s[3] = c2s[3] * f2
- elseif i == 4 then
- mults[2] = mults[2] * f1
- c1s[3] = c1s[3] * f1
- c1s[4] = c1s[4] * f1
- mults[4] = mults[4] * f2
- c2s[1] = c2s[1] * f2
- c2s[4] = c2s[4] * f2
- end
- break
- end
- end
- if done then
- --[[mults = {
- 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])),
- 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])),
- 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])),
- 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]))
- }]]
- return unpack(mults)
- end
- end
- end
- local function equation1(c1, c2, c3, c4)
- local m1, m2, m3, m4 = chembal(c1, c2, c3, c4)
- return (m1 == 1 and "" or (m1 .. " ")) .. chemname(c1, c2)
- .. " + " ..
- (m2 == 1 and "" or (m2 .. " ")) .. chemname(c3, c4)
- .. " \\rightarrow " ..
- (m3 == 1 and "" or (m3 .. " ")) .. chemname(c3, c2)
- .. " + " ..
- (m4 == 1 and "" or (m4 .. " ")) .. chemname(c1, c4)
- end
- local function equation2(c1, c2, c3, c4)
- local m1, m2, m3, m4 = chembal(c1, c2, c3, c4)
- return (isaq(c1, c2) and ionsname(c1, c2, m1) or ((m1 == 1 and "" or (m1 .. " ")) .. chemname(c1, c2)))
- .. " + " ..
- (isaq(c3, c4) and ionsname(c3, c4, m2) or ((m2 == 1 and "" or (m2 .. " ")) .. chemname(c3, c4)))
- .. " \\rightarrow " ..
- (isaq(c3, c2) and ionsname(c3, c2, m3) or ((m3 == 1 and "" or (m3 .. " ")) .. chemname(c3, c2)))
- .. " + " ..
- (isaq(c1, c4) and ionsname(c1, c4, m4) or ((m4 == 1 and "" or (m4 .. " ")) .. chemname(c1, c4)))
- end
- local function equation3(c1, c2, c3, c4)
- local m1, m2, m3, m4 = chembal(c1, c2, c3, c4)
- if not isaq(c3, c2) then
- return ionsname(c3, c2, m3) .. " \\rightarrow " .. (m3 == 1 and "" or (m3 .. " ")) .. chemname(c3, c2)
- elseif not isaq(c1, c4) then
- return ionsname(c1, c4, m4) .. " \\rightarrow " .. (m4 == 1 and "" or (m4 .. " ")) .. chemname(c1, c4)
- else
- return "ERROR"
- end
- end
- local chems = {{"Ba", "Cl"}, {"Cu", "SO_4"}, {"Ca", "Cl"}, {"Na", "CO_3"}, {"Na", "OH"}, {"Na", "S"}, {"NH_4", "OH"}}
- for i,v in ipairs(chems) do
- for ii,vv in ipairs(chems) do
- if i<ii then
- local c1, c2, c3, c4 = v[1], v[2], vv[1], vv[2]
- io.write(i.."+"..ii..":\t")
- --if not isaq(c3, c2) or not isaq(c1, c4) then
- print(equation1(c1,c2,c3,c4))
- print("\t"..equation2(c1,c2,c3,c4))
- print("\t"..equation3(c1,c2,c3,c4))
- --else
- -- print("NR")
- --end
- end
- end
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement