Il tuo corpo è fatto di cellule che contengono il DNA. Queste cellule si usurano regolarmente e devono essere sostituite: ci riescono dividendosi in cellule figlie. Anzi, il corpo umano medio va incontro a circa 10 milioni di miliardi di divisioni cellulari nel corso della vita!
Quando le cellule si dividono, si replica anche il loro DNA. A volte, durante questo processo, capita qualche errore e singoli pezzi di DNA vengono codificati con l'informazione sbagliata. Se confrontiamo due filamenti di DNA e contiamo le differenze tra loro, possiamo vedere quanti errori si sono verificati. Questa grandezza è nota come «distanza di Hamming».
La distanza di Hamming è utile in molti ambiti della scienza, non solo in biologia: è quindi una bella espressione da conoscere :)
Calcola la distanza di Hamming tra due filamenti di DNA.
Il DNA si legge usando le lettere C, A, G e T. Due filamenti potrebbero apparire così:
GAGCCTACTAACGGGAT
CATCGTAATGACGGCCT
^ ^ ^ ^ ^ ^^
Hanno 7 differenze, quindi la distanza di Hamming è 7.
La distanza di Hamming è definita solo per sequenze di uguale lunghezza: calcolarla tra sequenze di lunghezza diversa non dovrebbe funzionare.
Option si usa per indicare un calcolo che potrebbe non avere un risultato utile
(per esempio a causa di un errore o di un input non valido).
Se non conosci Option, puoi leggere questo tutorial.
Option è una cosiddetta Monad che copre un «aspetto computazionale», in questo caso la possibile assenza di un valore.
Un uso corretto delle Monad può portare a un codice molto conciso ma elegante
e leggibile. Un uso scorretto può facilmente portare all'opposto.
Guarda questo video per saperne di più.
Ci sono alcune regole pratiche per Option:
def add1(x: Int): Option[Int] = Some(x + 1)
meglio avere
def add1(x: Int): Int = x + 1
(esiste Option.map per applicare funzioni così semplici,
quindi non devi appesantirle con Option).
2. Non fare «unwrap» se non ne hai davvero bisogno.
Spesso ci sono funzioni integrate che fanno al caso tuo. Indicatori di un unwrap prematuro
sono isDefined/isEmpty o il pattern matching. Invece di
val x: Option[Int] = ...
if (x.isDefined) x.get + 1 else 0
// or
x match {
case Some(n) => n + 1
case None => 0
}
meglio avere
x map (_ + 1) getOrElse 0
Option. Invece dival xo: Option[Int] = ...
val yo: Option[Int] = ...
val zo: Option[Int] = ...
xo.flatMap(x =>
yo.flatMap(y =>
zo.map(z =>
x + y + z)))
meglio avere
for {
x <- xo
y <- yo
z <- zo
} yield x + y + z
Iscriviti a Exercism per imparare e padroneggiare Scala con 95 esercizi e il mentoring di persone reali, tutto gratis.