#### Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

# Creating a factoring calculator

Posts: 15

Hey Codea,

I'm attempting to code a program that will factor polynomials. Firstly, though, I have created a program that finds the factors of the inputted number. If you know how to factor, this basically will be part of the "x-box" method. This is just the beginning of a big project I have in mind.

``````-- Factor

function setup()

parameter.integer("n", 0, 300, 0)
parameter.action("Factors", factor)
print("Factors of "..n.." are: ")
factorsList = { }
end

function factor()

i = 1
while(i <= n) do
if(n%i==0) then
print(i)
table.insert(factorsList, i)
end
i = i + 1
end
drawFactors = true
end

function draw()

background(40, 40, 50)
fill(172, 22, 22, 255)
rect(WIDTH/4, HEIGHT/4, 500, 400)
fill(255, 255, 255, 255)
fontSize(50)
text(n, WIDTH/2+50, 550)
for i = 1, #factorsList do
text(factorsList[i], WIDTH/2-50, HEIGHT/2)
end
end
``````

I would like to draw the factors in a list format (with commas and such), however, they are overlapping each other. Also, in the print command, I want to have it in pairs. I'm trying to do `for i,v in pairs(factorsList) do print(i,v) end` but v doesn't have any value. Is there a way to have pairs with a single variable like i? So if the input was 10, the output (print and/or text) should read 1 10, 2 5.

Tagged:

• edited November 2016 Posts: 8,687

@Zacharias Here's your code modified a little.

``````-- Factor

function setup()
parameter.integer("n", 0, 300, 0,factor)
factorsList = {}
end

function factor()
factorsList = {}
i = 1
while(i <= n) do
if(n%i==0) then
table.insert(factorsList, i)
end
i = i + 1
end
end

function draw()
background(40, 40, 50)
fill(172, 22, 22, 255)
fontSize(25)
text(n,WIDTH/2,HEIGHT-30)
for i = 1, #factorsList do
text(factorsList[i], WIDTH/2, HEIGHT-30*i-60)
end
end
``````
• Posts: 15

@dave1707 Thanks a lot! It serves its purpose well. Now I just have to figure how to use this with factoring polynomials. Should be fun • edited November 2016 Posts: 5,396

@Zacharias - your loop only needs to run from 2 (1 is always a factor) to the square root of n. That should make it much faster.

For example, take the number 24. Loop from 2 to 4 (integer of square root of 5).

2 is a factor, so 12 must be as well (since 24/2=12).

3 is a factor, so 8 must be too.

4 is a factor, so 6 must be too

Factors are 1, 2, 3, 4, 6, 8, 12

NB if you are going to want to factor primes, there are faster methods.

• Posts: 237

@Zacharias I believe a good way to do is something I learned last year in math class, I don't know if it is the best way or it even works, but search up the Gausse-Jordan method. It deals with matrices and solving and factoring polynomials. That's how I know graphing calculators are able to do that.

• Posts: 15

@Ignatz I see what you mean. When I figure out how to do the rest of the factoring and what not, I'll come back and optimize it.

@CamelCoder Thanks for the suggestion. It looks complex, and I'd like to use my already obtained knowledge of math for what I'm coding. Feel free to try it out, though.

• edited November 2016 Posts: 15

[resolved]

• edited November 2016 Posts: 15

[resolved]

• Posts: 51

Going back to Ignatz's idea, I'd go from 2 up to the square root on n, which gives you the first half of the factors, and then take that list and work backwards through it, dividing n by each factor, to get the second half of the list. Much, much faster than going all the way up to n if n is large.

• Posts: 15
Alright thanks @Ceres and @Ignatz. I'll try and use those instructions and implement them into the code. Will update code here.
• Posts: 15

So I added pseudo code to clarify parts and added some aesthetic (not much) to the program. I'm confused with changing the loop to 2, math.sqrt(ac) and what to do inside, so I left it for later. Here is what I have:

``````-- Factor

function setup()
--DISPLAY
displayMode(STANDARD)
supportedOrientations(LANDSCAPE_ANY)
--PARAMETERS
parameter.integer("a", 1, 1, 1)
parameter.integer("b", 0, 50, 5)
parameter.integer("c", 0, 50, 6)
parameter.text("term", "x")
parameter.action("Factor", factor)
--LISTS
factorsList = {}
drawFactors = {}
--VARIABLES
local ac
local factor1
local factor2
end

function factor()

ac = a * c
factorsList = {} -- list of factors
drawFactors = {} -- list of factors to draw

--DETERMING FACTORS OF AC AND INPUTTING FACTORS IN A LIST
i = 1
while(i <= ac) do
if(ac%i==0) then
table.insert(factorsList, i)
table.insert(drawFactors, i)
end
i = i + 1
end
--DETERMINING FACTORS FOR FACTORED FORM
for i=1, #drawFactors do
factor1 = tonumber(factorsList[#factorsList])
factor2 = tonumber(factorsList[#factorsList-(#factorsList-1)])

if((factor1 + factor2 == b) and (factor1 * factor2 == ac)) then
return
else
table.remove(factorsList, #factorsList)
table.remove(factorsList, #factorsList-(#factorsList-1))
end
end
end

function draw()
background(40, 40, 50)

for i = 1, #drawFactors do
--LIST OF FACTORS
fill(236, 236, 236 , 255)
fontSize(25)
text("Factors of "..ac, WIDTH/2-225, HEIGHT/2+350)
text(drawFactors[i], WIDTH/2-225, HEIGHT-30*i-60)
--AC AND B IN X, AND POLYNOMIAL/FACTORED FORMS AT BOTTOM
fill(172, 22, 22, 255)
fontSize(50)
text(""..ac.."", WIDTH/2, HEIGHT/2+75) --in the X
text(""..b.."", WIDTH/2, HEIGHT/2-75)  -- in the X
fontSize(35)
text(""..term.."^2 + "..b..term.." + "..c.."", WIDTH/2, HEIGHT/2-225) -- polynomial
text("("..term.." + "..factor1..")("..term.." + "..factor2..")", WIDTH/2, HEIGHT/2-300) --factored
--FACTORS FOR FACTORED FORM OF POLYNOMIAL
fill(41, 184, 20, 255)
fontSize(50)
text(""..factor1.."", WIDTH/2-75, HEIGHT/2) -- in the X
text(""..factor2.."", WIDTH/2+75, HEIGHT/2) -- in the X
end

--"POLYNOMIAL:/FACTORED:" AT BOTTOM
fill(236, 236, 236, 255)
fontSize(35)
text("Factored: ", WIDTH/2-173, HEIGHT/2-300)
--X LINES IN MIDDLE
lineCapMode(ROUND)
smooth()
strokeWidth(7)
line(WIDTH/2+100, HEIGHT/2+150, WIDTH/2-100, HEIGHT/2-150)
line(WIDTH/2-100, HEIGHT/2+150, WIDTH/2+100, HEIGHT/2-150)
end
``````
• Posts: 15

I also need to do complex polynomial so where a > 1. That program can only solve simple polynomials.

• Posts: 237

I was sort of getting a headache from making my game, i really do hate 3D. I thought I would take a break and make my own version of this calculator. I added a UI just because I didn't like the parameters. The UI is sort of bad because I in all spent about an hour on this program, so it will probably have errors. I would like to post the code, but I do not know how to post code on this forum. Can u please tell me what to do so I can post it

• edited November 2016 Posts: 8,687

@CamelCoder To post code in the forum, just select all of your code then copy it. After that, just paste the code in the forum. Put 3 ~'s on a line before and after your code so it formats correctly.

• edited November 2016 Posts: 237
``````That's what I did, but it said that my body (the post) had too many characters in it
``````
• Posts: 8,687

@CamelCoder If your code is too big then you can post it in github, or split your code into 2 or more posts.

• Posts: 5,396

@CamelCoder - but there is little point in posting your code if it is rushed and has errors and doesn't work properly. Why would we want to look at it?

• edited December 2016 Posts: 8,687

Here's an example that uses the quadratic equation to solve for X. Just change the X2, X1, X0 values and see the results as you change the values. An example is shown when the program is started.

EDIT: Corrected an error.

``````supportedOrientations(PORTRAIT_ANY)

function setup()
fontSize(30)
parameter.text("X2",0)
parameter.text("X1",0)
parameter.text("X0",0)
X2=8    -- for example only
X1=2
X0=-15
end

function draw()
background(0)
fill(255)
X2=tonumber(X2)
if X2=="" or X2==nil then
X2=0
end
strA=X2.."x^2"
X1=tonumber(X1)
if X1=="" or X1==nil then
X1=0
end
strB=X1.."x"
if X1>=0 then
strB="+"..X1.."x"
end
X0=tonumber(X0)
if X0=="" or X0==nil then
X0=0
end
strC=X0
if X0>=0 then
strC="+"..X0
end
solve()
text(strA..strB..strC.." = 0",WIDTH/2,HEIGHT-100)
text(str1,WIDTH/2,HEIGHT-200)
text(str2,WIDTH/2,HEIGHT-250)
end

function solve()
if X2=="" or X1=="" or X0=="" then
str1,str2="",""
else
str1="x = "..(-X1+math.sqrt(X1*X1-4*X2*X0))/(2*X2)
str2="x = "..(-X1-math.sqrt(X1*X1-4*X2*X0))/(2*X2)
end
end
``````
• edited December 2016 Posts: 237

@Ignatz Although it was rushed, I found it to have few errors. I don't know the cause because I didn't look into it that much. It still works great for the most part.  I fixed the error it had, now I hope you think it is worth looking at.
Here is the first part:

``````--# Main
-- MyFactorCalc
displayMode(FULLSCREEN)
supportedOrientations(ANY)
function setup()
arrows={upArrow={},downArrow={}}
for i=1,6 do table.insert(arrows.upArrow,Arrow{size=vec2(70,35)})
table.insert(arrows.downArrow,Arrow{size=vec2(70,35),angle=180}) end
factorButton=TextButton{text=string.upper("Factor"),pos=vec2(WIDTH/2,HEIGHT/8),
establishArrowFuncs()
end
function draw()
var=string.char(counter)
if cpos then varc=math.abs(varc) else varc=-math.abs(varc)end
if bpos then varb=math.abs(varb) else varb=-math.abs(varb)end
background(255, 255, 255, 255)
textMode(CENTER)
textAlign(CENTER)
fill(0, 45, 255, 255)
textWrapWidth(500)
fontSize(30)
text("Modify the variables, then click factor to factor the formula.",WIDTH/2,HEIGHT-100)
fontSize(50)
font("AmericanTypewriter-Bold")
fill(0)
local s=getString(vara,varb,varc,var)
text(s,WIDTH/2,HEIGHT*3/4)
textWrapWidth(-1)
text(txt,WIDTH/2,HEIGHT/4)
drawSelections()
for i,v in pairs(arrows) do
for n,m in ipairs(v) do
if m.counter and m.counter>1.2 then
if math.floor(m.counter*25)%2==0 then m.func(BEGAN) end
end
end
end
factorButton:draw()
end
function factor(a,b,c)
txt="Factoring..."
local signb,signc=sign(b),sign(c)
local mm=math.greatestCommonFactor(a,b)
local m=math.abs(math.greatestCommonFactor(mm,c))
a,b,c=a/m,b/m,c/m
local ac=a*c
local factors=math.findAllFactors(ac)
local sol
for i,v in ipairs(factors) do
for n,m in ipairs(factors) do
if i~=n or #factors==1 then
if m+v==b and m*v==ac then
sol=vec2(m,v)
elseif -m+v==b and -m*v==ac then
sol=vec2(-m,v)
elseif m-v==b and m*-v==ac then
sol=vec2(m,-v)
elseif -m-v==b and -m*-v==ac then
sol=vec2(-m,-v)
end
end
end
end
if sol then
local function func(a,b,sol,s)
local gcf=math.greatestCommonFactor
local aa=gcf(a,sol.x)
local bb=gcf(b,sol.y)
local cc=gcf(a,sol.y)
local dd=gcf(b,sol.x)
local ab=math.abs(aa)+math.abs(bb)
local cd=math.abs(cc)+math.abs(dd)
local soll=vec2(aa,bb)
if not s or s==1 then
if ab<cd and sign(cc)~=-1 or sign(aa)==-1 then soll=vec2(cc,dd) end elseif s==2 then
soll=vec2(cc,dd) end
return soll:unpack()
end
local tt
::place::
local aa,cc=func(a,c,vec2(sol.y,sol.x),tt)
local f=a/aa
local ff=sol.x/aa
if cc*ff~=c and ff==-1 then
ff=2
end
if sign(aa)==-1 then
aa=-aa
f=-f
ff=-ff
end
if not (aa*f==a and (cc*f)+(aa*ff)==b and cc*ff==c) then
tt=2
goto place
end
txt=getFactoredString(aa,cc,f,ff,m)
else txt="NOT FACTORABLE"
if m~=1 then
txt=tostring(m).."("..getString(a,b,c,var)..")"
end
end
end

function drawSelections()
local tab={
{txt="a",tag="math.floor(vara)"},{txt="+/-",tag="stringSign(varb)"},
{txt="b",tag="math.floor(math.abs(varb))"},{txt="+/-",tag="stringSign(varc)"},
{txt="c",tag="math.floor(math.abs(varc))"},{txt="var.",tag="var"}}
for i,v in ipairs(tab) do
pushStyle()
local a=color(255,0,0)
if i==2 or i==3 then a=color(0,0,255)
elseif i==4 or i==5 then a=color(67, 255, 0, 255)
elseif i==6 then a=color(0, 255, 223, 255) end
fill(0)
fontSize(30)
textMode(CENTER)
local pos=vec2(WIDTH*i/(#tab+1),HEIGHT/2+150)
text(tostring(v.txt),pos:unpack())
pos.y=HEIGHT/2-30
fill(a)
rectMode(CENTER)
rect(pos.x,pos.y,100,100)
fill(255)
fontSize(55)
arrows.upArrow[i].pos.x=pos.x
arrows.upArrow[i].pos.y=pos.y+90
arrows.upArrow[i]:draw()
arrows.downArrow[i].pos.x=pos.x
arrows.downArrow[i].pos.y=pos.y-90
arrows.downArrow[i]:draw()
popStyle()
end
end

function establishArrowFuncs()
local s=ENDED
arrows.upArrow.func=function(a)if a==s then vara=vara+1;saveLocalData("vara",vara) end end
arrows.downArrow.func=function(a)if a==s then vara=math.max(vara-1,1)saveLocalData("vara",vara) end end
arrows.upArrow.func=function(a)if a==s then bpos=not bpos;saveLocalData("bpos",bpos) end end
arrows.downArrow.func=function(a)if a==s then bpos=not bpos;saveLocalData("bpos",bpos) end end
arrows.upArrow.func=function(a)if a==s then varb=math.abs(varb)+1;saveLocalData("varb",varb) end end
arrows.downArrow.func=function(a)if a==s then varb=math.max(math.abs(varb)-1,0)saveLocalData("varb",varb) end end
arrows.upArrow.func=function(a)if a==s then cpos=not cpos;saveLocalData("cpos",cpos) end end
arrows.downArrow.func=function(a)if a==s then cpos=not cpos;saveLocalData("cpos",cpos) end end
arrows.upArrow.func=function(a)if a==s then varc=math.abs(varc)+1;saveLocalData("varc",varc) end end
arrows.downArrow.func=function(a)if a==s then varc=math.max(math.abs(varc)-1,0)saveLocalData("varc",varc) end end
arrows.downArrow.func=function(a)if a==s then
counter=counter+1
if counter>122 then counter=97 end
saveLocalData("counter",counter)
end
end
arrows.upArrow.func=function(a)if a==s then
counter=counter-1
if counter<97 then counter=122 end
saveLocalData("counter",counter)
end
end
end

function touched(t)
for i,v in pairs(arrows) do
for n,m in ipairs(v) do
if m:touched(t) then txt="" end
end
end
factorButton:touched(t)
if factorButton.state==ENDED then
factor(vara,varb,varc)
end
end

function orientationChanged(o)
if factorButton then factorButton.pos=vec2(WIDTH/2,HEIGHT/8) end
end
``````
• edited December 2016 Posts: 237

Here is the second part:

``````--# Math
function math.findAllFactors(n)
local factors={}
for i=1,math.abs(n) do
local a=n/i
if a==math.floor(a) then
table.insert(factors,math.floor(i*sign(a)))
if a==i then
table.insert(factors,math.floor(i*sign(a)))
end
end
end
return factors
end

function math.greatestCommonFactor(a,b)
local ans=1
for i,v in pairs(math.findAllFactors(a)) do
for n,m in pairs(math.findAllFactors(b)) do
if v==m or -v==-m then
ans=v
elseif -v==m or v==-m then
ans=-v
end
end
end
return ans
end

function sign(x)
if x==x and x~=0 then
return x/math.abs(x)
end
return(0)
end
--# String
function stringSign(a) if a<0 then return "-" end return "+" end

function getString(a,b,c,x)
local space=string.rep(" ",2)
local s=""
local function concatVals(n,pow)
if n~=0 then
local a=tostring(math.floor(math.abs(n)))
local p=""
local t=stringSign(n)
if pow>=1 then
if a=="1" then a="" end
p=x if pow==2 then p=p.."²"t="" end end
s=s..t..space..a..p..space
end
end
concatVals(a,2)
concatVals(b,1)
concatVals(c,0)
return s
end

function getFactoredString(fo,fi,li,lo,m)
local space=string.rep(" ",2)
local s=""
if m~=1 then s=s..tostring(m) end
if fi~=0 then s=s.."(" end
if fo~=1 then s=s..tostring(math.floor(fo)) end
s=s..var
if fi~=0 then s=s..space..stringSign(fi)..space..tostring(math.floor(math.abs(fi)))..")" end
if lo~=0 then s=s.."(" end
if li~=1 then s=s..tostring(math.floor(li)) end
s=s..var
if lo~=0 then s=s..space..stringSign(lo)..space..tostring(math.floor(math.abs(lo)))..")" end
if string.sub(s,1+string.len(m),math.ceil(string.len(s)/2))
==string.sub(s,math.ceil(string.len(s)/2)+1,string.len(s)) then
s=string.sub(s,1,math.ceil(string.len(s)/2)).."²"
end
return s
end
--# Arrow
Arrow=class()

function Arrow:init(args)args=args or {}
self.strokeWidth=args.strokeWidth or 20
self.stroke=args.stroke or color(0, 0, 0, 255)
self.ang=args.angle or 0
self.size=args.size or vec2(200,200)
self.pos=args.pos or vec2(0,0)
self.lineCapMode=args.lineCapMode or ROUND
self.func=args.func or function()end
self.counter=nil
end

function Arrow:draw()
pushMatrix()
pushStyle()
translate(self.pos.x,self.pos.y)
rotate(self.ang)
lineCapMode(self.lineCapMode)
strokeWidth(self.strokeWidth)
stroke(self.stroke)
for i=-1,1,2 do
line(self.size.x/2*i,-self.size.y/2,0,self.size.y/2)
end
if self.counter then self.counter = self.counter + DeltaTime end
popStyle()
popMatrix()
end

function Arrow:touched(touch)
local shift=vec2(0,10)
if touch.x>self.pos.x-self.size.x/2-shift.x and touch.y>self.pos.y-self.size.y/2-shift.y and touch.x<self.pos.x+self.size.x/2+shift.x
and touch.y<self.pos.y+self.size.y/2+shift.y then
if touch.state==BEGAN then self.counter=0 elseif touch.state==ENDED then self.counter=nil end
self.func(touch.state)
return true
end
return false
end
--# TextButton
TextButton=class()

function TextButton:init(args)args=args or {}
self.font=args.font or nil
self.fontSize=args.fontSize or 50
self.fill=args.fill or color(0)
self.txt=args.text or ""
self.pos=args.pos or vec2(0,0)
self.w,self.h=0,0
end

function TextButton:draw()
pushStyle()
textMode(CENTER)
textAlign(CENTER)
fill(self.fill)
if self.font then font(self.font) end
fontSize(self.fontSize)
self.w,self.h=textSize(self.txt)
text(self.txt,self.pos:unpack())
popStyle()
end

function TextButton:touched(t)
if t.x>self.pos.x-self.w/2 and t.x<self.pos.x+self.w/2 and t.y>self.pos.y-self.h/2 and t.y<self.pos.y+self.h/2 then
self.state=t.state
else
self.state=nil
end
end
``````
• Posts: 8,687

@CamelCoder Nice job. One question, you don't allow the first variable for x^2 to be negative.

• Posts: 237

@dave1707 Thanks! Ya, I just didn't want to mess up the technique I used. Honestly, what I did was just thought about how I would factor a normal equation, and told the computer to do the same. That's probably why it's not too efficient. If you want, feel free to change it, I think that the leading coefficient shouldn't be negative.

• Posts: 8,687

@CamelCoder I'm not going to modify your code, but the leading coefficient could be negative as much as it could be positive. If the leading coefficient is negative, then there are 2 sets of answers. They're the same set of numbers, just with the signs flipped. Maybe I'll try writing something similar and see what I come up with. It's always good to see different coding styles.

• Posts: 5,396

Assuming you wrote this for fun, I have no criticism, because it's good practice - but if intended for practical use, I would far rather enter a series of numbers such as 43,-345,12,3 and have the program factor them. This allows as many numbers as you like, positive or negative, and if you want to enter 187, you don't have to press an arrow key 187 separate times.

• Posts: 8,687

@Ignatz I think 99% of the programs written here are for fun or by new coders just trying to learn how to write programs. If it's a program someone wants to make some money from, they may write it in Codea, but they're not going to post it here. Any program written can be improved upon by someone else. Pressing the up or down arrows to change a number could take awhile depending on the number, but it was an interesting idea anyways. Maybe a change could be if you press and hold the up/down arrows, the number starts changing until you lift your finger.

• edited December 2016 Posts: 237

@Ignatz I didn't intend on making a UI aside from the parameters, but I just wanted to go a bit further, that's why it is awful. I will modify the code to make it possible to hold the arrow and zoom through the numbers.  I have added the ability to hold on the arrows to get to the number quicker

• Posts: 8,687

Here's another version. Tap a box and input the values then tap Solve.

``````displayMode(FULLSCREEN)
supportedOrientations(LANDSCAPE_ANY)

function setup()
rectMode(CENTER)
fontSize(30)
ans={}
tab={}
table.insert(tab,box(400,600,150,50,0,"x^2"))
table.insert(tab,box(525,600,100,50,0,"x"))
table.insert(tab,box(625,600,100,50,0,""))
table.insert(tab,box(WIDTH/2,500,150,50,"","Solve"))
end

function draw()
background(0)
fill(255)
for a,b in pairs(tab) do
b:draw()
end
if #ans==0 then
text("No solution found.",WIDTH/2,HEIGHT/2)
else
for a,b in pairs(ans) do
v1=string.format("%d",b.x)
v2=string.format("%+d",b.y)
v3=string.format("%d",b.z)
v4=string.format("%+d",b.w)
text("("..v1.."x"..v2..") ("..v3.."x"..v4..")",WIDTH/2,HEIGHT/2-a*50+100)
end
end
end

function touched(t)
for a,b in pairs(tab) do
b:touched(t)
end
end

function keyboard(k)
for a,b in pairs(tab) do
b:keyboard(k)
end
end

function solve()
ans={}
t1=vals(a)
t2=vals(c)
cnt=0
for a1=1,#t1 do
for a2=1,#t2 do
for b1=1,#t1 do
for b2=1,#t2 do
aa=t1[a1]*t1[b1]
bb=t1[a1]*t2[b2]+t1[b1]*t2[a2]
cc=t2[a2]*t2[b2]
if aa==a and bb==b and cc==c then
cnt=cnt+1
if a<0 and cnt<3 or a>0 and cnt<2 then
table.insert(ans,vec4(t1[a1],t2[a2],t1[b1],t2[b2]))
end
end
end
end
end
end
end

function vals(v)
local t={}
for z=1,math.abs(v) do
if math.abs(v)%z==0 then
table.insert(t,z)
if v<0 then
table.insert(t,-z)
end
end
end
return t
end

box=class()

function box:init(x,y,w,h,v,s)
self.x=x
self.y=y
self.w=w
self.h=h
self.v=v
self.s=s
self.sel=false
end

function box:draw()
fill(255)
if self.sel then
fill(0, 255, 88, 255)
end
rect(self.x,self.y,self.w,self.h)
fill(0, 141, 255, 255)
str=""
if string.sub(self.v,1,1)~="-" then
str="+"
if self.s=="x^2" or self.s=="Solve" then
str=""
end
end
text(str..self.v..self.s,self.x,self.y)
end

function box:touched(t)
if t.state==BEGAN then
ans={}
self.sel=false
if t.x>self.x-self.w/2 and t.x<self.x+self.w/2 and
t.y>self.y-self.h/2 and t.y<self.y+self.h/2 then
if self.s=="Solve" then
a=tonumber(tab.v)
b=tonumber(tab.v)
c=tonumber(tab.v)
hideKeyboard()
if a==nil or b==nil or c==nil then
return
end
solve()
else
self.sel=true
self.v=""
showKeyboard()
end
end
end
end

function box:keyboard(k)
if k>="0" and k<="9" or k=="-" or k=="+" or k==BACKSPACE then
if self.sel then
if k==BACKSPACE then
self.v=string.sub(self.v,1,#self.v-1)
end
self.v=self.v..k
end
end
end
``````
• Posts: 237

@dave1707 I'm sorry to say, but every equation I would type in would give me no solution found.

• Posts: 8,687

@CamelCoder Try 3x^2+13x-10 or 6x^2+11x-10 or -6x^2+19x-15.

• Posts: 15

I'm glad my little post sparked some inspiration. @CamelCoder I enjoyed your UI. I have lots of diff ideas of projects and learning how to do UI like yours seems prudent. Thanks @dave1707 for that program. Some don't work but it's definitely better than mine

• Posts: 8,687

@Zacharias I didn't post the program to be better than yours, I posted it to show a different style and for others to learn from it. Everyone has a different style of coding and I still learn from others even though I've been coding for what seems like forever. You said some don't work, but not every equation will have factors. Do you have any examples of equations that should work and don't. As for your code sparking interest, yes it did. I'm working on a program that will factor equations such as x^3+x^2+x+#=0 and even higher orders.

• Posts: 15
@dave1707 Oh I know that. I just admire your work. And I just realized right now I wasn't changing a to 1 in your code. Totally my fault (I was checking your code late at night). Great work on the factoring by grouping. The code works! (:
• Posts: 8,687

Here's a program that will factor third order equations like 1x3-5x2+2x+8 . Just enter 1,-5,2,8 in the parameter text area and press Factor. I included 6 examples to try. If there are more factors then the screen will show, just slide them up. I didn't spend a lot of time making it fancy, so if you want you can do it.

``````function setup()
print("-24,72,-18,-30")
print("15,109,25,-21")
print("6,-33,-27,54")
print("1,-5,2,8")
print("1,-3,-4,12")
print("455,675,145,-75")
dy=0
sh={}
tab={}
delay=0
fontSize(30)
p2=string.char(194)..string.char(178)
p3=string.char(194)..string.char(179)
parameter.text("nbrs")
parameter.action("Factor",createTab)
fill(255)
end

function factor()
t1=vals(tab)
t2=vals(tab)
solve()
yy={}
for z=1,#n1 do
tt=order(n1[z],n2[z],n3[z])
table.insert(yy,toInt(tt).."  "..toInt(tt).."  "..toInt(tt))
end
table.sort(yy)
h=""
sh={}
for z=1,#yy do
if yy[z]~=h then
table.insert(sh,yy[z])
h=yy[z]
end
end
end

function createTab()
tab={}
sh={}
delay=0
str=""
for z=1,#nbrs do
val=string.sub(nbrs,z,z)
if val=="," then
table.insert(tab,tonumber(str))
str=""
else
str=str..val
end
end
table.insert(tab,tonumber(str))
nbrs=""
end

function draw()
background(0)
if #tab>0 then
delay=delay+1
fill(255)
s2,s3,s4="","",""
if tab>=0 then
s2="+"
end
if tab>=0 then
s3="+"
end
if tab>=0 then
s4="+"
end
text(tab.."x"..p3..s2..tab.."x"..p2..s3..tab.."x"..s4..tab,
WIDTH/2,HEIGHT-50+dy)
if #sh==0 then
end
for a,b in pairs(sh) do
text(a.."   "..b,WIDTH/2,HEIGHT-70-a*50+dy)
end
else
text("If factors go off bottom, slide them up.",WIDTH/2,HEIGHT/2)
end
if delay==4 then
showKeyboard()
hideKeyboard()
factor()
end
end

function order(a,b,c)
local tab={a}
if b.x<=a.x then
table.insert(tab,1,b)
else
table.insert(tab,2,b)
end
if c.x<=tab.x then
table.insert(tab,1,c)
elseif c.x<=tab.x then
table.insert(tab,2,c)
else
table.insert(tab,3,c)
end
return tab
end

function toInt(a)
aa=math.tointeger(a.x)
bb=math.tointeger(a.y)
bp=""
if bb>=0 then
bp="+"
end
return("("..aa.."x"..bp..bb..")")
end

function solve()
n1,n2,n3={},{},{}
for a=1,#t2 do
for b=1,#t1 do
for c=1,#t2 do
for d=1,#t1 do
for e=1,#t2 do
for f=1,#t1 do
aa=t2[a]*t2[c]*t2[e]
bb=t2[e]*t2[a]*t1[d]+t2[e]*t2[c]*t1[b]+t1[f]*t2[a]*t2[c]
cc=t2[e]*t1[b]*t1[d]+t1[f]*t2[a]*t1[d]+t1[f]*t2[c]*t1[b]
dd=t1[b]*t1[d]*t1[f]
if aa==tab and bb==tab and
cc==tab and dd==tab then
table.insert(n1,vec2(t2[a],t1[b]))
table.insert(n2,vec2(t2[c],t1[d]))
table.insert(n3,vec2(t2[e],t1[f]))
end
end
end
end
end
end
end
end

function vals(v)
local t={}
for z=1,math.abs(v) do
if math.abs(v)%z==0 then
table.insert(t,-z)
table.insert(t,z)
end
end
return t
end

function touched(t)
if t.state==MOVING then
dy=dy+t.deltaY
if dy<0 then
dy=0
end
end
end
``````
• Posts: 110

@dave1707 with your quadratic factoring calculator, you didn't allow for -ve value, so I just (inelegantly) tweaked it:

``````--# Main
displayMode(FULLSCREEN)
supportedOrientations(LANDSCAPE_ANY)

function setup()
rectMode(CENTER)
fontSize(30)
ans={}
tab={}
table.insert(tab,box(400,600,150,50,0,"x^2"))
table.insert(tab,box(525,600,100,50,0,"x"))
table.insert(tab,box(625,600,100,50,0,""))
table.insert(tab,box(WIDTH/2,500,150,50,"","Solve"))
end

function draw()
background(0)
fill(255)
for a,b in pairs(tab) do
b:draw()
end
if #ans==0 then
text("No solution found.",WIDTH/2,HEIGHT/2)
else
for a,b in pairs(ans) do
v1=string.format("%d",b.x)
v2=string.format("%+d",b.y)
v3=string.format("%d",b.z)
v4=string.format("%+d",b.w)
text("("..v1.."x"..v2..") ("..v3.."x"..v4..")",WIDTH/2,HEIGHT/2-a*50+100)
end
end
end

function touched(t)
for a,b in pairs(tab) do
b:touched(t)
end
end

function keyboard(k)
for a,b in pairs(tab) do
b:keyboard(k)
end
end

function solve()
ans={}
t1=vals(a)
t2=vals(c)
cnt=0
for a1=1,#t1 do
for a2=-#t1,#t2 do
for b1=-#t1,#t1 do
for b2=-#t2,#t2 do
aa=t1[a1]*t1[b1]
bb=t1[a1]*t2[b2]+t1[b1]*t2[a2]
cc=t2[a2]*t2[b2]
if aa==a and bb==b and cc==c then
cnt=cnt+1
if a<0 and cnt<3 or a>0 and cnt<2 then
table.insert(ans,vec4(t1[a1],t2[a2],t1[b1],t2[b2]))
end
end
end
end
end
end
end

function vals(v)
local t={}
t=0
for z=1,math.abs(v) do
if math.abs(v)%z==0 then
table.insert(t,z)
if v<0 then
table.insert(t,-z)
end
end
end
for i=1,#t do
t[-i]=-t[i]
end
return t
end

box=class()

function box:init(x,y,w,h,v,s)
self.x=x
self.y=y
self.w=w
self.h=h
self.v=v
self.s=s
self.sel=false
end

function box:draw()
fill(255)
if self.sel then
fill(0, 255, 88, 255)
end
rect(self.x,self.y,self.w,self.h)
fill(0, 141, 255, 255)
str=""
if string.sub(self.v,1,1)~="-" then
str="+"
if self.s=="x^2" or self.s=="Solve" then
str=""
end
end
text(str..self.v..self.s,self.x,self.y)
end

function box:touched(t)
if t.state==BEGAN then
ans={}
self.sel=false
if t.x>self.x-self.w/2 and t.x<self.x+self.w/2 and
t.y>self.y-self.h/2 and t.y<self.y+self.h/2 then
if self.s=="Solve" then
a=tonumber(tab.v)
b=tonumber(tab.v)
c=tonumber(tab.v)
hideKeyboard()
if a==nil or b==nil or c==nil then
return
end
solve()
else
self.sel=true
self.v=""
showKeyboard()
end
end
end
end

function box:keyboard(k)
if k>="0" and k<="9" or k=="-" or k=="+" or k==BACKSPACE then
if self.sel then
if k==BACKSPACE then
self.v=string.sub(self.v,1,#self.v-1)
end
self.v=self.v..k
end
end
end
``````
• Posts: 8,687

@MattthewLXXIII Thanks for the fix. I think I ran into that error when I did the next program for third order equations. The way I fixed it there was in the function vals() where I always created - values instead of checking for v<0 before creating them.