Hamming

Hamming

Fácil

Introducción

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 :)

Instrucciones

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.

Notas de implementación

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.

Errores comunes que deberías evitar

Hay unas cuantas reglas generales para Option:

  1. Si no lo necesitas, no lo uses. En lugar de
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
  1. Las mónadas se pueden usar dentro de una for-comprehension. ¡Todo son ventajas! Esto es recomendable cuando quieres «componer» varias instancias de Option. En lugar de
val 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
Editar en GitHub El enlace se abre en una ventana o pestaña nueva
Scala Exercism

¿Listo para empezar Hamming?

Regístrate en Exercism para aprender y dominar Scala con 95 ejercicios y mentoría humana real, todo gratis.