トラック
/
Scala
Scala
/
演習
/
ハミング
ハミング

ハミング

初級

はじめに

体は、DNAを含む細胞でできています。 そうした細胞は定期的に古くなり、入れ替わる必要があります。それが、娘細胞に分裂することで行われます。 実際、平均的な人間の体では、一生の間に約1京回もの細胞分裂が起こっています!

細胞が分裂するとき、DNAも複製されます。 この過程でときどき間違いが起こり、DNAの一片に誤った情報が書き込まれてしまうことがあります。 2本のDNAの鎖を比べて、違いの数を数えれば、いくつの間違いが起きたのかがわかります。 これが「ハミング距離」と呼ばれるものです。

ハミング距離は生物学だけでなく、科学の多くの分野で役立つので、覚えておくとよい言葉です :)

説明

2つのDNA鎖の間のハミング距離を計算します。

DNAは、C、A、G、Tという文字で表されます。 2つの鎖は、たとえば次のようになります。

GAGCCTACTAACGGGAT
CATCGTAATGACGGCCT
^ ^ ^  ^ ^    ^^

違いは7か所あるので、ハミング距離は7です。

実装上の注意

ハミング距離は、同じ長さの並びに対してのみ定義されています。そのため、長さの異なる並びの間で計算しようとしても、うまくいきません。

Optionは、役に立つ結果が得られないかもしれない計算(たとえばエラーや不正な入力が原因の場合)を表すために使います。

Optionに馴染みがない場合は、このチュートリアルを読んでみてください。

Optionは、いわゆるMonadであり、「計算の側面」、この場合は値が存在しない可能性を扱います。

モナドを適切に使うと、とても簡潔でありながらエレガントで読みやすいコードになります。使い方を誤ると、あっという間に正反対の結果になってしまいます。詳しく知りたい場合はこの動画を見てみましょう。

避けておきたいよくある落とし穴

Optionには、いくつかの経験則があります。

  1. 必要ないなら使わない。次のように書くのではなく
def add1(x: Int): Option[Int] = Some(x + 1)

次のようにしましょう

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

(このような単純な関数を適用するためのOption.mapがあるので、わざわざOptionでコードを煩雑にする必要はありません。)

  1. 本当に必要でないなら「アンラップ」しない。多くの場合、目的に合った組み込み関数があります。早まったアンラップの兆候は、isDefined/isEmptyやパターンマッチです。次のように書くのではなく
val x: Option[Int] = ...

if (x.isDefined) x.get + 1 else 0
// or
x match {
  case Some(n) => n + 1
  case None => 0
}

次のようにしましょう

x map (_ + 1) getOrElse 0
  1. モナドは、for内包表記の中で使うのが一番です。これは、複数のOptionインスタンスを「合成」したいときに適しています。次のように書くのではなく
val xo: Option[Int] = ...
val yo: Option[Int] = ...
val zo: Option[Int] = ...

xo.flatMap(x =>
  yo.flatMap(y =>
    zo.map(z =>
	  x + y + z)))

次のようにしましょう

for {
  x <- xo
  y <- yo
  z <- zo
} yield x + y + z
GitHubで編集する リンクは新しいウィンドウまたはタブで開きます
Scala Exercism

ハミングを始める準備はできましたか?

Exercismに登録すれば、95個の演習、そして本物の人間によるメンタリングとともに、Scalaを学んでマスターできます。すべて無料です。