Page 1 of 3

Lua Algebra Solver help?

Posted: February 13th, 2015, 3:12 pm
by revolt4peace
I would like to create a lua script in a rainmeter skin that would solve an equation such as x^2+3x=-2 or 3x+5=14 or even more complex (but still simple algebra (including trigonometric functions such as cos, sin, and tan)) equations. The only problem is, I have no idea how to do this.

My only idea so far is to create something that checks how long the input string is, then creates a two dimensional matrix that keeps track of what kind of character each one is, as well as important things such as if it is inside parenthesis or not (I would like support for distributive property), and then decides the first step to get x by itself on one side of the =. It would then change the string, and re-evaluate until it got to a simple x=#.

I would love feedback on if this method is even feasible, and any ideas would be much appreciated!

Thanks in advance to anyone who helps! :thumbup:

Re: Lua Algebra Solver help?

Posted: February 15th, 2015, 9:01 pm
by balala
I've started to work with your idea and here's what I reached:
Equation.ini:

Code: Select all

[Rainmeter]
Update=-1
BackgroundMode=2
SolidColor=80,80,80,220

[Variables]
Equation=x^2+8x+12=0

[MeasureLuaScript]
Measure=Script
ScriptFile=Script.lua

[MeterColor]
Meter=STRING
X=0
Y=0
Padding=15,5,15,5
FontColor=255,255,255
FontEffectColor=0,0,0
StringEffect=Shadow
FontSize=10
FontFace=Segoe UI
StringStyle=BOLD
StringAlign=LEFT
AntiAlias=1
Text=#Equation##CRLF##Res1##CRLF##Res2#
DynamicVariables=1
Script.lua:

Code: Select all

function Initialize()
	Equation = SKIN:GetVariable('Equation')
	a, b, c = '', '', ''
	n = 0
	Coefficients = {}
	for i=1,#Equation do
		Coefficients[i] = '0'
	end
	for i = 1,#Equation do
		Coefficients[i] = string.sub(Equation, i, i)
	end
	i = 0
	repeat
		i = i + 1
	until ((( Coefficients[i] == 'x' ) and ( Coefficients[i+1] == '^' ) and ( Coefficients[i+2] == '2' )) or i == #Equation)
	if i < #Equation then
		for i = 1,#Equation do
			if ( Coefficients[i] == 'x' ) and ( Coefficients[i+1] == '^' ) and ( Coefficients[i+2] == '2' ) then
				if i-1 >= 1 then
					for j = 1,(i-1) do
						a = a .. Coefficients[j]
					end
				end
				if i-1 < 1 then
					a = '1'
				end
				n = i + #a + 2
			end
		end
		for i = 1,#Equation do
			if ( Coefficients[i] == 'x' ) and ( Coefficients[i+1] ~= '^' ) then
				for j = n,(i-1) do
					b = b .. Coefficients[j]
				end
				n = i+1
			end
		end
		for i = 1,#Equation do
			if Coefficients[i] == '=' then
				for j = n,(i-1) do
					c = c .. Coefficients[j]
				end
				n = i+1
			end
		end
		a, b, c = tonumber(a), tonumber(b), tonumber(c)
		if Delta(a, b, c) >= 0 then
			SKIN:Bang('!SetVariable', 'Res1', 'x1='..(math.floor(Result1(a, b, c))+(math.floor(100*(Result1(a, b, c)-math.floor(Result1(a, b, c)))))/100))
			SKIN:Bang('!SetVariable', 'Res2', 'x2='..(math.floor(Result2(a, b, c))+(math.floor(100*(Result2(a, b, c)-math.floor(Result2(a, b, c)))))/100))
		else
			SKIN:Bang('!SetVariable', 'Res1', 'This equation has no real solutions.')
			SKIN:Bang('!SetVariable', 'Res2', '')
		end
	else
		for i = 1,#Equation do
			if Coefficients[i] == 'x' then
				for j = 1,(i-1) do
					a = a .. Coefficients[j]
				end
				n = i+1
			end
		end
		for i = 1,#Equation do
			if Coefficients[i] == '=' then
				for j = n,(i-1) do
					b = b .. Coefficients[j]
				end
				n = i+1
			end
		end
		a, b = tonumber(a), tonumber(b)
		SKIN:Bang('!SetVariable', 'Res1', 'x='..(-b/a))
		SKIN:Bang('!SetVariable', 'Res2', '')
	end
end

function Delta(a, b, c)
	return (b*b - 4*a*c)
end

function Result1(a, b, c)
	return ((-b-math.sqrt(Delta(a, b, c)))/(2*a))
end

function Result2(a, b, c)
	return ((-b+math.sqrt(Delta(a, b, c)))/(2*a))
end

function Update()
end
This skin can handle the first and second degree equation. The first must have this form: eg 6x-12=0, the second: x^2-3x+2=0. Until now other forms are not accepted (eg 2+x^2-3x=0 or x^2-3x=-2). I'm not very good in lua scripting, I hope you'll not laughing on a such convoluted code. Maybe someone much better than me will help us.

Re: Lua Algebra Solver help?

Posted: February 15th, 2015, 11:01 pm
by revolt4peace
Thank you so much for this! This will definitely help me get started, as I know almost nothing in lua (yet). This is not the end solution, but this is definitely a large step in the right direction. :D

Re: Lua Algebra Solver help?

Posted: February 16th, 2015, 2:12 pm
by balala
revolt4peace wrote:Thank you so much for this! This will definitely help me get started, as I know almost nothing in lua (yet). This is not the end solution, but this is definitely a large step in the right direction. :D
There's a very good lua online book: http://www.lua.org/pil/contents.html
I think you should use it in your work.

Re: Lua Algebra Solver help?

Posted: February 16th, 2015, 2:20 pm
by jsmorley
In my view, this is going to be a "Manhattan Project" / "boiling the oceans" level of effort...

https://github.com/simoncozens/cassowary.lua
https://github.com/simoncozens/cassowary.lua/blob/master/cassowary.lua

Be aware that we don't support .require or .dofile in our implementation of Lua / Rainmeter, so you would need that entire thousands of line of function code in your .lua file. I have not looked at it closely to see if there are other issues with using it in our environment, I mostly just wanted to give a sense of the level of effort.

Re: Lua Algebra Solver help?

Posted: February 16th, 2015, 2:40 pm
by revolt4peace
Don't worry about the amount of effort I will need to put into this, I'm ready. I'm used to making code that is easily 10K lines. Thanks for the help! I'll take a look at this code you gave me and see what's up.

:D

Re: Lua Algebra Solver help?

Posted: February 16th, 2015, 2:43 pm
by jsmorley
Glad to help. I'm walking away from this now, and not looking back. Hands in pockets, whistling nervously.

Re: Lua Algebra Solver help?

Posted: February 16th, 2015, 3:33 pm
by revolt4peace
Just so you know, balala, there was one error with your code.

I changed

Code: Select all

SKIN:Bang('!SetVariable', 'Res1', 'x1='..(math.floor(Result1(a, b, c))+(math.floor(100*(Result1(a, b, c)-math.floor(Result1(a, b, c)))))/100))
         SKIN:Bang('!SetVariable', 'Res2', 'x2='..(math.floor(Result2(a, b, c))+(math.floor(100*(Result2(a, b, c)-math.floor(Result2(a, b, c)))))/100))
to

Code: Select all

SKIN:Bang('!SetVariable', 'Res1', 'x1='..(-(math.floor(Result1(a, b, c))+(math.floor(100*(Result1(a, b, c)-math.floor(Result1(a, b, c)))))/100)))
         SKIN:Bang('!SetVariable', 'Res2', 'x2='..(-(math.floor(Result2(a, b, c))+(math.floor(100*(Result2(a, b, c)-math.floor(Result2(a, b, c)))))/100)))
because the results were negative when they were supposed to be positive, and positive when they were meant to be negative.

Thanks again for the (quite large) step in the right direction!

Re: Lua Algebra Solver help?

Posted: February 16th, 2015, 3:43 pm
by balala
revolt4peace wrote:Just so you know, balala, there was one error with your code.
Sorry for that, but I hope you got the idea.

Re: Lua Algebra Solver help?

Posted: February 16th, 2015, 5:14 pm
by revolt4peace
When I say:

Code: Select all

 if Coefficients[5] < '10' and Coefficients[5] >= '0' then
It does not read the '10' or '0' as numbers, so you would think I would simply change '10' to 10 and '0' to 0, and it would all work. But when I do remove the '' then the code stops working at all. Why is this, how do I fix it, and is there a better way to check if something is a number, rather than another character?