Hamming

Hamming

Fácil

Introdução

Seu corpo é formado por células que contêm DNA. Essas células se desgastam com frequência e precisam ser substituídas, o que elas fazem se dividindo em células-filhas. Na verdade, o corpo humano médio passa por cerca de 10 quatrilhões de divisões celulares ao longo da vida!

Quando as células se dividem, o DNA delas também se replica. Às vezes, durante esse processo, acontecem erros e pequenos trechos de DNA são codificados com a informação incorreta. Se compararmos duas fitas de DNA e contarmos as diferenças entre elas, podemos ver quantos erros aconteceram. Isso é conhecido como "distância de Hamming".

A distância de Hamming é útil em muitas áreas da ciência, não só na biologia, então é um termo legal de se conhecer :)

Instruções

Calcule a distância de Hamming entre duas fitas de DNA.

Lemos o DNA usando as letras C, A, G e T. Duas fitas podem ser assim:

GAGCCTACTAACGGGAT
CATCGTAATGACGGCCT
^ ^ ^  ^ ^    ^^

Elas têm 7 diferenças e, portanto, a distância de Hamming é 7.

Notas de implementação

A distância de Hamming só está definida para sequências de mesmo comprimento, então uma tentativa de calculá-la entre sequências de comprimentos diferentes não deve funcionar.

Option é usado para indicar uma computação que pode não ter um resultado útil (por exemplo, devido a um erro ou a uma entrada inválida). Se você não conhece Option, pode ler este tutorial. Option é o que se chama de mônada, que cobre um "aspecto computacional", neste caso a possível ausência de um valor. O uso correto de mônadas pode resultar em um código bem conciso, mas ainda assim elegante e legível. O uso incorreto pode facilmente resultar no contrário. Assista a este vídeo para saber mais.

Armadilhas comuns que você deve evitar

Existem algumas regras práticas para Option:

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

é melhor ter

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

(existe o Option.map para aplicar funções simples como essas, então você não precisa poluí-las com Option). 2. Não faça "unwrap" se você realmente não precisar. Muitas vezes existem funções prontas para o seu objetivo. Indicadores de unwrap prematuro são isDefined/isEmpty ou pattern matching. 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
  1. Mônadas podem ser usadas dentro de uma for-comprehension. Isso é demais. Isso é recomendável quando você quer "compor" várias instâncias de Option. Em vez 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)))

é melhor ter

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 Hamming?

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