|
|
|
|
Coucou,
J'ai commencé à apprendre le Python depuis peu de temps. J'avais aussi commencé Ocaml il y a longtemps. Ahem, mes connaissances en prog n'ont pas tellement évoluées. Enfin bon, j'ai réussi à faire un petit programme que voici:
print "\n\t\t-----------------Faktoriz v.3,14-------------------\n"
menu_item = 0
while menu_item != "quit":
print "*^*^*^*^*^*^*^*^*^*^*^*^*^*^*^*^*^*^*^*^*^*^*^*^*^*^*^*^*^*"
print "\n$Type 'do' to Faktoriz(TM) a number"
print "$Type 'quit' if you really insist\n"
menu_item = raw_input("What'll it be? ")
if menu_item == "do":
A = input("\nEl number stp (ouais, entier supérieur ou égal à 2, hein, tu veux pas faire planter mon prog non plus?): ")
div = 2
resultat = str(A) + " = "
print "\n"
while div <= A:
if A%div == 0:
print A, div
puiss = 1
resultat += str(div)
while A%div == 0:
A = A/div
if A == 1:
print A, "Done."
resultat += "^" + str(puiss) + "\n" # pour le dernier facteur (surtout si c'est tous les mêmes e.g. 2^8)
elif A%div != 0: # sinon ça imprime une ligne de trop comme A a changé entre temps
resultat += "^" + str(puiss) + " * " # on change de facteur
pass
else:
print A, div
puiss += 1
else:
div = div + 1
print "\n", resultat
print "\nDon't go!.. :( Punk."
Je vous demanderais d'excuser les prompts débiles ainsi que les commentaires naifs mais ça faisait longtemps que j'avais pas fait de boucles..
Bon, mes questions sont les suivantes:
je sais que c'est peut-être pas après mon premier programme que je devrais me soucier d'optimisation mais, dès qu'un facteur dépasse les quelques millions, le temps de calcul devient long voire interminable, ce qui est assez pitoyable.
J'ai lu un article de Van Rossum à ce propos mais mes connaissances sont encore basiques et j'ai rien pigé.
J'ai fait ça en pur style impératif (oui, là ma connaissance approfondie de Ocaml me permet de le reconnaitre ;) peut-être une fonction récursive (ah.. let rec, c'était beau, c'était dur..)? Enfin c'est une suggestion au pif..
Autrement, petite question technique, j'ai réussi à le compiler avec py2exe (je suis sous windoze, n'est-ce pas) mais mon exécutable fait environ 2Mo, pour une source de 2Ko c'est pas terrible.. Comment puis-je réduire ça?
J'espère que quelqu'un aura des suggestions pour rendre mon code plus élégant, plus efficace, plus cool quoi, peut-être même l'illustre Sebsauvage (dont je complimente le site au passage)..
Merci d'avance
PS; j'offre bien évidemment ce code source à tout le monde (GNU/GPL , ce que vous voulez), pour ce qu'il vaut..
Salut,
|
Salut Pascal,
print "\n\t\t-----------------Faktoriz v.3,14-------------------\n"
menu_item = 0
while menu_item != "quit":
print "*^*^*^*^*^*^*^*^*^*^*^*^*^*^*^*^*^*^*^*^*^*^*^*^*^*^*^*^*^*"
print "\n$Type 'do' to Faktoriz(TM) a number"
print "$Type 'quit' if you really insist\n"
menu_item = raw_input("What'll it be? ")
if menu_item == "do":
A = input("\nEl number stp (ouais, entier supérieur ou égal à 2, hein, tu veux pas faire planter mon prog non plus?): ")
div = 2
resultat = str(A) + " = "
print "\n"
while div <= A:
if A%div == 0:
print A, div
puiss = 1
resultat += str(div)
while A%div == 0:
A = A/div
if A == 1:
print A, "Done."
resultat += "^" + str(puiss) + "\n" # pour le dernier facteur (surtout si c'est tous les mêmes e.g. 2^8)
elif A%div != 0: # sinon ça imprime une ligne de trop comme A a changé entre temps
resultat += "^" + str(puiss) + " * " # on change de facteur
pass
else:
print A, div
puiss += 1
else:
div = div + 1
print "\n", resultat
print "\nDon't go!.. :( Punk." |
J'ai du nouveau sur ce fichu prog.. Bon, comme suggéré je suis retourné voir mon prog de nombres premiers.
upper = input("upper? ")
primes = [2]
for elem in range(3, upper+1):
for x in primes:
if elem % x == 0: # break dès qu'un nombre premier dans la liste est un diviseur
break
else:
n = primes[-1] + 1
while n <= elem:
if elem % n != 0:
n += 1
else: # c'est le prochain nombre premier
primes.append(elem)
break
print primes
Bon, sûrement qu'il y a mieux à faire mais j'ai arrêté là, les yeux ensanglantés, la vie sociale annéantie.. ;) Mais après, en réfléchissant, je me suis dis que c'est pas très utile d'avoir une liste pré-calculée parce qu'en fait, tout ce que fait le programme c'est ajouter 1 au diviseur et voir si le nouveau nombre est un facteur du nombre cherché. Et il ne commence à ralentir vraiment que vers le million. Ca prend plus longtemps pour calculer un million de nombres premiers que de laisser mon prog comme ça. Donc après je me suis dit: pourquoi pas, quand on change de diviseur, faire en sorte que ça soit le prochain nombre premier (plutôt que juste incrémenter). Mais la on se paye le problème de devoir en plus calculer si c'est un nombre premier! J'ai essayé, peut-être que je l'ai mal fait mais mon prog prenait 10 fois plus longtemps! Finalement la seule optimisation à laquelle j'ai pensée c'est: Ben, virer tous les diviseurs pairs, puisque le premier truc que fait mon prog c'est essayer de diviser le nombre donné par 2. Ca laisse évidemment tous les doublons 3*k, 5*k, 7*k (k:impair).. Mais bon: voir si le prochain diviseur est pair c'est rapide. J'ai tenté et ça accélère légèrement l'affaire.. Des suggestions? :))) (Bon sang, j'écris beaucoup!) |
Rhaâ, si!!
def primes(n): if n==2: return [2] elif n<2: return [] s=range(3,n+2,2) mroot = n ** 0.5 half=(n+1)/2 i=0 m=3 while m <= mroot: if s[i]: j=(m*m-3)/2 s[j]=0 while j<half: s[j]=0 j+=m i=i+1 m=2*i+3 return [2]+[x for x in s if x]Bon mais ça m'avance pas tellement.. Si je compile le programme, ça irait plus vite? Bon, faut que je révise mes maths moi.. ~Wonderful Bangladesh~ |
Hello.
|
Merci!
|
Tiens, j'ai trouvé un nouvel algo pour factoriser.
|