It is currently March 28th, 2024, 12:53 pm

Lua Algebra Solver help?

Discuss the use of Lua in Script measures.
User avatar
revolt4peace
Posts: 83
Joined: February 3rd, 2015, 4:36 pm

Lua Algebra Solver help?

Post 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:
User avatar
balala
Rainmeter Sage
Posts: 16109
Joined: October 11th, 2010, 6:27 pm
Location: Gheorgheni, Romania

Re: Lua Algebra Solver help?

Post 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.
User avatar
revolt4peace
Posts: 83
Joined: February 3rd, 2015, 4:36 pm

Re: Lua Algebra Solver help?

Post 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
User avatar
balala
Rainmeter Sage
Posts: 16109
Joined: October 11th, 2010, 6:27 pm
Location: Gheorgheni, Romania

Re: Lua Algebra Solver help?

Post 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.
User avatar
jsmorley
Developer
Posts: 22628
Joined: April 19th, 2009, 11:02 pm
Location: Fort Hunt, Virginia, USA

Re: Lua Algebra Solver help?

Post 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.
User avatar
revolt4peace
Posts: 83
Joined: February 3rd, 2015, 4:36 pm

Re: Lua Algebra Solver help?

Post 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
User avatar
jsmorley
Developer
Posts: 22628
Joined: April 19th, 2009, 11:02 pm
Location: Fort Hunt, Virginia, USA

Re: Lua Algebra Solver help?

Post by jsmorley »

Glad to help. I'm walking away from this now, and not looking back. Hands in pockets, whistling nervously.
User avatar
revolt4peace
Posts: 83
Joined: February 3rd, 2015, 4:36 pm

Re: Lua Algebra Solver help?

Post 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!
Last edited by revolt4peace on February 16th, 2015, 5:12 pm, edited 2 times in total.
User avatar
balala
Rainmeter Sage
Posts: 16109
Joined: October 11th, 2010, 6:27 pm
Location: Gheorgheni, Romania

Re: Lua Algebra Solver help?

Post 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.
User avatar
revolt4peace
Posts: 83
Joined: February 3rd, 2015, 4:36 pm

Re: Lua Algebra Solver help?

Post 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?
Post Reply