Generare una lista di primi usando il teorema di Wilson e la primalità con Fermat Il teorema di Wilson afferma che: Sia N un intero > 2. allora N è primo sse (N-1)! = -1 (mod N) il simbolo = sta per congruente Questo criterio di primalità non è molto efficiente perché comunque richiede una certa potenza di calcolo. Per questo motivo proponiamo un programma scritto con il potente linguaggio di programmazione Python che permette di gestire numeri interi molto grandi : tramite la funzione Wilson() di generare una lista di primi tramite la funzione testwilson(p) di effettuare un test di primalità tramite la funzione fattore(p) vengono generati numeri pseudocasuali tra 2 la radine quadrata del numero da fattorizzare fino a trovare una soluzione. Tramite la funzione testprimo(p) si fa un test di primalità e nel caso il numero non sia primo viene fornito un fattore Nel codice sono presenti anche altre funzioni utili alla teoria dei numeri, alla fattorizzazione degli interi e alla ricerca dei numeri primi Ecco il codice in Python import math def mcd(a,b): if b == 0: return a else: return mcd(b, a%b) def fattoriale(x): if x < 2: return 1 else: return x*fattoriale(x-1) Per il fattoriale c'è anche la funzione math.factorial(x) e per la potenza math.pow(x,y) def divisore(num,den): if den ==1: return num else: return float(num)/den def potenza(a,b): if b == 0: return 1 else: return a*potenza(a,b-1) def wilson(): n = 3; while(n < 100): if fattoriale(n-1)%n == -1%n: print(n); n = n+1; return 1; def testwilson(n): if fattoriale(n-1)%n == -1%n: print('è primo'); else: print('non è primo'); return 1; def fattore(p): import random; import math; x = math.floor(random.random()*math.sqrt(p)); while(p/x != math.floor(p/x)): x = math.floor(random.random()*math.sqrt(p)); print (x); print (p/x); return 1; def testprimo(p): i = 2; while i < p: if mcd(i,p) != 1: print('non è primo'); print(mcd(i,p)); return 0; i = i+1; return 1; Per rimanere nel tema della primalità, possiamo costruire un programma in Python che sfrutti il piccolo teorema di Fermat ovvero se N è primo, per ogni intero a primo con N ho che a^(N-1)= 1 mod N. Questo dal punto di vista logico equivale a dire che se esiste un a tale che MCD(a,N) = 1 e a^(N-1) != 1 allora N non è primo. Quindi possiamo scrivere il seguente test di primalità (supponiamo per semplicità che N sia dispari e che l’ultima cifra non sia 0 o 5): def test2primo(N): j = 2; while j < N-1: if mcd(j, N) == 1: if (j** (N-1))%N != 1%N : return 'non è primo'; j = j+1; return 'è primo'; Ove ** è la funzione potenza che potevamo sostituire con potenza(a,b). Nota: Per generare numeri interi casuali che possono essere fattori di un numero intero p possiamo usare anche il PARI/Gp secondo il codice {fattor(p) = local(w); w = 1+random(floor(sqrt(p))); while( p/w != floor(p/w), w = 1+random(floor(sqrt(p)))); print(w); print(p/w); return(1);}