Rutas
/
Scala
Scala
/
Ejercicios
/
Recuento de nucleótidos
Recuento de nucleótidos

Recuento de nucleótidos

Media

Instrucciones

Todos heredamos de nuestros padres biológicos un conjunto de instrucciones químicas conocido como ADN, que influye en cómo se construyen nuestros cuerpos. ¡Toda la vida conocida depende del ADN!

Nota: No necesitas saber nada sobre nucleótidos ni sobre el ADN para completar este ejercicio.

El ADN es una larga cadena de otras sustancias químicas, y las más importantes son los cuatro nucleótidos: adenina, citosina, guanina y timina. Una sola cadena de ADN puede contener miles de millones de estos cuatro nucleótidos, ¡y el orden en que aparecen es importante! Al orden de estos nucleótidos en un fragmento de ADN lo llamamos «secuencia de ADN».

Representamos una secuencia de ADN como una colección ordenada de estos cuatro nucleótidos, y una forma habitual de hacerlo es con un string de caracteres como «ATTACG» para una secuencia de ADN de 6 nucleótidos. «A» para la adenina, «C» para la citosina, «G» para la guanina y «T» para la timina.

Dado un string que representa una secuencia de ADN, cuenta cuántos hay de cada nucleótido. Si el string contiene caracteres que no son A, C, G o T, entonces no es válido y deberías señalar un error.

Por ejemplo:

"GATTACA" -> 'A': 3, 'C': 1, 'G': 1, 'T': 2
"INVALID" -> error

Un uso habitual de Either es indicar un cálculo que posiblemente dé lugar a un error (si el error en sí no te interesa, quizá sea mejor opción el tipo Option, más sencillo). Cuando no hay ningún error, el resultado suele ser un Right (regla mnemotécnica: el valor «right»), mientras que un error es un Left; por ejemplo, un Left[String] que contiene un mensaje de error. Ten en cuenta que, en Scala 2.12, Either está sesgado hacia la derecha de forma predeterminada, así que funciona como se espera en operaciones como filter, map, flatMap o en una for-comprehension. Si no conoces Either, puedes leer este tutorial. Pero ten en cuenta que este tutorial trata de versiones de Scala anteriores a la 2.12. Para Scala 2.12 puedes ignorar RightProjection sin problema y omitir .right. Either es lo que se conoce como una mónada que abarca un «aspecto computacional», en este caso el manejo de errores. El uso correcto de las mónadas puede dar lugar a un código muy conciso pero elegante y legible. Un uso incorrecto puede dar lugar fácilmente a lo contrario. Ve este vídeo para aprender más.

Errores comunes que debes evitar

Hay unas cuantas reglas generales para Either:

  1. Si no lo necesitas, no lo uses. En lugar de
def add1(x: Int): Either[String, Int] = Right(x + 1)

es mejor tener

def add1(x: Int): Int = x + 1

(existe Either.map para aplicar ese tipo de funciones tan sencillas, así que no hace falta que las sobrecargues con Either). 2. No hagas «unwrap» si no lo necesitas de verdad. A menudo existen funciones integradas para lo que buscas. Los indicios de un «unwrap» prematuro son isLeft/isRight o la coincidencia de patrones. Por ejemplo, en lugar de

val x: Either[String, Int] = ...

if (x.isRight) x.right.get + 1 else x.left.get
// or
x match {
  case Right(n) => n + 1
  case Left(s) => s
}

es mejor tener

x fold (identity, _ + 1)
  1. Las mónadas se pueden usar dentro de una for-comprehension. ¡Es lo mejor! Esto es recomendable cuando quieres «componer» varias instancias de Either. En lugar de
val xo: Either[String, Int] = ...
val yo: Either[String, Int] = ...
val zo: Either[String, 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 Recuento de nucleótidos?

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