Trilhas
/
Scala
Scala
/
Exercícios
/
Contagem de Nucleotídeos
Contagem de Nucleotídeos

Contagem de Nucleotídeos

Médio

Instruções

Cada um de nós herda dos nossos pais biológicos um conjunto de instruções químicas conhecidas como DNA, que influenciam a forma como o nosso corpo é construído. Toda a vida conhecida depende do DNA!

Observação: você não precisa entender nada sobre nucleotídeos ou DNA para completar este exercício.

O DNA é uma longa cadeia de outras substâncias químicas, e as mais importantes são os quatro nucleotídeos: adenina, citosina, guanina e timina. Uma única cadeia de DNA pode conter bilhões desses quatro nucleotídeos, e a ordem em que eles aparecem é importante! Chamamos a ordem desses nucleotídeos em um trecho de DNA de "sequência de DNA".

Representamos uma sequência de DNA como uma coleção ordenada desses quatro nucleotídeos, e uma forma comum de fazer isso é com uma string de caracteres como "ATTACG" para uma sequência de DNA de 6 nucleotídeos. 'A' para adenina, 'C' para citosina, 'G' para guanina e 'T' para timina.

Dada uma string que representa uma sequência de DNA, conte quantos de cada nucleotídeo estão presentes. Se a string contiver caracteres que não sejam A, C, G ou T, ela é inválida e você deve sinalizar um erro.

Por exemplo:

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

Um uso comum de Either é indicar uma computação que pode resultar em erro (se o erro em si não interessa, o tipo mais simples Option pode ser uma escolha melhor). Quando não há erro, o resultado costuma ser um Right (mnemônico: o valor "certo"), enquanto um erro é um Left, por exemplo um Left[String] contendo uma mensagem de erro. Repare que no Scala 2.12 o Either é enviesado para a direita por padrão, então ele funciona como esperado em operações como filter, map, flatMap ou em uma for-comprehension. Se você não conhece Either, pode ler este tutorial. Mas atenção: esse tutorial é sobre versões do Scala anteriores à 2.12. No Scala 2.12, você pode ignorar RightProjection sem problemas e omitir o .right. Either é uma chamada mônada que cobre um "aspecto computacional", neste caso o tratamento de erros. O uso adequado de mônadas pode resultar em um código bem conciso, mas ainda assim elegante e legível. O uso inadequado pode facilmente resultar no contrário. Assista a este vídeo para saber mais.

Armadilhas comuns que você deve evitar

Há algumas regras práticas para Either:

  1. Se você não precisa, não use. Em vez de
def add1(x: Int): Either[String, Int] = Right(x + 1)

prefira

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

(existe Either.map para aplicar funções simples assim, então você não precisa sobrecarregá-las com Either).

  1. Não faça "unwrap" se você realmente não precisar. Muitas vezes já existem funções prontas para o seu propósito. Indicadores de unwrap prematuro são isLeft/isRight ou pattern matching. Por exemplo, em vez 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
}

prefira

x fold (identity, _ + 1)
  1. Mônadas podem ser usadas dentro de uma for-comprehension FTW. Isso é recomendável quando você quer "compor" várias instâncias de Either. Em vez 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)))

prefira

for {
  x <- xo
  y <- yo
  z <- zo
} yield x + y + z
Editar via GitHub O link abre em uma nova janela ou aba
Scala Exercism

Tudo pronto para começar Contagem de Nucleotídeos?

Crie sua conta no Exercism para aprender e dominar Scala com 95 exercícios e mentoria humana de verdade, tudo de graça.