Antonio_Scalzo beh, fantastico! Infatti l'ho testato e devo dire che (empiricamente) funziona alla grande, dato che se confrontiamo anche la mia ottimizzazione, N/2 >> sqrt(N) quando andiamo a prendere N sufficientemente grande.
In particolare, dal mio codice migliore (algoritmo 3) di 8,7 secondi, con questa ottimizzazione ho ottenuto 0,029 secondi! Un miglioramento decisamente ottimo 🙂
Non ho modo però di dimostrarne la validità generale (ok, possiamo dimostrarlo empiricamente per una lista più o meno grande di numeri primi...), così come affinare ulteriormente il metodo ovvero, c'è una ragione precisa (che magari mi sfugge) per cui debba arrivare alla radice quadrata del numero come valore limite? Oppure si può dimostrare la validità anche andando spingendosi oltre (quindi anche fermandosi ad un valore più piccolo di sqrt(j))?
Attualmente riuscirei solo a fare una verifica su base empirica. Intendo dire, la frase:
Antonio_Scalzo giacché tutti i divisori di J maggiori di sqrt(J) ... devono restituire numeri minori di sqrt(J) e che a loro volta sono dei divisori di J.
è sempre un'osservazione ricavata a posteriori, su base empirica, oppure una dimostrazione della validità generale? E come dicevo, in questo caso, perché proprio esattamente sqrt(j) come valore limite?
Edit: ho provato anche a spingermi leggermente oltre, ovvero anziché j0.5 ho imposto j0.4 ma su larga scala, andando a ricostruire la lista di numeri primi, in alcuni casi però non viene rispettata la condizione. Con sqrt(j) invece ho testato qualche migliaio di numeri primi ed effettivamente risulta verificato, coincidente con la lista calcolata in modo "tradizionale"! Al massimo posso testarlo su tutta la lista fino ad N, chiaro che risolverlo in modo empirico non è sufficiente come dimostrazione di validità generale.