O teu corpo é feito de células que contêm DNA. Essas células desgastam-se regularmente e precisam de ser substituídas, o que conseguem ao dividir-se em células-filhas. De facto, o corpo humano médio passa por cerca de dez mil biliões de divisões celulares ao longo da vida!
Quando as células se dividem, o seu DNA também se replica. Por vezes, durante este processo, acontecem erros e pequenas partes de DNA ficam codificadas com a informação incorreta. Se compararmos duas cadeias de DNA e contarmos as diferenças entre elas, conseguimos ver quantos erros ocorreram. É a isto que se chama a "distância de Hamming".
A distância de Hamming é útil em muitas áreas da ciência, não só na biologia, por isso é uma expressão que vale a pena conheceres :)
Calcula a distância de Hamming entre duas cadeias de ADN.
Lemos o ADN através das letras C, A, G e T. Duas cadeias podem ter este aspeto:
GAGCCTACTAACGGGAT
CATCGTAATGACGGCCT
^ ^ ^ ^ ^ ^^
Têm 7 diferenças e, por isso, a distância de Hamming é 7.
A distância de Hamming só está definida para sequências de igual comprimento. Por isso, não deve ser possível calculá-la entre sequências com comprimentos diferentes.
O Option usa-se para indicar um cálculo que pode não ter um resultado útil
(por exemplo, por causa de um erro ou de dados inválidos).
Se não estás familiarizado com o Option, podes ler este tutorial.
O Option é uma chamada mónada que abrange um «aspeto computacional», neste caso a possível ausência de um valor.
O uso correto das mónadas pode resultar em código muito conciso, mas ainda assim elegante
e legível. O uso incorreto pode facilmente resultar no contrário.
Vê este vídeo para saberes mais.
Há algumas regras básicas para o Option:
def add1(x: Int): Option[Int] = Some(x + 1)
é melhor ter
def add1(x: Int): Int = x + 1
(há o Option.map para aplicar funções simples como estas,
por isso não precisas de as sobrecarregar com o Option).
2. Não faças «unwrap» se não precisares mesmo.
Muitas vezes há funções incorporadas para o que queres. Indícios de
«unwrap» prematuro são isDefined/isEmpty ou a correspondência de padrões. Em vez de
val x: Option[Int] = ...
if (x.isDefined) x.get + 1 else 0
// or
x match {
case Some(n) => n + 1
case None => 0
}
é melhor ter
x map (_ + 1) getOrElse 0
Option. Em vez deval xo: Option[Int] = ...
val yo: Option[Int] = ...
val zo: Option[Int] = ...
xo.flatMap(x =>
yo.flatMap(y =>
zo.map(z =>
x + y + z)))
é melhor ter
for {
x <- xo
y <- yo
z <- zo
} yield x + y + z
Inscreve-te no Exercism para aprenderes e dominares Scala com 95 exercícios, e mentoria humana real, tudo grátis.