Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- function replace(string,pattern,replace)
- for i = 1,#string do
- if string:sub(i,i) == pattern:sub(1,1) then
- word = ""
- word = string:sub(i,i)
- for n=1,#pattern do
- if string:sub(i+n,i+n) == pattern:sub(1+n,1+n) then
- word = word..string:sub(i+n,i+n)
- end
- end
- if #word==#pattern then
- local p1 = string:sub(1,i-1)
- local p2 = string:sub(i+#pattern)
- result = p1..p2
- --i,i+n
- end
- end
- end
- return result
- end
- known = {
- vx = 50,
- v0x = 10,
- ax = 10,
- x0 = 0,
- find = "x",
- equation = "vx^2=v0x^2+2ax(x-x0)",
- vars = {'vx','v0x','ax','x','x0'},
- }
- function replaceKnownVars(tVars,equation)
- --"y=mx+b" --> "(50)=(10)x+(5)"
- local sOutput = equation
- for i,v in pairs(tVars) do
- if tonumber(v) then
- --replace known vars with values
- sOutput = sOutput:gsub(i,"("..v..")")
- end
- end
- --[[
- local simplifyAnswer = function(equation)
- local left,right = equalSplit(equation)
- loadstring("i="..left)()
- equation = tostring(i).."="..right
- return equation
- end]]
- --sOutput = simplifyAnswer(sOutput)
- return sOutput
- end
- function addImplicitOperators(equation)
- --"(50)=(10)(30)x+2(5)" --> "(50)=+(10)*(30)x+2*(5)"
- local sOutput = equation
- -- adds + to first base
- addPlus = function(sOutput)
- local char1 = sOutput:sub(sOutput:find("=")+1,sOutput:find("=")+1)
- if char1~="-" and char1~="+" then
- local p1 = sOutput:sub(1,sOutput:find("="))
- local p2 = sOutput:sub(sOutput:find("=")+1)
- sOutput = p1.."+"..p2
- end
- return sOutput
- end
- sOutput = addPlus(sOutput)
- addAsterisks = function(right)
- --input right side of equation
- --output = input with * inbetween
- for i = 1,#right do
- if right:sub(i,i) == "(" then
- if right:sub(i-1,i-1) then
- if tonumber(right:sub(i-1,i-1)) or right:sub(i-1,i-1) == ")" then
- local p1 = right:sub(1,i-1)
- local p2 = right:sub(i)
- right = p1.."*"..p2
- addAsterisks(right)
- end
- end
- --parenthesis = parenthesis + 1
- --elseif right:sub(i,i) == ")" then
- --parenthesis = parenthesis - 1
- end
- end
- return right
- end
- sOutput = addAsterisks(sOutput)
- return sOutput
- end
- local function simplifyAnswer(equation)
- --50^2=(10+20)x+(50*2) --> 2500=30x+100+1200
- local left,right = equalSplit(equation)
- loadstring("l="..left)()
- right = right:gsub("%((%A.-)%)",
- function(inbetween)
- loadstring("r="..inbetween)()
- return r
- end
- )
- equation = tostring(l).."="..right
- return equation
- end
- local function equalSplit(equation)
- --returns 2 halves of equation
- local eq = equation:find("=")
- local left = equation:sub(1,eq-1)
- local right = equation:sub(eq+1,#equation)
- return left,right
- end
- local function find(equation,listOfChars)
- local occurences = {}
- local parenthesisIgnore = 0
- for i,v in pairs(listOfChars) do
- for n = 1, #equation do
- local check = equation:sub(n,n)
- if check == "(" then
- parenthesisIgnore = parenthesisIgnore + 1
- elseif check == ")" then
- parenthesisIgnore = parenthesisIgnore - 1
- elseif check == v and parenthesisIgnore == 0 then
- table.insert(occurences,n)
- end
- end
- end
- return occurences
- end
- local function splitBases(equation)
- --right side of equation
- equation = equation:sub(equation:find("=")+1,#equation)
- --add + to bases
- --if equation:sub(1,1) ~= "-" then
- --equation = "+"..equation
- --end
- local occurences = find(equation,{"-","+"})
- local bases = {}
- --local parenthesis = find(equation,{"(",")"})
- table.sort(occurences)
- for i = 1,(#occurences) do
- if i == (#occurences) then
- table.insert(bases,equation:sub(occurences[i]))
- else
- table.insert(bases,equation:sub(occurences[i],occurences[i+1]-1))
- end
- end
- return occurences,bases
- end
- function BaseAS(equation)
- local sOutput = equation
- local occurences,bases = splitBases(sOutput)
- local left,right = equalSplit(sOutput)
- local opposites = {}
- --sOutput = addPlus(sOutput)
- --add/subtract to left
- for i,v in pairs(bases) do
- if v:sub(1,1) == "-" then
- opposites[i] = "+"..v:sub(2)
- elseif v:sub(1,1) == "+" then
- opposites[i] = "-"..v:sub(2)
- else
- opposites[i] = "-"..v
- end
- end
- for i,v in pairs(opposites) do
- left,right = equalSplit(sOutput)
- if not v:find("%a") then
- loadstring("a="..left..v)()
- left = a
- end
- end
- --delete from right
- left,right = equalSplit(sOutput)
- for i,v in pairs(bases) do
- if not v:find("%a") then
- right = replace(right,v)
- end
- end
- sOutput = left.."="..right
- return sOutput
- end
- function BaseMD(equation)
- --bases p/e
- local result = equation
- local left,right = equalSplit(equation)
- local parenthesis = 0
- local bases = {}
- local baseLoc = {}
- local basealt = {}
- for i = 1,#right do
- if right:sub(i,i) == "(" then
- parenthesis = parenthesis + 1
- elseif right:sub(i,i) == ")" then
- parenthesis = parenthesis - 1
- elseif right:sub(i,i) == "*" and parenthesis == 0 then
- table.insert(baseLoc,i)
- end
- end
- table.insert(baseLoc,1)
- table.sort(baseLoc)
- for i =1,#baseLoc do
- if i == (#baseLoc) then
- table.insert(bases,right:sub(baseLoc[i]+1))
- else
- table.insert(bases,right:sub(baseLoc[i]+1,baseLoc[i+1]-1))
- end
- end
- local copy = equation
- local parenthesis = 0
- --multiply/divide to left
- --local opposites = {}
- for i,v in pairs(bases) do
- --left = left/( v )
- if not v:find("%a") then
- v = v:gsub("(%+)","")
- loadstring("lj="..left.."/("..v..")")()
- left = lj
- end
- end
- for i,v in pairs(bases) do
- if not v:find("%a") then
- bases[i] = nil
- local lk = replace(right,v)
- right = lk
- end
- end
- --old result
- --result = left.."="..right
- --base reconstruction based result
- --[[turn tBases into a string in order of indexes]]
- local sConstructor = ""
- for i,v in pairs(bases) do
- sConstructor = sConstructor..v
- end
- sConstructor = addAsterisks(sConstructor)
- result = left.."="..sConstructor
- return result
- end
- function unknownVarsAmount(known,equation)
- local vars = known.vars
- local unknown = {}
- print(equation)
- for i,v in ipairs(vars) do
- if equation:find(v) then
- table.insert(unknown,v)
- end
- end
- return #unknown
- end
- function pemdas(equation)
- local left,right = equalSplit(equation) --take right side of equation
- local sOutput = nil --points to function
- local tOutput = {0}
- --iterate through right
- local parenthesis = 0
- for i = 1,#right do
- local char = right:sub(i,i)
- local backchar = right:sub(i-1,i-1) or ""
- --looking for outermost in parenthesis
- if char == "(" then
- parenthesis = parenthesis+1
- elseif char == ")" then
- parenthesis = parenthesis-1
- elseif parenthesis==0 then
- if (char == "+" or char == "-") and (backchar ~= "*" and backchar ~= "/" and backchar ~= "^" and i~=1) then
- --negative exponent fix
- sOutput = "BaseAS"
- table.insert(tOutput,3)
- --implicit + handled within that other function
- elseif char == "*" or char == "/" then
- sOutput = "BaseMD"
- table.insert(tOutput,2)
- elseif char == "^" then
- sOutput = "BaseEXP"
- table.insert(tOutput,1)
- end
- end
- --looking for +,-,^,/,*
- --looking for implicit +,*
- end
- --higher number takes precedence
- table.sort(tOutput, function(a,b) return a>b end)
- if tOutput[1] == 3 then
- sOutput = "BaseAS"
- elseif tOutput[1] == 2 then
- sOutput = "BaseMD"
- elseif tOutput[1] == 1 then
- sOutput = "BaseEXP"
- elseif tOutput[1] == 0 then
- sOutput = nil
- else
- error("unexpected value in tOutput")
- end
- --print(table.concat(tOutput,", "))
- --print(math.max(=(table.concat(tOutput,", ")))
- --print(math.max(tOutput))
- if not sOutput then
- breakParenthesis = function(right)
- --input right side of equation
- local finished = false
- local output = ""
- if right:sub(1,1) == "(" and right:sub(#right,#right) == ")" then
- output = right:sub(2,#right-1)
- else
- --error("no outer parenthesis detected",2)
- --lets assume this means its correct ie no operators or parentheses
- output = right
- finished = true
- end
- return output,finished
- end
- local finishCheck = false
- right,finishCheck = breakParenthesis(right)
- if finishCheck then
- sOutput = "finished"
- else
- sOutput = "nextLayer"
- end
- end
- equation = left.."="..right
- return sOutput,equation
- end
- function AlgebraStep(prevRes)
- --input equation with 1 unknown
- --output equation with 1 step worked out
- local nextStep,nextLayer = pemdas(prevRes)
- local sEquation = nil
- if nextStep == "BaseAS" then
- sEquation = BaseAS(prevRes)
- elseif nextStep == "BaseMD" then
- sEquation = BaseMD(prevRes)
- elseif nextStep == "nextLayer" then
- sEquation = nextLayer
- elseif nextStep == "finished" then
- return "FINISHED"
- end
- if sEquation then
- return sEquation
- else
- error("nextStep = "..nextStep,2)
- end
- end
- function repeatAlgebra(equation,nStep)
- local equation2 = equation
- local neq = nStep or 1
- while true do
- equation2 = AlgebraStep(equation2)
- if equation2 ~= "FINISHED" then
- print(equation2," : step"..tostring(neq))
- neq = neq+1
- else
- neq = neq - 1
- print("Finished with "..neq.." steps")
- break
- end
- end
- end
- function solve(known,equation)
- local sOutput = equation
- local neq = 1
- sOutput = replaceKnownVars(known,equation)
- if unknownVarsAmount(known,sOutput) > 1 then
- error("too many unknown vars")
- end
- while true do
- sOutput = addImplicitOperators(sOutput)
- print("impOPs = "..sOutput)
- sOutput = simplifyAnswer(sOutput)
- print("simpFy = "..sOutput)
- sOutput = AlgebraStep(sOutput)
- if sOutput ~= "FINISHED" then
- print(sOutput," : step"..tostring(neq))
- neq = neq+1
- else
- neq = neq - 1
- print("Finished with "..neq.." steps")
- break
- end
- end
- end
- --print(addImplicitOperators("(50)=2(23)(43)+2"))
- --print(simplifyAnswer("(50)^2=+(25*36)+(743-123)/(x/72)"))
- shell.run("clr")
- function testRepeatAlgebra()
- print(known.equation)
- local step1 = replaceKnownVars(known,known.equation)
- print(step1.." : replaceKnownVars")
- local step2 = addImplicitOperators(step1)
- print(step2.." : addImplicitOps")
- local step3 = simplifyAnswer(step2)
- print(step3.." : simplifyAnswer")
- repeatAlgebra(step3)
- --solve(known,known.equation)
- end
- testRepeatAlgebra()
- --solve(known,known.equation)
- --solve(known,"125=(x-0)")
- --[[
- print(step1.." : replaceKnownVars")
- local step2 = addImplicitOperators(step1)
- print(step2.." : addImplicitOps")
- local step3 = simplifyAnswer(step2)
- print(step3.." : simplifyAnswer")
- local equation2 = step3
- local neq = 4
- repeatAlgebra(equation2,5,neq)
- ]]
- --[[print(pemdas(step3))
- equation2 = AlgebraStep(equation2)
- print(equation2," : step"..tostring(neq))
- neq = neq+1
- equation2 = AlgebraStep(equation2)
- print(equation2," : step"..tostring(neq))
- neq = neq+1
- equation2 = AlgebraStep(equation2)
- print(equation2," : step"..tostring(neq))
- neq = neq+1
- equation2 = AlgebraStep(equation2)
- print(equation2," : step"..tostring(neq))
- neq = neq+1
- equation2 = AlgebraStep(equation2)
- print(equation2," : step"..tostring(neq))
- neq = neq+1
- ]]
- --local step5 = BaseMD(step4)
- --print(step5.." : BaseMD")
- --print("result="..nextStep.."(\""..prevRes.."\")")
- --loadstring("result="..nextStep.."(\""..prevRes.."\")")()
- --loadstring("result=BaseAS(step3)")()
- --print(result)
- --[[
- print(result)
- local step4 = BaseAS(step3)
- print(step4.." : BaseAS")
- --print(pemdas(step4))
- local t,step6 = pemdas(step5)
- print(step6.." : "..t)
- local step7 = BaseAS(step6)
- print(step7.." : BaseAS")
- result=BaseAS(step3)
- ]]--
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement