Project Euler - Problema 3
8/Jun 2015
Definizione del problema
Per prima cosa la definizione del problema è la seguente:
The prime factors of 13195 are 5, 7, 13 and 29.
What is the largest prime factor of the number 600851475143 ?
La traduzione in italiano recita:
I fattori primi di 13195 sono 5, 7, 13 e 29.
Quale è il più grande fattore primo del numero 600851475143 ?
Verifica di primalità
Un numero è primo se e solo se è divisibile solo per 1 e per se stesso.
Sono stati proposti numerosi metodi per verificare la primalità di un numero (vedi Test Primalità); alcuni sono efficienti ma molto complessi da implementare. Io utilizzerò un metodo semplice anche se poco efficiente: dato n il numero di cui si vuole verificare la primalità, si eseguono i seguenti passi
- si elencano tutti i numeri compresi tra 2 e \(\sqrt{n}\)
- si calcola il resto della divisione intera con n
- si verifica che tutti i resti siano diversi da zero
Codifica in clojure
(defn prime? [n]
(let [max (Math/sqrt n)
v (range 2 (inc max))
mv (map #(pos? (rem n %)) v)]
(every? true? mv)))
Possiamo verificare in repl:
user => (prime? 12)
false
user => (prime? 167)
true
user => (prime? 123)
true
Soluzione
A questo punto applichiamo il predicato prime? appena definito. Procediamo nel seguente modo:
- definiamo una costante con il numero del problema
- calcoliamo la radice quadrata anche per lui
- creiamo un range decrescente
- preleviamo solo i numeri primi divisori
- prendiamo il primo
(def p3-number 600851475143)
(def sq-p3-number (int (Math/sqrt p3-number)))
(def p3-solution (->> (range sq-p3-number 2 -1)
(filter #(and (prime? %) (zero? (rem p3-number %))))
first))