-- A B A Logique Nspire -- Louis DURAND (c) 2009-2011 -- FRANCE 54 -- Participation au concours Lua TI Planet/Inspired Lua 2011. -- Commence le 05/07/2011 (jour des resultats du BAC ! :D) -- Termine le 02/09/2011 -- Des morceaux de code Basic ont ete repris de mon ABA Logique pour TI 89. -- Revision pour OS 3.2 en 11/2012 et 07-08/2013 -- Changement majeur : moteur de simplification algebrique remplace par une simplification par tableaux de Karnaugh. function on.create() if math.eval("true => true") then os31=false else os31=true end n=0 gui=string.uchar(34) diff=string.uchar(8800) accent=string.uchar(233) timer.start(0.1) chg={0,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1,5,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1,6,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1,5,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1} gray="000001011010110111101100" var.store("chg",chg) hist=var.recall("hist") histo=var.recall("histo") eql=var.recall("eql") eqvar=var.recall("eqvar") cours=var.recall("cours") n_eq=var.recall("n_eq") if hist==nil then n_eq=1 eqvar=gen_eqvar() var.store("n_eq",1) var.store("eqvar",eqvar) hist={"S=a*/(b+/c)"} histo={"a*/(b+/c)"} var.store("histo",histo) var.store("hist",hist) end if eql==nil then eql="a*/(b+/c)" var.store("eql",eql) eqvar="S" var.store("eqvar",eqvar) var.store("cours",1) cours=1 end verif=0 options={{4,"A : Karnaugh","B : Binaire naturel","C : Code Gray (r"..accent.."fl"..accent.."chi)"},{5,"A : V"..accent.."rifier "..accent.."quivalence","B : Simplification","C : Transfo pour ladder","D : Transfo pour NAND"},{4,"A : depuis table Karnaugh","B : depuis table bin naturel","C : depuis table code Gray"},{4,"A : "..string.uchar(192).." propos","B : Effacer historique","C : Reset S"..string.uchar(61507)}} end function on.paint(gc) gc2=gc ww=platform.window:width() wh=platform.window:height() if item==nil then -- Animation debut if n==20 then gc:setFont("serif","i",8) gc:setColorRGB(127,127,127) gc:drawString("> Participation au concours Lua TI Bank 2011",10,150,"top") if disp==1 then gc:setColorRGB(0,0,0) gc:drawString("Appuyez sur ENTER",10,175,"top") end end gc:setColorRGB(n*12,200,255-n*12) gc:setFont("serif","b",12) str1="A B A Logique Nspire 2" str2=" > Louis DURAND < " str3=" (c) 2009-2013 " gc:drawString(string.sub(str1,0,n),(ww-gc:getStringWidth(str1))/2,15,"top") gc:setFont("serif","b",10) gc:drawString(string.sub(str2,20-n),ww-(ww-gc:getStringWidth(str2))/2-gc:getStringWidth(string.sub(str2,20-n)),40,"top") gc:drawString(string.sub(str3,0,n),(ww-gc:getStringWidth(str3))/2,65,"top") elseif item==0 then -- MENU ! if verif==1 then titre("Entrez S"..string.uchar(8317)..string.uchar(185)..string.uchar(8318).." :") elseif verif==2 then titre("Entrez S"..string.uchar(8317)..string.uchar(178)..string.uchar(8318).." :") else gc:setFont("serif","b",12) gc:setColorRGB(128,0,0) gc:drawString(str1,(ww-gc:getStringWidth(str1))/2+1,1,"top") gc:setColorRGB(0,200,0) gc:drawString(str1,(ww-gc:getStringWidth(str1))/2,0,"top") -- Titre end gc:setPen("thin","dashed") gc:setColorRGB(127,127,127) gc:drawLine(0,24,ww,24) gc:drawLine(0,52,ww,52) gc:setPen("thin","smooth") gc:setFont("serif","r",10) str4="Nouvelle "..accent.."quation" str5="Historique" sh=gc:getStringHeight(str4) sw=gc:getStringWidth(str4) gc:setColorRGB(255,80,80) fillRoundRect(ww/4+2,58+sh/2,30+sw,4+sh,5) fillRoundRect(3*ww/4+2,58+sh/2,30+sw,4+sh,5) if lig==0 and col==0 then -- Surbrillance de selection gc:setColorRGB(250,180,180) else gc:setColorRGB(250,128,114) end fillRoundRect(ww/4,56+sh/2,30+sw,4+sh,5) if lig==0 and col==1 then -- Surbrillance de selection gc:setColorRGB(250,180,180) else gc:setColorRGB(250,128,114) end fillRoundRect(3*ww/4,56+sh/2,30+sw,4+sh,5) gc:setColorRGB(128,0,0) gc:drawString(str4,(ww/2-sw)/2,55,"top") gc:drawString(str5,ww/2+(ww/2-gc:getStringWidth(str5))/2,55,"top") -- Boutons "Nouvelle eq" et "Historique" gc:setFont("serif","r",9) sw2=gc:getStringWidth(options[3][3]) if lig>0 then gc:setColorRGB(200,200,200) fillRoundRect(ww/2,77+lig*25,ww-20,23,5) if col==1 then fillRoundRect(3*ww/4,139,sw2+20,98,10) gc:setColorRGB(230,255,255) gc:fillRect((3*ww/2-sw2)/2-5,95+opt*20,sw2+10,15) gc:setColorRGB(0,0,0) for n=2, options[lig][1] do gc:drawString(options[lig][n],(3*ww/2-sw2)/2,60+n*20,"middle") end end end if lig==0 and col==1 then -- Historique start=5 gc:setColorRGB(120,80,120) gc:setFont("sansserif","r",7) gc:drawString(string.uchar(8592).." pour supprimer un "..accent.."l"..accent.."ment.",(3*ww/2-sw2)/2,85,"middle") if rappel>strt+5 then strt=rappel-5 elseif rappel0 then if verif==1 then etap="premi"..string.uchar(232).."re " else etap="deuxi"..string.uchar(232).."me " end text(" Entrez votre "..etap..accent.."quation ou rappelez-en une::dans l'historique.::Appuyez sur [tab] pour continuer ; [esc] pour annuler.",5,100) elseif enter==1 then if pb==1 then gc:setColorRGB(250,0,0) gc:setFont("serif","b",10) str=string.uchar(61699).." INVALIDE "..string.uchar(61699) gc:drawString(str,(ww-gc:getStringWidth(str))/2,80,"top") end text(" Utilisez des lettres pour les variables (de a jusqu'"..string.uchar(224).." f)::Utilisez ces 3 op"..accent.."rateurs ainsi que les parenth"..string.uchar(232).."ses : ::+ = OU ; * = ET ; / = NON:: [clear] = tout effacer ; [del] = suppr un caract"..string.uchar(232).."re:: [esc] pour annuler ; [enter] pour confirmer::N.B.: OS"..string.uchar(8805).."3.2 : [=>] 'implique' ; [<=>] '"..accent.."quivaut'",5,100,0,0,0,240,240,255) else gc:setColorRGB(0,0,0) gc:setFont("sansserif","b",10) gc:drawString("1) Tables >",(ww/2-sw)/2,100,"middle") gc:drawString("2) Op"..accent.."rations >",(ww/2-sw)/2,125,"middle") gc:drawString("3) Table"..string.uchar(8658)..string.uchar(201).."quation >",(ww/2-sw)/2,150,"middle") gc:drawString("4) [...] >",(ww/2-sw)/2,175,"middle") end if enter==1 then -- Saisie de l'equation (avec scrolling ! ;) ) gc:setColorRGB(0,0,0) gc:setFont("sansserif","r",10) larg=gc:getStringWidth(string.sub(eqvar.."="..msg,1,pos+#eqvar+1)) if start+larg>ww-5 then start=ww-larg-15 elseif start+larg<80 then start=120-larg if start>5 then start=5 end end gc:drawString(eqvar.."="..msg,start,27,"top") if disp==1 then gc:setColorRGB(127,127,127) gc:drawLine(start+larg,28,start+larg,48) end end end if not(enter==1) then aff_pretty(0) end else -- Rubriques if simplificat then titre("Simplification") text(" Forme normale "..forme.." :",5,30,120,0,255,240,240,240) text(" factorisation selon "..op.." :",5,82,120,0,255,240,240,240) prepare_pretty(eqvar.."="..facto) aff_pretty(80) prepare_pretty(eqvar.."="..simp) aff_pretty(30) text(" Appuyez sur [tab] pour choisir la forme de::la simplification.:: Appuyez sur [enter] pour visualiser la m"..accent.."thode::de r"..accent.."solution !",5,130,0,0,0,250,230,240) elseif eqtb==1 then titre(string.uchar(201).."quation d'une table") text(" Tapez sur 1, 2, 3, 4, 5 ou 6 pour choisir le nombre::de variables ou appuyez sur [C] pour charger::l'"..accent.."quation courante. ( "..eqvar.." )::::Utilisez les fl"..string.uchar(232).."ches, 0 et 1 pour remplir le tableau,::ou cliquez "..string.uchar(224).." la souris !:: Pour indiquer un "..accent.."tat ind"..accent.."termin"..accent.." ("..string.uchar(934).."), entrez::n'importe quel autre caract"..string.uchar(232).."re, '.' par exemple.",5,30,30,50,100,255,200,220) elseif (lig==1 or lig==3) and opt==0 or aff_simpli then -- Dessin table Karnaugh if verif==4 then eqvar=eqvar1 elseif verif==5 then eqvar=eqvar2 end cl=#mat[1] lg=#mat dbx=ww/2-cl*22/2 if aff_simpli and cl==8 then dbx=dbx-20 end dby=wh/2-lg*22/2+14 varc="" varl="" for cc=1,#v do if cc<=#v/2 then varl=varl..v[cc] else varc=varc..v[cc] end end gc:setColorRGB(128,20,0) for cc=0,cl do gc:drawLine(dbx+cc*22,dby,dbx+cc*22,dby+lg*22) end for cc=0,lg do gc:drawLine(dbx,dby+cc*22,dbx+cl*22,dby+cc*22) end gc:drawLine(dbx,dby,dbx-18,dby-18) if aff_simpli then -- interface simplification start=ww/2+76 scrol=0 gc:setColorRGB(255,131,250) if #entoures>0 then gc:fillRect(start-3,14+18*sel_k,82,18) for i=1, #entoures do prepare_pretty(entoures[i].eqn) aff_pretty(18*(i-1)+3) gc:drawLine(start-4,25+i*18,start-2,25+i*18) end gc:drawLine(start-5,25,start-5,25+#entoures*18) if option==1 then gc:drawString("*",start-7,29,"bottom") else gc:drawString("+",start-8,27,"bottom") end gc:drawArc(start-10,14,10,10,0,360) drawEntoure(entoures[sel_k]) -- Entoure le bloc de simplification correspondant a la selection end gc:setFont("sansserif","r",8) gc:setColorRGB(0,0,110) gc:drawString("[tab] = switch",start+10,20,"bottom") titre("Forme "..forme) elseif lig==3 then -- Cadre de selection pour remplir la table gc:setColorRGB(200,255,200) gc:fillRect(dbx+ex*22+1,dby+ey*22+1,21,21) gc:setFont("sansserif","r",8) gc:setColorRGB(0,0,110) gc:drawString("[2-6] dimension",ww/2+92,40,"top") gc:drawString("[A] inverser tout",ww/2+92,55,"top") gc:drawString("[B] remplir "..string.uchar(934),ww/2+92,70,"top") gc:drawString("[C] Charger "..eqvar2,ww/2+92,85,"top") titre("Tableau de Karnaugh "..eqvar) else gc:setFont("sansserif","r",8) gc:setColorRGB(0,0,110) gc:drawString("Tab : permuter",ww-gc:getStringWidth("Tab : permuter")-5,40,"top") gc:drawString("les variables.",ww-gc:getStringWidth("les variables.")-5,55,"top") titre("Tableau de Karnaugh "..eqvar) end gc:setFont("sansserif","r",8) -- Ecriture des anotations en bleu gc:setColorRGB(0,200,200) gc:drawString(varc,dbx-6-string.len(varl)*2,dby-18,"middle") gc:drawString(varl,dbx-17-string.len(varl)*2,dby-6,"middle") for cc=1,cl do gc:drawString(string.sub(gray,cc*3-string.len(varc)+1,cc*3),dbx-12-string.len(varc)*2+cc*22,dby,"bottom") end for cc=1,lg do gc:drawString(string.sub(gray,cc*3-string.len(varl)+1,cc*3),dbx-10-string.len(varl)*2,dby-18+cc*22,"top") end gc:setFont("sansserif","r",10) -- Ecriture dans la table gc:setColorRGB(0,0,0) for ll=1,lg do for cc=1,cl do if mat[ll][cc]==2 then gc:drawString(string.uchar(934),dbx+cc*22-14,dby+ll*22-20,"top") else gc:drawString(tostring(mat[ll][cc]),dbx+cc*22-14,dby+ll*22-20,"top") end end end gc:drawString(eqvar,dbx-28,dby-16,"bottom") if verif>=4 then eqvar=string.sub(eqvar2,1,string.find(eqvar2,string.uchar(8317))-1) end elseif (lig==1 or lig==3) and opt>0 then -- Dessin table verite dbx=(ww-cl*20)/2 gc:setColorRGB(255,230,230) gc:fillRect(dbx,dby,cl*20,20) if lig==3 then -- Cadre de selection pour remplir la table gc:setColorRGB(200,255,200) gc:fillRect(dbx+cl*20-18,dby+ey*20+1,18,19) gc:setFont("sansserif","r",8) gc:setColorRGB(0,0,110) gc:drawString("[2-6] dimension",ww/2+80,40,"top") gc:drawString("[A] inverser tout",ww/2+80,55,"top") gc:drawString("[B] remplir "..string.uchar(934),ww/2+80,70,"top") gc:drawString("[C] Charger "..eqvar2,ww/2+80,85,"top") end gc:setColorRGB(128,20,0) yy=dby if yy<0 then yy=0 end yy2=dby+lg*20 if yy2>wh then yy2=wh end for cc=0,cl do gc:drawLine(dbx+cc*20,yy,dbx+cc*20,yy2) end gc:drawLine(dbx+cl*20-19,yy,dbx+cl*20-19,yy2) com=(dby-25)/20+2 fin=(wh-25)/20+3 if fin-com>lg then fin=lg+com end for cc=0,fin do if cc-com>=0 then gc:drawLine(dbx,cc*20-15,dbx+cl*20,cc*20-15) end end gc:setFont("sansserif","r",10) gc:setColorRGB(0,0,0) for cc=1,cl do if cc==cl then gc:setFont("sansserif","b",10) end for ll=1,fin do if ll-com>0 then if tb[ll-com][cc]==2 then gc:drawString(string.uchar(934),dbx+cc*20-14,ll*20-34,"top") elseif cc==cl and ll-com==1 then gc:drawString(tb[1][cc],dbx+cc*20-17,ll*20-34,"top") else gc:drawString(tostring(tb[ll-com][cc]),dbx+cc*20-13,ll*20-34,"top") end end end end titre("Table de verite "..string.uchar(9733)..bin) gc:setColorRGB(0,80,0) gc:fillRect(ww-10,25,6,wh-31) gc:setColorRGB(110,100,255) gc:fillPolygon({ww-10,24,ww-7,19,ww-4,24}) gc:fillPolygon({ww-10,wh-5,ww-7,wh,ww-4,wh-5}) if lg*20<(wh-31) then gc:fillRect(ww-9,26,4,wh-33) else gc:fillRect(ww-9,26+(25-dby)*(wh-33)/(lg*20),4,(wh-31)*(wh-33)/(lg*20)) end elseif lig==2 and opt==0 then titre("V"..accent.."rifier "..accent.."quivalence entre "..eqvar1.." et "..eqvar2.." :") if string.len(eql1)>string.len(eql2) then prepare_pretty(eqvar2.."="..eql2) disp2=disp disp=0 aff_pretty(30) disp=disp2 prepare_pretty(eqvar1.."="..eql1) aff_pretty(0) else prepare_pretty(eqvar1.."="..eql1) aff_pretty(0) prepare_pretty(eqvar2.."="..eql2) disp2=disp disp=0 aff_pretty(30) disp=disp2 end if faux==1 then text(" "..string.uchar(61699).." Les deux "..accent.."quations ne sont pas "..accent.."quivalentes.",5,90,255,0,0,250,240,250) else text(" "..string.uchar(10003).." Les deux "..accent.."quations sont bien "..accent.."quivalentes ! "..string.uchar(9786),5,90,0,255,0,250,240,250) end elseif lig==2 and opt==2 then titre("Mise en forme 'ladder'") if pb==1 then text("Imcompatible avec les op"..accent.."rateurs "..string.uchar(8658).." et "..string.uchar(8660).." !:::: Effectuez une simplification au pr"..accent.."alable, [ 2) > B ]::puis r"..accent.."essayez !",5,30,20,0,20,255,240,200) else aff_pretty(text(" Cela permet, par le th"..accent.."or"..string.uchar(232).."me de De Morgan, de::transformer des groupes de variables compl"..accent.."ment"..accent.."es::en variables uniques compl"..accent.."ment"..accent.."es, utile pour les::circuits ladder. EX : /(a*b)=/a+/b",5,30,20,0,20,255,240,200)) end elseif lig==2 and opt==3 then titre("Pour portes NAND (NON ET)") if pb==1 then text("Imcompatible avec les op"..accent.."rateurs "..string.uchar(8658).." et "..string.uchar(8660).." !:::: Effectuez une simplification au pr"..accent.."alable, [ 2) > B ]::puis r"..accent.."essayez !",5,30,0,20,20,255,255,200) else aff_pretty(text(" Adapte votre "..accent.."quation pour une utilisation avec la::cellule universelle NAND.:: Il faut "..tostring(nan[2]).." portes NAND :",5,30,0,20,20,255,255,200)) end elseif lig==4 and opt==0 then gc:setColorRGB(255,255,170) gc:fillRect(2,2,ww-4,wh-4) gc:setColorRGB(255,240,250) gc:setFont("serif","b",12) fillRoundRect(ww/2,15,gc:getStringWidth(str1)+8,gc:getStringHeight(str1),10) if disp==1 then gc:setColorRGB(128,0,0) else gc:setColorRGB(0,200,0) end gc:drawString(str1,(ww-gc:getStringWidth(str1))/2+disp,2+disp,"top") gc:setFont("sansserif","b",9) gc:setColorRGB(0,0,200) str2="Louis DURAND "..string.uchar(169).." 2009-2013" gc:drawString(str2,(ww-gc:getStringWidth(str2))/2,30,"top") str2="FRANCE ~ 54" gc:drawString(str2,(ww-gc:getStringWidth(str2))/2,55,"top") text(" Des parties de ce programme ont "..accent.."t"..accent.." reprises et::adapt"..accent.."es de ABA Logique v2.0 pour TI 89.:: Retrouvez mes programmes sur ti-planet.org !::Si vous avez des probl"..string.uchar(232).."mes ou questions, rendez vous::sur le forum du site, j'y suis membre r"..accent.."gulier.:: Pour une meilleure prise en main et des astuces,::"..accent.."tudiez l'Activit"..accent.." ainsi que le Lisez-moi fournis.",5,80,50,40,30,240,250,255) elseif lig==4 and opt==1 then titre("Effacer l'historique") text(" Voulez-vous vraiment effacer votre::historique ?:: [ENTER]=oui ; [ESC]=annuler",5,25,100,0,0) elseif lig==4 and opt==2 then titre("R"..accent.."initialiser S"..string.uchar(61507)) text(" Voulez-vous vraiment r"..accent.."initialiser le comptage::des "..accent.."quations ?:: [ENTER]=oui ; [ESC]=annuler",5,25,100,0,0,240,255,240) end end end function on.tabKey() if item==1 and lig==1 and opt==0 then if var.recall("vsav")==nil then var.store("vsav",v) for aba=1,#v/2 do table.insert(v,1,table.remove(v)) end else v=var.recall("vsav") math.eval("DelVar vsav") end var.store("v",v) karnaugh() elseif simplificat or aff_simpli then option=1-option sel_k=1 simpl_kar(mat,v) end if not(enter==1) then if verif==1 then eql1=eql eqvar1=eqvar..string.uchar(8317)..string.uchar(185)..string.uchar(8318) verif=2 prepare_pretty(eqvar.."="..eql) elseif verif==2 then eql2=eql eqvar2=eqvar..string.uchar(8317)..string.uchar(178)..string.uchar(8318) verif=3 item=1 lig=2 formatage(eql1) v1=v vv1=vv eq1=eq formatage(eql2) eq2=eq if #v1>#v then v=v1 vv=vv1 var.store("vv",vv1) var.store("v",v1) end karnaugh() mat2=var.recall("kar") var.store("eq",eq1) karnaugh() mat1=var.recall("kar") faux=0 for aba=1,#mat do for cpt=1,#mat[1] do if not(mat1[aba][cpt]==mat2[aba][cpt]) then faux=1 aba=#mat end end end scrol=1 start=5 -- Initialise le scrolling pretty print disp=1 timer.start(.5) elseif verif==3 then on.enterKey() end end platform.window:invalidate() end function on.charIn(char) if enter == 1 then msg=string.sub(msg,1,pos)..char..string.sub(msg,pos+1) pos=pos+1 elseif item==1 then if lig==3 and opt==0 and not(aff_simpli) then if char=="1" and eqtb==2 then mat[ey+1][ex+1]=1 elseif char=="0" and eqtb==2 then mat[ey+1][ex+1]=0 elseif char=="1" then ch=1 eqtb=2 mat=math.eval("NewMat(1,2)") v={} for aba=1,ch do v[aba]=string.uchar(96+aba) end eqvar=gen_eqvar() cl=#mat[1] lg=#mat ex=0 ey=0 elseif char=="2" then ch=2 eqtb=2 mat=math.eval("NewMat(2,2)") elseif char=="3" then ch=3 eqtb=2 mat=math.eval("NewMat(2,4)") elseif char=="4" then ch=4 eqtb=2 mat=math.eval("NewMat(4,4)") elseif char=="5" then ch=5 eqtb=2 mat=math.eval("NewMat(4,8)") elseif char=="6" then ch=6 eqtb=2 mat=math.eval("NewMat(8,8)") elseif string.lower(char)=="c" then -- Charger l'equation formatage(eql) karnaugh() ch=#v eqtb=2 eqvar=gen_eqvar() elseif eqtb==2 then if string.lower(char)=="a" then mat=inverse_tbl(mat,0) elseif string.lower(char)=="b" then mat=remplir_tbl(mat,0) else mat[ey+1][ex+1]=2 end end if string.find(string.lower(char),"[2-6abc]")==nil and eqtb==2 then on.arrowRight() if ex==0 then on.arrowDown() end elseif eqtb==2 then if string.lower(char)~="c" then v={} for aba=1,ch do v[aba]=string.uchar(96+aba) end eqvar=gen_eqvar() end cl=#mat[1] lg=#mat ex=0 ey=0 end elseif lig==3 and opt>0 then if char=="1" and eqtb==2 then tb[ey+1][cl]=1 on.arrowDown() elseif char=="0" and eqtb==2 then tb[ey+1][cl]=0 on.arrowDown() elseif string.find(char,"[1-6]")~=nil then ch=tonumber(char) v={} for aba=1,ch do v[aba]=string.uchar(96+aba) end var.store("v",v) eqvar=gen_eqvar() if opt==1 then math.eval("newMat(2^(dim(v))+1,dim(v)+1)=:tb:"..gui..eqvar..gui.."=:tb[1,dim(v)+1]:For aba,1,dim(v):v[aba]=:tb[1,aba]:EndFor::For aba,0,2^(dim(v))-1:aba=:nbr:For cpt,1,dim(v):intDiv(nbr,2^(dim(v)-cpt))=:n:nbr-n*2^(dim(v)-cpt)=:nbr:n=:tb[aba+2,cpt]:EndFor:EndFor") tb=var.recall("tb") else var.store("eq","false") tbl_gray() end cl=#tb[1] lg=#tb ey=1 dby=25 eqtb=2 if opt==1 then bin=" Binaire naturel" else bin=" Code Gray" end elseif string.lower(char)=="c" then -- Charger l'equation formatage(eql) if opt==1 then tbl_verite() bin=" Binaire naturel" else tbl_gray() bin=" Code Gray" end cl=#tb[1] lg=#tb ey=1 dby=25 ch=#v eqtb=2 eqvar=gen_eqvar() elseif eqtb==2 then if string.lower(char)=="a" then tb=inverse_tbl(tb,1) elseif string.lower(char)=="b" then tb=remplir_tbl(tb,1) else tb[ey+1][cl]=2 on.arrowDown() end end end elseif item==0 then char=string.lower(char) if string.find(char,"[1-4]")~=nil and verif==0 then lig=tonumber(char) col=1 opt=0 scrol=0 prepare_pretty(eqvar.."="..eql) elseif string.find(char,"%a") then n=string.byte(char)-96 if col==1 and lig>0 then if n]","[^=]>","<[^=]","[*+/%(][<=]",">[*+%)<=]","[^a-f*+/%(%)%0%1<=>]"} else patt={"[*+][*+]","/[*+]","%(%)","%([*+]","[*+/]%)","[^a-f*+/%(%)%0%1]"} end for aba=1,#patt do if string.find("("..msg..")",patt[aba])~=nil then -- Verifications de la validite de l'equation pb=1 end end if pb==0 then timer.stop() enter=0 eql=msg start=5 var.store("eql",eql) local n_h=sto_hist(eqvar.."=",eql,0) -- verifie si l'equation n'est pas deja dans les deux premiers termes de l'historique if n_h==0 then n_eq=n_eq+1 var.store("n_eq",n_eq) else eqvar=string.sub(hist[n_h],string.find(hist[n_h],"S"),string.find(hist[n_h],"=")-1) cours=n_h var.store("cours",cours) end var.store("eqvar",eqvar) prepare_pretty(eqvar.."="..eql) end elseif item==nil or item==1 then timer.stop() if lig==4 and opt==1 then hist={} histo={} var.store("hist",hist) var.store("histo",histo) n_eq=1 var.store("n_eq",1) elseif lig==4 and opt==2 then n_eq=1 var.store("n_eq",1) end if simplificat then aff_simpli=true simplificat=false scrol=0 sel_k=1 elseif lig==3 and opt==0 and eqtb==2 then option=0 etiq="kar" n_eq=n_eq+1 var.store("n_eq",n_eq) simpl_kar(mat,v) simplificat=true eqtb=3 scrol=1 start=5 disp=1 timer.start(.5) elseif lig==3 and eqtb==2 then local i,j option=0 if ch==1 then mat=math.eval("NewMat(1,2)") elseif ch==2 then mat=math.eval("NewMat(2,2)") elseif ch==3 then mat=math.eval("NewMat(2,4)") elseif ch==4 then mat=math.eval("NewMat(4,4)") elseif ch==5 then mat=math.eval("NewMat(4,8)") elseif ch==6 then mat=math.eval("NewMat(8,8)") end if opt==1 then for i=1,#mat do for j=1,#mat[1] do mat[i][j]=tb[tonumber(string.sub(gray,i*3-math.floor(ch/2)+1,i*3)..string.sub(gray,j*3-math.ceil(ch/2)+1,j*3) , 2) + 2][#tb[1]] end end etiq="tbn" else for i=0, #tb-2 do if math.floor(i/#mat[1])%2==0 then mat[math.floor(i/#mat[1])+1][i%(#mat[1])+1]=tb[i+2][#tb[1]] else mat[math.floor(i/#mat[1])+1][#mat[1]-(i%(#mat[1]))]=tb[i+2][#tb[1]] end end etiq="tbg" end n_eq=n_eq+1 var.store("n_eq",n_eq) simpl_kar(mat,v) simplificat=true eqtb=3 scrol=1 start=5 disp=1 timer.start(.5) elseif verif==3 then mat=mat1 lig=1 opt=0 verif=4 elseif verif==4 then mat=mat2 var.store("eq",eq2) karnaugh() verif=5 elseif eqtb==1 then else if lig==3 then eqvar=eqvar2 end eqtb=0 verif=0 item=0 lig=0 col=0 start=5 scrol=0 aff_simpli=false prepare_pretty(eqvar.."="..eql) math.eval("DelVar vsav") end elseif lig>0 then -- lorsque selection dans le menu if col==0 then col=1 opt=0 else item=1 formatage(eql) if lig==1 and opt==0 then karnaugh() elseif lig==1 and opt==1 then tbl_verite() cl=#tb[1] lg=#tb dby=25 bin=" Binaire naturel" elseif lig==1 and opt==2 then tbl_gray() cl=#tb[1] lg=#tb dby=25 bin=" Code Gray" elseif lig==2 and opt==0 then item=0 verif=1 lig=0 col=0 prepare_pretty(eqvar.."="..eql) elseif lig==2 and opt==1 then karnaugh() -- sortie : mat option=0 etiq="simp" simpl_kar(mat,v) -- sortie : simp, entoures --simplif(eql) simplificat=true scrol=1 start=5 disp=1 timer.start(.5) elseif lig==2 and opt==2 then pb=0 if string.find(eql,"=>")==nil and string.find(eql,"<=>")==nil then ladder(eql,1) prepare_pretty(eqvar.."="..eq2) scrol=1 start=5 disp=1 timer.start(.5) else pb=1 end elseif lig==2 and opt==3 then pb=0 if string.find(eql,"=>")==nil and string.find(eql,"<=>")==nil then nand(eql) prepare_pretty(eqvar.."="..nan[1]) scrol=1 start=5 disp=1 timer.start(.5) else pb=1 end elseif lig==3 then eqtb=1 eqvar2=eqvar elseif lig==4 and opt==0 then disp=1 timer.start(0.3) end end elseif lig==0 and col==0 or lig==-1 then scrol=0 lig=0 pb=0 enter=1 disp=1 msg=eql start=5 eqvar2=eqvar eqvar=gen_eqvar() pos=string.len(msg) timer.start(0.5) elseif lig==0 and col==1 then if histo[rappel]~=nil then eql=histo[rappel] var.store("eql",eql) cours=rappel var.store("cours",cours) eqvar=string.sub(hist[rappel],string.find(hist[rappel],"S"),string.find(hist[rappel],"=")-1) var.store("eqvar",eqvar) end end platform.window:invalidate() end function on.escapeKey() if item==0 then if lig==-1 then lig=0 scrol=0 elseif col==0 and enter==0 then verif=0 end col=0 if enter==1 then eqvar=eqvar2 enter=0 end timer.stop() prepare_pretty(eqvar.."="..eql) elseif item==1 then if aff_simpli then aff_simpli=false simplificat=true prepare_pretty(eqvar.."="..simp) scrol=1 start=5 disp=1 timer.start(.5) elseif simplificat and lig==3 then simplificat=false eqtb=2 timer.stop() scrol=0 table.remove(hist,1) table.remove(histo,1) if hist[1]~=nil and string.sub(hist[1],string.find(hist[1],"S"),string.find(hist[1],"=")-1)==eqvar then table.remove(hist,1) table.remove(histo,1) end var.store("hist",hist) var.store("histo",histo) n_eq=n_eq-1 if opt>0 then cl=#tb[1] lg=#tb ey=1 dby=25 end else eqtb=0 verif=0 item=0 scrol=0 start=5 simplificat=false timer.stop() if lig==3 then eqvar=eqvar2 end prepare_pretty(eqvar.."="..eql) math.eval("DelVar vsav") end end platform.window:invalidate() end function on.backspaceKey() if enter==1 and pos>0 then msg=string.sub(msg,1,pos-1)..string.sub(msg,pos+1) pos=pos-1 elseif lig==0 and col==1 then if rappel1 then rappel=rappel-1 end if strt+5>=math.eval("dim(hist)") and strt>1 then strt=strt-1 end var.store("hist",hist) var.store("histo",histo) end platform.window:invalidate() end function on.clearKey() if enter==1 then if pos==string.len(msg) then msg="" pos=0 else msg=string.sub(msg,1,pos) end end platform.window:invalidate() end function on.arrowLeft() if scrol==1 then start=start+10 if start>5 then start=5 end elseif item==0 then if enter==1 then if pos>0 then pos=pos-1 end disp=1 else col=0 prepare_pretty(eqvar.."="..eql) end elseif item==1 then if eqtb==2 and opt==0 then ex=math.eval("mod("..tostring(ex-1)..","..tostring(cl)..")") end end platform.window:invalidate() end function on.arrowRight() if scrol==1 then if start+larg>ww then start=start-10 end elseif item==0 then if enter==1 then if pos0 then if col==1 then if opt>0 then opt=opt-1 end else lig=lig-1 end elseif col==1 then if rappel>1 then rappel=rappel-1 end end elseif item==1 then if lig==1 and opt>0 and dby<25 then dby=dby+20 elseif eqtb==2 and opt>0 then if ey>1 then ey=ey-1 end if dby+ey*20<26 then dby=dby+20 end elseif eqtb==2 then ey=math.eval("mod("..tostring(ey-1)..","..tostring(lg)..")") elseif aff_simpli then sel_k=(sel_k-2)%(#entoures)+1 end end platform.window:invalidate() end function on.arrowDown() if item==0 then if enter==1 then pos=string.len(msg) elseif lig==0 and col==1 then if rappel0 and dby+lg*20>wh then dby=dby-20 elseif eqtb==2 and opt>0 then if ey+1wh then dby=dby-20 end elseif eqtb==2 then ey=math.eval("mod("..tostring(ey+1)..","..tostring(lg)..")") elseif aff_simpli then sel_k=(sel_k)%(#entoures)+1 end end platform.window:invalidate() end function on.mouseMove(x,y) local r,val if item==0 and enter~=1 then if x>(ww/2-sw)/2-15 and x<(ww/2+sw)/2+15 and y>55 and y<59+sh and (lig~=0 or col~=0) then lig=0 col=0 timer.stop() scrol=0 prepare_pretty(eqvar.."="..eql) r=1 elseif x>(3*ww/2-sw)/2-15 and x<(3*ww/2+sw)/2+15 and y>55 and y<59+sh and (lig~=0 or col~=1) then lig=0 col=1 rappel=1 strt=1 scrol=0 r=1 elseif y<52 and lig~=-1 then col=0 on.charIn("s") prepare_pretty(eqvar.."="..eql) r=1 elseif y>88 and lig==0 and col==1 then if y>94 and y<214 and rappel~=math.floor((y-94)/20)+strt then rappel=math.floor((y-94)/20)+strt r=1 end elseif x88 then r=1 if y<113 and lig~=1 then on.charIn("1") elseif y>113 and y<138 and lig~=2 then on.charIn("2") elseif y>138 and y<163 and lig~=3 then on.charIn("3") elseif y>163 and y<188 and lig~=4 then on.charIn("4") else r=0 end elseif x>ww/2 and y>95 and lig>0 then r=1 if y<115 and opt~=0 then opt=0 elseif y>115 and y<135 and opt~=1 then opt=1 elseif y>135 and y<155 and opt~=2 then opt=2 elseif y>155 and y<175 and opt~=3 and lig==2 then opt=3 else r=0 end end elseif item==1 and eqtb==2 then if opt==0 then if x>dbx and y>dby then val=math.floor((x-dbx-1)/22) if val=48 and y=start-3 and y>=34 and y<34+18*#entoures then val=math.floor((y-16)/18) if val~=sel_k then sel_k=val r=1 end end end if r==1 then platform.window:invalidate() end end function on.mouseDown(x,y) if item==0 then if y<24 then if x<20 then on.arrowLeft() elseif x>ww-20 then on.arrowRight() end elseif lig==0 and col==1 then if x<10 and y>200 then on.arrowDown() elseif x<10 and y<105 then on.arrowUp() elseif x>20 and y>94 then on.enterKey() end elseif y>24 and y<52 or x>(ww/2-sw)/2-15 and x<(ww/2+sw)/2+15 and y>55 and y<59+sh or lig>0 and x>ww/2 and y>94+opt*20 and y<114+opt*20 then on.enterKey() end elseif item==1 and (lig==1 or lig==3) and opt>0 then if x>ww-14 then if y>16 and y<27 then on.arrowUp() elseif y>wh-8 then on.arrowDown() end elseif eqtb==2 and y>25 then if y>45 then tb[ey+1][cl]=(tb[ey+1][cl]+1)%3 platform.window:invalidate(dbx+(cl-1)*20,45,20,wh-45) end else on.enterKey() end elseif item==1 and eqtb==2 then if x>dbx and y>dby and x",string.uchar(8660))[1] equation=str_replace(equation,"=>",string.uchar(8658))[1] pretty=pretty_print(equation,"") db=string.find(pretty[1],"*") while not(db==nil) do pretty[1]=string.sub(pretty[1],1,db-1)..string.uchar(183)..string.sub(pretty[1],db+1) db=string.find(pretty[1],"*") end end function pretty_print(e,str_db) local nnn,hhh,eq1,eq2,eq3,db,cp,cpp,po,pff,paran db=string.find(e,"/") hhh=-1 while not(db==nil) do cpp=true cp=0 while cpp do cp=cp+1 if not(string.sub(e,db+cp,db+cp)=="/") then cpp=false end end if string.sub(e,db+cp,db+cp)=="(" then po=db+cp pff=db+cp while not(po==nil or po>pff) do po=string.find(e,"(",po+1,true) pff=string.find(e,")",pff+1,true) end eq1=string.sub(e,1,db-1) eq2=string.sub(e,db+cp+1,pff-1) eq3=string.sub(e,pff+1) nn=nn+1 nnn=nn paran=pretty_print(eq2,str_db..string.sub(e,1,db-1)) -- Rappel de la fonction pour traiter l'interieur du bloc complemente. e=eq1..paran[1]..eq3 if paran[2]+cp>hhh then hhh=paran[2]+cp end bar[nnn]={str_db..eq1,str_db..eq1..paran[1],paran[2]+1,cp} else e=string.sub(e,1,db-1)..string.sub(e,db+cp) nn=nn+1 if cp-1>hhh then hhh=cp-1 end bar[nn]={str_db..string.sub(e,1,db-1),str_db..string.sub(e,1,db),0,cp} end db=string.find(e,"/") end return {e,hhh} end -- > Affichage pretty print function aff_pretty(y) if scrol==1 and disp==1 then gc2:setColorRGB(150,150,255) gc2:drawString(string.uchar(9664),5,2+y,"top") gc2:drawString(string.uchar(9654),ww-15,2+y,"top") end gc2:setColorRGB(0,0,0) gc2:setFont("sansserif","r",10) larg=gc2:getStringWidth(pretty[1]) haut=gc2:getStringHeight(pretty[1]) gc2:drawString(pretty[1],start,38+pretty[2]+y,"middle") for aba=1,nn do for ab=1,bar[aba][4] do gc2:drawLine(start+gc2:getStringWidth(bar[aba][1]),43-haut/2+pretty[2]-(bar[aba][3]+ab)*2+y,start+gc2:getStringWidth(bar[aba][2]),43-haut/2+pretty[2]-(bar[aba][3]+ab)*2+y) end end end function str_replace(str,sub,rplc) local tr,cpt cpt=0 tr=string.find(str,sub) while not(tr==nil) do str=string.sub(str,1,tr-1)..rplc..string.sub(str,tr+string.len(sub)) tr=string.find(str,sub) cpt=cpt+1 end return {str,cpt} end function formatage(eql) eq=str_replace(eql,"*"," and ")[1] eq=str_replace(eq,"+"," or ")[1] eq=str_replace(eq,"//","")[1] eq=str_replace(eq,"/","not ")[1] eq=str_replace(eq,"1","true")[1] eq=str_replace(eq,"0","false")[1] vv={} v={} for aba=1,8 do if not(string.find(eql,string.uchar(aba+96))==nil) then vv[#vv+1]=aba+96 v[#v+1]=string.uchar(aba+96) end end var.store("vv",vv) var.store("v",v) var.store("eq",eq) end function karnaugh() math.eval("0=:aba:If dim(v)=1 Then:newMat(1,2)=:kar:ElseIf dim(v)=2 Then:newMat(2,2)=:kar:ElseIf dim(v)=3 Then:newMat(2,4)=:kar:ElseIf dim(v)=4 Then:newMat(4,4)=:kar:ElseIf dim(v)=5 Then:newMat(4,8)=:kar:ElseIf dim(v)=6 Then:newMat(8,8)=:kar:Else:{{0}}=:kar:EndIf:For aba,1,dim(v):false=:#(v[aba]):EndFor::{}=:s:For aba,1,2^(dim(v)):If aba>1:not expr(v[dim(v)+1-chg[aba]])=:#(v[dim(v)+1-chg[aba]]):when(expr(eq),1,0)=:s[aba]:EndFor::1=:cp:1=:l::Try:Loop:For cpt,1,dim(kar)[2]:s[cp]=:kar[l,cpt]:cp+1=:cp:EndFor:l+1=:l:For cpt,-dim(kar)[2],-1:s[cp]=:kar[l,-cpt]:cp+1=:cp:EndFor:l+1=:l:EndLoop: Else:EndTry") mat=var.recall("kar") end function tbl_verite() math.eval("newMat(2^(dim(v))+1,dim(v)+1)=:tb:"..gui..eqvar..gui.."=:tb[1,dim(v)+1]:For aba,1,dim(v):v[aba]=:tb[1,aba]:EndFor::For aba,0,2^(dim(v))-1:aba=:nbr:For cpt,1,dim(v):intDiv(nbr,2^(dim(v)-cpt))=:n:nbr-n*2^(dim(v)-cpt)=:nbr:when(n=0,false,true)=:#(v[cpt]):n=:tb[aba+2,cpt]:EndFor:when(expr(eq),1,0)=:tb[aba+2,dim(v)+1]:EndFor") tb=var.recall("tb") end function tbl_gray() math.eval("0=:aba:newMat(2^(dim(v)),dim(v)+1)=:tbg::For aba,1,dim(v):false=:#(v[aba]):EndFor::For aba,1,2^(dim(v)):If aba>1:not expr(v[dim(v)+1-chg[aba]])=:#(v[dim(v)+1-chg[aba]]):For cp,1,dim(v):when(expr(v[cp]),1,0)=:tbg[aba,cp]:EndFor:when(expr(eq),1,0)=:tbg[aba,dim(v)+1]:EndFor::newMat(1,dim(v)+1)=:t:"..gui..eqvar..gui.."=:t[1,dim(v)+1]:For aba,1,dim(v):v[aba]=:t[1,aba]:EndFor:colAugment(t,tbg)=:tb") tb=var.recall("tb") end function inverse_tbl(t,o) local i,j,res if o==1 then -- Table de verite res=t for i=2, #res do if res[i][#res[1]]==2 then res[i][#res[1]]=2 else res[i][#res[1]]=1-res[i][#res[1]] end end else -- Tableau de Karnaugh res=math.eval("NewMat("..tostring(#t)..","..tostring(#t[1])..")") for i=1, #res do for j=1, #res[1] do if t[i][j]==2 then res[i][j]=2 else res[i][j]=1-t[i][j] end end end end return res end function remplir_tbl(t,o) local i,j,res if o==1 then -- Table de verite res=t for i=2, #res do res[i][#res[1]]=2 end else -- Tableau de Karnaugh res=math.eval("NewMat("..tostring(#t)..","..tostring(#t[1])..")") for i=1, #res do for j=1, #res[1] do res[i][j]=2 end end end return res end -- FACTORISATION D'UNE FORME NORMALE CONJONCTIVE OU DISJONCTIVE function factor(eq) local p,pp,i,j,eq2,terms,facs,bar,pabar,factorisations,f,s,fac,res,mini,op1,op2,op3,op4,nb,fac_r if option==1 then -- factorisation selon + op1="+" op2="*" op3=")*" op4="(" else -- factorisation selon * op1="*" op2="+" op3="+" op4="" end terms={} eq2=op2..eq..op2 i=1 p=1 pp=string.find(eq2,op2,2) while pp~=nil do -- construction liste des termes if pp-p<=3 then -- terme simple terms[i]=string.sub(eq2,p+1,pp-1) else terms[i]=string.sub(eq2,p+1+option,pp-1-option) end p=pp pp=string.find(eq2,op2,p+1) i=i+1 end facs={0,{}} -- max, liste des variables l'atteignant for i=1, #v do -- Decompte de le redondance des variables bar=0 pabar=0 -- nb de '/a' , nb de 'a' for j=1, #terms do if string.find(terms[j],"/"..v[i])~=nil then bar=bar+1 elseif string.find(terms[j],v[i])~=nil then pabar=pabar+1 end end if bar>facs[1] then facs={bar,{"/"..v[i]}} elseif bar==facs[1] then table.insert(facs[2],"/"..v[i]) end if pabar>facs[1] then facs={pabar,{v[i]}} elseif pabar==facs[1] then table.insert(facs[2],v[i]) end end if facs[1]>1 then factorisations={} for i=1, #facs[2] do -- On effectue toutes les factorisations de poids egales fac=op4 res=op4 f=facs[2][i] for j=1, #terms do s=string.find(terms[j],f) if s~=nil and string.sub(terms[j],s-1,s-1)~="/" then if s==1 then fac=fac..string.sub(terms[j],#f+2)..op3..op4 else fac=fac..string.sub(terms[j],1,s-2)..string.sub(terms[j],s+#f)..op3..op4 end else res=res..terms[j]..op3..op4 end end if #fac>2 then fac_r=factor(string.sub(fac,1,#fac-1-option)) -- rappel recursif de la fonction fac=fac_r[1] end if #res>2 then res=factor(string.sub(res,1,#res-1-option))[1] end if fac_r[2] or option==1 then -- le resultat ! if res==op4 then factorisations[i]={op4..f..op1..fac..string.sub(op3,-2,-2) , true} else factorisations[i]={op4..f..op1..fac..op3..res , false} end else if res=="" then factorisations[i]={f.."*("..fac..")" , true} else factorisations[i]={f.."*("..fac..")+"..res , false} end end end else factorisations={{eq , false}} end -- selection de la factorisation la plus courte mini={nb_var(factorisations[1][1]), #factorisations[1][1] , 1} for i=2, #factorisations do nb=nb_var(factorisations[i][1]) if nb=2 then if e.r1>=1 and e.r2<=li/2 then if li~=8 or not(e.sym_r9) or (e.sym_c9 and not(e.sym_rc9)) then -- Avec cas double symetrie r/c eqn=eqn..ne1..vars[n]..op1 end elseif e.r1>=li/2+1 and e.r2<=li then if li~=8 or not(e.sym_r9) or (e.sym_c9 and not(e.sym_rc9)) then -- Avec cas double symetrie r/c eqn=eqn..ne2..vars[n]..op1 end end n=n+1 end if li>=4 then if e.r1>=li/4+1 and e.r2<=3*li/4 then if li~=8 or not(e.sym_r5) or (e.sym_c5 and not(e.sym_rc5)) then -- Avec cas double symetrie r/c eqn=eqn..ne2..vars[n]..op1 end elseif e.r1>=3*li/4+1 and e.r2<=5*li/4 or e.r1>=-li/4+1 and e.r2<=li/4 then if li~=8 or not(e.sym_r5) or (e.sym_c5 and not(e.sym_rc5)) then -- Avec cas double symetrie r/c eqn=eqn..ne1..vars[n]..op1 end end n=n+1 if li==8 then if e.r1>=2 and e.r2<=3 or e.r1>=6 and e.r2<=7 then eqn=eqn..ne2..vars[n]..op1 elseif e.r1>=4 and e.r2<=5 or e.r1>=0 and e.r2<=1 or e.r1>=8 and e.r2<=9 then eqn=eqn..ne1..vars[n]..op1 end n=n+1 end end -- colonnes if e.c1>=1 and e.c2<=co/2 then if co~=8 or not(e.sym_c9) then eqn=eqn..ne1..vars[n]..op1 end elseif e.c1>=co/2+1 and e.c2<=co then if co~=8 or not(e.sym_c9) then eqn=eqn..ne2..vars[n]..op1 end end n=n+1 if co>=4 then if e.c1>=co/4+1 and e.c2<=3*co/4 then if co~=8 or not(e.sym_c5) then eqn=eqn..ne2..vars[n]..op1 end elseif e.c1>=3*co/4+1 and e.c2<=5*co/4 or e.c1>=-co/4+1 and e.c2<=co/4 then if co~=8 or not(e.sym_c5) then eqn=eqn..ne1..vars[n]..op1 end end n=n+1 if co==8 then if e.c1>=2 and e.c2<=3 or e.c1>=6 and e.c2<=7 then eqn=eqn..ne2..vars[n]..op1 elseif e.c1>=4 and e.c2<=5 or e.c1>=0 and e.c2<=1 or e.c1>=8 and e.c2<=9 then eqn=eqn..ne1..vars[n]..op1 end end end if eqn=="" then if option==1 then eqn="0 " else eqn="1 " end end sol[i].eqn=string.sub(eqn,1,#eqn-1) eq=eq..string.sub(eqn,1,#eqn-1)..op2 end if #sol==0 then if option==1 then eq="1)+(" else eq="0 " end end if option==1 then return "("..string.sub(eq,1,#eq-2) else return string.sub(eq,1,#eq-1) end end -- FIN SIMPLIFICATION function drawEntoure(ent) -- Dessine les paquets de simplification local gx,gy,dx,dy,li1,li2,co1,co2 gc2:setColorRGB(191,62,255) gc2:setPen("medium") gx=math.max(ent.c1,1) gy=math.max(ent.r1,1) dx=math.min(ent.c2,#kar[1]) dy=math.min(ent.r2,#kar) gc2:drawRect(dbx+22*(gx-1),dby+22*(gy-1),22*(dx-gx+1),22*(dy-gy+1)) if ent.c1<1 then gc2:drawRect(dbx+22*(ent.c1+#kar[1]-1),dby+22*(gy-1),22*(1-ent.c1),22*(dy-gy+1)) end if ent.r1<1 then gc2:drawRect(dbx+22*(gx-1),dby+22*(ent.r1+#kar-1),22*(dx-gx+1),22*(1-ent.r1)) end if ent.c2>#kar[1] then gc2:drawRect(dbx,dby+22*(gy-1),22*(ent.c2-#kar[1]),22*(dy-gy+1)) end if ent.r2>#kar then gc2:drawRect(dbx+22*(gx-1),dby,22*(dx-gx+1),22*(ent.r2-#kar)) end if ent.c1<1 and ent.r1<1 then gc2:drawRect(dbx+22*(ent.c1+#kar[1]-1),dby+22*(ent.r1+#kar-1),22*(1-ent.c1),22*(1-ent.r1)) end if ent.c2>#kar[1] and ent.r2>#kar then gc2:drawRect(dbx,dby,22*(ent.c2-#kar[1]),22*(ent.r2-#kar)) end if ent.c1<1 and ent.r2>#kar then gc2:drawRect(dbx+22*(ent.c1+#kar[1]-1),dby,22*(1-ent.c1),22*(ent.r2-#kar)) end if ent.r1<1 and ent.c2>#kar[1] then gc2:drawRect(dbx,dby+22*(ent.r1+#kar-1),22*(ent.c2-#kar[1]),22*(1-ent.r1)) end if ent.sym_r9 then drawEntoure({r1=9-ent.r2 , c1=ent.c1 , r2=9-ent.r1 , c2=ent.c2}) end if ent.sym_c9 then drawEntoure({r1=ent.r1 , c1=9-ent.c2 , r2=ent.r2 , c2=9-ent.c1}) end if ent.sym_rc9 then drawEntoure({r1=9-ent.r2 , c1=9-ent.c2 , r2=9-ent.r1 , c2=9-ent.c1}) end if ent.sym_r5 then li1=5-ent.r2 li2=5-ent.r1 if li2<1 then li1=li1+8 li2=li2+8 end drawEntoure({r1=li1 , c1=ent.c1 , r2=li2 , c2=ent.c2}) end if ent.sym_c5 then co1=5-ent.c2 co2=5-ent.c1 if co2<1 then co1=co1+8 co2=co2+8 end drawEntoure({r1=ent.r1 , c1=co1 , r2=ent.r2 , c2=co2}) end if ent.sym_rc5 then drawEntoure({r1=li1 , c1=co1 , r2=li2 , c2=co2}) end if ent.sym_r9c5 then drawEntoure({r1=9-ent.r2 , c1=co1 , r2=9-ent.r1 , c2=co2}) end if ent.sym_r5c9 then drawEntoure({r1=li1 , c1=9-ent.c2 , r2=li2 , c2=9-ent.c1}) end end function ladder(eq,hist) eq2=math.eval("ladder("..gui..eq..gui..",0)") if hist==1 then sto_hist("Ladder "..eqvar.."=",eq2,1) end end function nand(eq) local f,po,pf,na nan=math.eval("transfo_nand("..gui..eq..gui..")") na=nan[1] f=string.find(na,"%(") while f~=nil do if string.sub(na,f-1,f-1)~="/" then na=string.sub(na,1,f-1)..string.sub(na,f+1) po=f-1 pf=f-1 while not(po==nil or po>pf) do po=string.find(na,"%(",po+1) pf=string.find(na,"%)",pf+1) end na=string.sub(na,1,pf-1)..string.sub(na,pf+1) f=string.find(na,"%(",f) else f=string.find(na,"%(",f+1) end end nan[1]=na sto_hist("NAND "..eqvar.."=",nan[1],1) end function sto_hist(egal,eq,shift) if eq==histo[1] then return 1 elseif eq==histo[2] then return 2 elseif eq==histo[3] then return 3 elseif eq==histo[4] then return 4 else math.eval("augment({"..gui..eq..gui.."},left(histo,25))=:histo:augment({"..gui..egal..eq..gui.."},left(hist,25))=:hist") hist=var.recall("hist") histo=var.recall("histo") if shift==0 then cours=1 else cours=cours+1 end var.store("cours",cours) return 0 end end function gen_eqvar() if n_eq>9 then return "S"..string.uchar(8320+math.floor(n_eq/10)%10)..string.uchar(8320+n_eq%10) else return "S"..string.uchar(8320+n_eq%10) end end function titre(str) local stw,sth,aba,db gc2:setFont("serif","b",12) stw=gc2:getStringWidth(str) sth=gc2:getStringHeight(str) for aba=0,sth,2 do gc2:setColorRGB(255,255-55*aba/sth,255-100*aba/sth) gc2:fillPolygon({(ww-stw-sth*(1-aba/sth/2))/2,0,(ww-stw)/2,sth-aba,(ww+stw)/2,sth-aba,(ww+stw+sth*(1-aba/sth/2))/2,0}) end gc2:setColorRGB(0,0,0) gc2:drawString(str,(ww-stw)/2+1,1,"top") gc2:setColorRGB(0,180,0) gc2:drawString(str,(ww-stw)/2,0,"top") end function text(str,x,y,r1,g1,b1,r2,g2,b2) local out,f,n,hh,aba out={} hh=gc2:getStringHeight(str) n=1 f=string.find(str,"::") while f~=nil do out[n]=string.sub(str,1,f-1) str=string.sub(str,f+2) n=n+1 f=string.find(str,"::") end out[n]=str gc2:setFont("serif","i",10) if not(b2==nil) then gc2:setColorRGB(r2,g2,b2) gc2:fillRect(x,y,ww-x-5,hh*n+4) end if not(b1==nil) then gc2:setColorRGB(r1,g1,b1) else gc2:setColorRGB(0,0,0) end for aba=0,n-1 do gc2:drawString(out[aba+1],x+4,y+hh*aba,"top") end return y+hh*n end function fillRoundRect(x,y,wd,ht,radius) if radius > ht/2 then radius = ht/2 end gc2:fillPolygon({(x-wd/2),(y-ht/2+radius), (x+wd/2),(y-ht/2+radius), (x+wd/2),(y+ht/2-radius), (x-wd/2),(y+ht/2-radius), (x-wd/2),(y-ht/2+radius)}) gc2:fillPolygon({(x-wd/2-radius+1),(y-ht/2), (x+wd/2-radius+1),(y-ht/2), (x+wd/2-radius+1),(y+ht/2), (x-wd/2+radius),(y+ht/2), (x-wd/2+radius),(y-ht/2)}) x = x-wd/2 y = y-ht/2 gc2:fillArc(x + wd - (radius*2), y + ht - (radius*2), radius*2, radius*2, 1, -91); gc2:fillArc(x + wd - (radius*2), y, radius*2, radius*2,-2,91); gc2:fillArc(x, y, radius*2, radius*2, 85, 95); gc2:fillArc(x, y + ht - (radius*2), radius*2, radius*2, 180, 95); end -- From Better Lua. Merci a Adriweb ! function deepcopy(t) if type(t) ~= 'table' then return t end local mt = getmetatable(t) local res = {} for k,v in pairs(t) do if type(v) == 'table' then v = deepcopy(v) end res[k] = v end setmetatable(res,mt) return res end -- From better Lua. Merci a Adriweb !