HACKING 120% {Hacking, programmazione, computer & molto altro}

Esercizio sui numeri primi

« Older   Newer »
  Share  
view post Posted on 2/11/2011, 19:56     +1   -1
Avatar

Water can take unforseen forms.

Group:
Founder
Posts:
5,273
Reputation:
+1,147
Location:
Shabang

Status:


Ok, l' esercizio (molto semplice), consiste nel trovare da un numero preso in input tutti i numeri primi presenti tra esso e il suo doppio. Se il numero sarà zero, il programma comunicherà errore per ogni altro numero darà il risultato.
 
Web  Top
Krypt05
view post Posted on 27/6/2012, 09:30     +1   -1




Sto cercando l'algormitmo che, dato di input un numero, restituisca True se è primo e False se non lo è.

Ci sono riuscito, ma senza applicare la funzione ricorsiva:
CODICE
def VerificaPrimi(x):
   c=True
   i=2
   while i<=(x-1)/2 and c==True:    
       if x%­i!=0:
           i=i+1
       else:
           c=False
   if c==False:
       return False
   else:
       return True
x=int(raw_input())
print VerificaPrimi(x)


Solo che questo non mi soddisfa perchè fa dei calcoli inutili... ammettendo che si inserisca il numero 23, prova a dividerlo per 2, poi per 3, e fin qui è corretto, poi per 4, e qui non va bene perchè se non è divisibile per due non lo è nemmeno per 4, ed è un calcolo risparmiabile, poi lo divide per 5 e va bene, poi per 6, ed è un altro calcolo inutile perchè se non è divisibile ne per 2 ne per 3 non lo è nemmeno per 6.
Quindi ho pensato che ha senso provare a dividere il numero inserito soltanto per i numeri primi inferiori alla sua metà che lo precedono, in questo modo il numero di calcoli che python deve effettuare diminuisce enormemente, soprattutto in caso di un valore di input molto elevato.

E quindi ho fatto questo:
CODICE
def VerificaPrimi(x):
   c=True
   i=2
   while i<=x/2 and c==True:
       if VerificaPrimi(i)==True:
           if x%­i!=0:
               i=i+1
           else:
               c=False
   if c==False:
       return False
   else:
       return True
   i=i+1
x=int(raw_input())
print VerificaPrimi(x)


Inizialmente sembra funzionare, ma stranamente da un certo valore in poi (mi pare il 17) mi pare che restituisca soltanto False per i numeri pari immessi, mentre per tutti i dispari (primi o no) non restituisce nulla, e non capisco perchè : \

Igitur te voco, Wet Water, ut ducas me recto iteris.
 
Top
view post Posted on 27/6/2012, 10:51     +1   -1
Avatar

Water can take unforseen forms.

Group:
Founder
Posts:
5,273
Reputation:
+1,147
Location:
Shabang

Status:


Usare la metà è sbagliato, devi usare la radice quadrata.

Wikipedia spiega il perché:
http://it.wikipedia.org/wiki/Crivello_di_Eratostene

Quindi inizi così

CODICE
from math import sqrt


E poi trovi l'sqrt chiamando normalmente una funzione importata

CODICE
sqrt(numero)


Dovrebbe avere anche qualche altro errore, mo lo vedo :)

PS: odio i source che lavorano tanto sui booleani.

Ho trovato qualcosina qui:

http://it.wikibooks.org/wiki/Python/Esempi

Ma usando una lista per rimuovere i valori eviti i doppioni e riduci di molto il tempo, lo implemento, chiedo 5 minuti.

Edit: no, non si riduce il tempo, perché devi mettere un for x in range nella lista dentro un altro range quindi viene troppo alto.
 
Web  Top
*Atwa*
view post Posted on 27/6/2012, 11:58     +1   -1




CITAZIONE
Ma usando una lista per rimuovere i valori eviti i doppioni e riduci di molto il tempo, lo implemento, chiedo 5 minuti.

Puoi usare i set al posto del for x in tuttoquellochevuoi.
 
Top
Krypt05
view post Posted on 27/6/2012, 12:09     +1   -1




Immagino che utilizzando liste e for x in range tutto sia molto più facile, ma io vorrei usare solo quello che ho imparato finora, ovvero funzioni semplici, ricorsive, istruzioni condizionali e ciclo while.
Quella cosa del Crivello di Eratostene è davvero interessante, grazie per avermelo fatto presente : )

Riassumendo: il primo codice va bene?
E il secondo cos'ha che non va?

Edit:
Nel frattempo ho scritto di nuovo la funzione che verifica se un numero è primo o no, ma è più sintetica della prima (senza funzione ricorsiva):
CODICE
def VerificaPrimo(numero):
   import math
   i=2
   c=True
   while i<=math.sqrt(numero) and c==True:
       resto=numero%­i
       if resto!=0:
           i=i+1
       else:
           c=False
   print c

numero=int(raw_input())
VerificaPrimo(numero)




Edited by Krypt05 - 27/6/2012, 14:28
 
Top
*Atwa*
view post Posted on 28/6/2012, 12:21     +1   -1




CITAZIONE (Krypt05 @ 27/6/2012, 13:09) 
Immagino che utilizzando liste e for x in range tutto sia molto più facile, ma io vorrei usare solo quello che ho imparato finora, ovvero funzioni semplici, ricorsive, istruzioni condizionali e ciclo while.
Quella cosa del Crivello di Eratostene è davvero interessante, grazie per avermelo fatto presente : )

Riassumendo: il primo codice va bene?
E il secondo cos'ha che non va?

Edit:
Nel frattempo ho scritto di nuovo la funzione che verifica se un numero è primo o no, ma è più sintetica della prima (senza funzione ricorsiva):
CODICE
def VerificaPrimo(numero):
   import math
   i=2
   c=True
   while i<=math.sqrt(numero) and c==True:
       resto=numero%­i
       if resto!=0:
           i=i+1
       else:
           c=False
   print c

numero=int(raw_input())
VerificaPrimo(numero)

Il primo codice va bene e dà output giusti.
Il secondo no, dimenticalo completamente D:
L'ultimo che hai fatto va bene, però se fossi in te userei return c al posto di print c :P .
Ah leggiti la PEP08 , ti sarà utile quando dovrai pubblicare i tuoi prossimi source :asd:
 
Top
Krypt05
view post Posted on 28/6/2012, 12:40     +1   -1




Ook grazie, allora ci metto return e mi leggo quel PEP08 : )
 
Top
6 replies since 2/11/2011, 19:56   159 views
  Share