platform.apilevel = '1.0' -- NombreGeek par Extra44 strH = 0 -- hauteur caractère en pixel dans on.paint mode = 0 -- mode pour affichage/calcul algo() g1 = 42 -- g=g1 de départ k = 5 -- k de départ gk={""} -- str résultat 'gk' (un seul element si len jusqu'a taux=3.2) (v34d -> taux = 3.30=1/0.3028) function on.varChange() -- Gestion des variables "g1" et "k" local a, b a = var.recall("g1") -- variable utilisée dans page editeur mathematique if a ~= g1 then errMsg={} if a<0 or math.floor(a)~=a or a>9e+015 then -- sur pc avant qu'il perde les pedales on a g max à env 9.e+015 mode=10 errMsg[1]="g1 doit être un ENTIER compris dans [0; 9e+015] !" errMsg[2]="g1 saisi=" .. a errMsg[3]="g1 mémorisé=" .. string.format("%.0f",a) return 1 -- disallow modifications end g1=a mode=1 platform.window:invalidate() end b = var.recall("k") if b ~= k then errMsg={} if b<1 or b>1000 or math.floor(b)~=b then mode=10 errMsg[1]="il faut k ENTIER ?[1;1000]!" -- NB : tests actuels : k max rendant un résultat : k=63 sur pc (et 51 on calc) return 1 end k=b mode=1 platform.window:invalidate() end return 0 end function on.arrowUp() local i=math.ceil(gn/200) iPage=iPage+math.floor(i/10) -- 1/10e du nb de pages suivante if iPage>i then iPage=i end getPage_gk() platform.window:invalidate() end function on.arrowDown() local i=math.ceil(gn/200) iPage=iPage-math.floor(i/10) -- 1/10e du nb de pages préc if iPage<1 then iPage=1 end getPage_gk() platform.window:invalidate() end function on.arrowLeft() if iPage>1 then iPage=iPage-1 -- page précédente getPage_gk() platform.window:invalidate() end end function on.arrowRight() local i=math.ceil(gn/200) if iPageCalculs en cours...",150,a) algo() if mode==1 then mode=3 end end if mode==3 then -- mode =3 : affichage du résultat (mémorisé/précédent) aff_gk(gc) elseif mode==10 then -- mode =10 : il y a une erreur; affichage du message dans errMsg gc:drawString("Erreur !",150,a) for b=1, #errMsg do a=a+strH gc:drawString(errMsg[b],0,a) end elseif mode==11 then -- clear screen : ne plus afficher les résultats sur l'écran. for b=1, #errMsg do a=a+strH gc:drawString(errMsg[b],0,a) end end -- Affichage du menu a=a+strH+strH -- N° de page affichée : gc:drawString("'? ???' = page ".. iPage .."/" .. math.ceil(gn/200) , 150, a) a=a+strH gc:drawString("l=lancer algo",150,a) -- 5H : raccourci clavier a=a+strH gc:drawString("c=clear/efface ecran",150,a) -- 6H a=a+strH gc:drawString("Cidessous : exécuter :",150,a) -- 7H -- instruction pour modifier / lancer l'algo avec des paramètres (g1, k) différents a=a+strH gc:drawString("dans la 'boite mathématique'",150,a+strH) -- 9H : pour n'afficher qu'une ligne en en italic & bold, on affiche la derniere ligne (normale) en 9H gc:setFont("sansserif", "bi", 9) gc:drawString("algo(g1,k)",150,a) -- puis en 8H la ligne en italic&bold (et taille 9) end function aff_gk(gc) -- Affichage de la page 'iPage' ' des resultats avec defilement possible par +/- : local a, b, c, d, n, o a=strH+strH -- hauteur de l'affichage de la ligne, debut = 2H c=a -- mémorisation ligne d'affichage actuelle (2H) gc:drawString("g" ..k .." (" .. gn .. " chiffres)", 150, a) -- 2H b=gc:getStringWidth("1") -- offset/tabulation horizontale pour alignement des n° de ligne (1..10) à droite if gn<21 then -- moins d'une ligne ? gc:drawString("1 : "..strPage, b, c) -- 3H else n=#strPage a=c -- ligne 2H c=1 -- index début du caract. a afficher o=1 -- n° de ligne a afficher (1..10) while c9 then b=0 -- offset horizontal affichage (ligne code ci dessous), pour aligner les n° de ligne (1..10) à droite end d=c+19 if d>n then d=n end gc:drawString(o.." : " .. string.sub(strPage, c, d), b, a) -- pour o=1 : 1ere ligne: en 2H a=a+strH -- ligne (position d'affichage en pixel) suivante o=o+1 -- n° ligne (1..10) de résultat suivant c=c+20 -- position 1er caractère de la ligne suivante end end end function getPage_gk() local a, b, c, n, n2, t, u c=(iPage-1)*200+1 -- index début chaine a afficher n=0 b=0 n2=#tdezip repeat b=b+1 -- indice tableau de str resultat (1..) if bZip==true then t=Decompress_gk(b) else t=gk[b] -- t chaine gk[b] end u=#t -- longueur gk[b] (dezipé si besoin) n=n+u -- taille cumulée depuis gk[1]...gk[b] until n>=c a=0 -- dernier car a afficher dans gk[b] if n-c<200 then a=u -- moins de 200 chiffres dans gk[b] : jusqu'a fin de gk[b] else a=u-n+c+199 -- ne prendre en tout que 200 ch end strPage=string.sub(t,u-n+c,a) -- u-n+c=u-(n-c) = debut du 'c'ieme car dans gk[b] a=#strPage if a<200 and n1 then return -- si deja decoupée, on sort ! end -- Decoupage chaine trop longue -- i: indice tabl gk[i] i=1 d=1 -- 1er chiffre dans str resultat a decouper w=gk[1] gk[1]="" -- liberation memoire while dgn then f=gn end gk[i]=string.sub(w, d, f) i=i+1 d=f+1 -- chiffre suivant (f+1) end -- while end function algo() -- algorithme du nombre du geek. -- Lancé soit par une touche "l" (petit 'L'), soit par l'exécution de la fonction algo(g1,k) dans la boite mathématique de la fenetre du bas de l'interface -- en lancant la fonction "algo(42,5)" (puis Return/EXE) par exemple -- NB : -- * Pour les itérations (k) 2 et 3 , il faut "lire" basiquement, il y a -- beaucoup trop de combinaisons pour effectuer des recherches/remplacement par string.gsub -- * Le remplacement se fait par string.gsub (remplacement des occurences...), les chiffres 1 à 3 -- se répétent très souvent, au contraire des autres chiffres (0, et 4..9) local q={"222","111","33","22","11", "1", "2", "3", "B", "A", "c", "b", "a", "i", "j", "k"} local r={"B", "A", "c", "b", "a", "i", "j", "k", "32", "31", "23", "22", "21", "11", "12", "13"} local l iPage=1 -- nouveau calcul :reinit de la page d'affichage a 1 (sinon peut y avoir des bug affichage ...) gk={""} -- nlle recherche : vidage memoire gk: bZip=false if k==1 then strPage=tostring(g1) gn=#strPage gk[1]=strPage return end l=algo_etape1(q, r) if l==0 then return end -- maintenant à partir de k=4, on réalise l'algo par des "string.gsub" : il y a un nb de combinaisons limitées -- (car les chiffres autres que 1,2,3 sont isolés par de 1,2 ou 3)! l=algo_etape2(l, q, r) if gn>gcoupelim and l a k algo_etape3(q, r) bZip=true -- flag compression à 1 ici. end end if gn<=200 then -- chaine (200 chiffres) a afficher strPage=gk[1] elseif bZip==true then -- >200 ch et non zippé : on va prendre les 200 premiers chiffres de la chaine 1 après dezippage strPage=string.sub(Decompress_gk(1), 1, 200) else -- >200ch et zippé : on va prendre les 200 premiers chiffres de la chaine 1 (sans sippage) strPage=string.sub(gk[1], 1, 200) end end function algo_etape1(q, r) -- Optimisation des rech : en fonction des chiffres present (autres que 1,2,3): on ne fait les rech que pour les -- chiffres présents : local w, w0, n, o, a, b, c, l l=3 -- 1ere traitement: boucle jusqu'a 3 ou k si plus petit ... w=string.format("%.0f",g1) -- pour les nombres >= 1e+014 (14 ch) on enleve le format scientifique if l>k then l=k -- k<3 ? (au cas ou k est plus petit que 3, alors k -> dans l end for y=2, l do -- ligne y ( jusqu'a 3 ou k si plus petit) w0=w -- 1ere (puis 2e) itération pour 'compter'/lire la 1ere ligne et en construire g2 (puis g3) n=#w -- longueur gk (donc gi) initial w="" o=1 -- index char dans gi b=string.sub(w0, 1, 1) -- caract (de départ) concerné while o<=n do -- bcl de parcourt de tous les char suivant de gi c=0 -- nb caract identiq a=b -- a=caract de départ : -- comptage du nombre de caractères identiques au char mémorisé dans 'a' à la suite: repeat -- bcl de parcourt des char identique c=c+1 o=o+1 b=string.sub(w0, o, o) -- caract courant until o>n or b~=a w=w .. c .. a -- écriture du nombre de caractère identique & caractere concerné à la suite du resultat (itération courante)... end gk[1]=w gn=#w if w==w0 then -- cas de ligne y qui ne varie pas (g1=22 alors g2= ...= g999=...=22 par ex) strPage=w return 0 end end OptimizeSearch(w, q, r) return l end function OptimizeSearch(w, q, r) -- Ajout des chiffres présent autres que 1,2,3 dans le tableau de recherche de l'algo... local s={ "4", "5", "6", "7", "8", "9", "0"} -- chiffres pas toujours present local t={"14","15","16","17","18","19","10"} for x=1, 7 do if string.find(w, s[x]) then table.insert(q, s[x]) table.insert(r, t[x]) end end end function algo_etape2(l, q, r) local n, w n=#q w=gk[1] for y=l+1, k do -- ligne y ( de 4 --> a k) for x=1, n do -- remplacement des ch 1,2,3 par a,b,c; puis 4..9 et 0 par leur lecture : "14","15",..."19", "10" w=string.gsub(w, q[x], r[x]) -- l'ordre des rech = ordre dans le tabl : TRES important !!! end gn=#w if ygcoupelim then -- si str trop long, et reste 1 ou des iterations : on sort pour decoupe la str resultat: l=y break end l=y end gk[1]=w gn=#w return l end function Decompress_gk(m) -- Decompression de gk[m] et retourne la chaine decompressée local n2=#tdezip local w=gk[m] for x=1, n2 do w=string.gsub(w, tzip[x], tdezip[x]) end return w end function Compress_gk(m) -- Compression de gk[m] dans gk[m] local n2=#tdezip for x=1, n2 do -- compression gk[m]=string.gsub(gk[m], tdezip[x], tzip[x]) end end function algo_etape3(q, r) local a, m, nq, u, o, ngk nq=#q ngk=#gk gn=0 a=0 -- index ch dans gk[c+1] deja utilisé (=0 si pas encore utilisé) m=1 if bZip==true then gk[m]=Decompress_gk(m) end while m<=ngk do -- on parcourt les gk... u=#gk[m] o=string.sub(gk[m], u, u) -- dernier ch de gk[m] gk[m]=string.sub(gk[m],a+1, u) -- chaine de travail en cours (~=gk[m] + qq ch de gk[m+1)) if m0 then -- on met les chiffres identiq de la str suivante dans la str courante gk[m]=gk[m]..string.sub(gk[m+1], 1, a) end end--if for x=1, nq do -- iteration courante (lecture nb geek) : gk[m]=string.gsub(gk[m], q[x], r[x]) end--for gn=gn+#gk[m] -- maj nombre ch du resultat courant Compress_gk(m) m=m+1 end -- while end