Tu cuerpo está formado por células que contienen ADN. Esas células se desgastan con regularidad y hay que sustituirlas, algo que logran dividiéndose en células hijas. De hecho, el cuerpo humano medio experimenta unas diez mil billones de divisiones celulares a lo largo de la vida.
Cuando las células se dividen, su ADN también se replica. A veces, durante este proceso, se producen errores y piezas individuales de ADN se codifican con la información incorrecta. Si comparamos dos cadenas de ADN y contamos las diferencias entre ellas, podemos ver cuántos errores se produjeron. Esto se conoce como la «distancia de Hamming».
La distancia de Hamming es útil en muchas áreas de la ciencia, no solo en biología, así que es una expresión que merece la pena conocer :)
Calcula la distancia de Hamming entre dos cadenas de ADN.
Leemos el ADN con las letras C, A, G y T. Dos cadenas podrían tener este aspecto:
GAGCCTACTAACGGGAT
CATCGTAATGACGGCCT
^ ^ ^ ^ ^ ^^
Tienen 7 diferencias y, por tanto, la distancia de Hamming es 7.
La distancia de Hamming solo está definida para secuencias de la misma longitud, así que intentar calcularla entre secuencias de distinta longitud no debería funcionar.
Option se usa para indicar un cálculo que puede que no tenga un resultado útil
(por ejemplo, debido a un error o a una entrada no válida).
Si no estás familiarizado con Option, puedes leer este tutorial.
Option es una llamada mónada que cubre un «aspecto computacional», en este caso la posible ausencia de un valor.
El uso adecuado de las mónadas puede dar lugar a un código muy conciso pero elegante
y legible. Un uso inadecuado puede dar fácilmente el resultado contrario.
Mira este vídeo para aprender más.
Hay unas cuantas reglas generales para Option:
def add1(x: Int): Option[Int] = Some(x + 1)
es mejor tener
def add1(x: Int): Int = x + 1
(existe Option.map para aplicar funciones tan simples,
así que no hace falta que las sobrecargues con Option).
2. No «desenvuelvas» el valor si no lo necesitas de verdad.
A menudo existen funciones integradas para lo que quieres hacer. Los indicios de un
desenvolvimiento prematuro son isDefined/isEmpty o la coincidencia de patrones. En lugar de
val x: Option[Int] = ...
if (x.isDefined) x.get + 1 else 0
// or
x match {
case Some(n) => n + 1
case None => 0
}
es mejor tener
x map (_ + 1) getOrElse 0
Option. En lugar deval xo: Option[Int] = ...
val yo: Option[Int] = ...
val zo: Option[Int] = ...
xo.flatMap(x =>
yo.flatMap(y =>
zo.map(z =>
x + y + z)))
es mejor tener
for {
x <- xo
y <- yo
z <- zo
} yield x + y + z
Regístrate en Exercism para aprender y dominar Scala con 95 ejercicios y mentoría humana real, todo gratis.