Треки
/
Scala
Scala
/
Вправи
/
Підрахунок нуклеотидів
Підрахунок нуклеотидів

Підрахунок нуклеотидів

Середня

Вказівки

Кожен із нас успадковує від своїх біологічних батьків набір хімічних вказівок, відомий як ДНК, що впливає на те, як побудоване наше тіло. Усе відоме життя залежить від ДНК!

Примітка: щоб виконати цю вправу, не потрібно розуміти нічого про нуклеотиди чи ДНК.

ДНК - це довгий ланцюг інших хімічних речовин, найважливіші з яких - чотири нуклеотиди: аденін, цитозин, гуанін і тимін. Один ланцюг ДНК може містити мільярди цих чотирьох нуклеотидів, і порядок, у якому вони розташовані, має значення! Порядок цих нуклеотидів у певній ділянці ДНК ми називаємо «послідовністю ДНК».

Ми подаємо послідовність ДНК як упорядкований набір із цих чотирьох нуклеотидів, а поширений спосіб зробити це - записати рядок тексту (англ. string), наприклад «ATTACG» для послідовності ДНК із 6 нуклеотидів. «A» означає аденін, «C» - цитозин, «G» - гуанін, «T» - тимін.

Дано рядок тексту, що задає послідовність ДНК: порахуйте, скільки є кожного з нуклеотидів. Якщо рядок тексту містить символи, які не є A, C, G або T, тоді він неправильний, і слід повідомити про помилку.

Наприклад:

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

Поширене використання Either - позначати обчислення, яке може завершитися помилкою (якщо сама помилка не має значення, то простіший тип Option може виявитися кращим вибором). Якщо помилки немає, результатом зазвичай буває Right (мнемоніка: «правильне» значення), а помилку позначає Left, наприклад Left[String] із повідомленням про помилку. Варто зауважити, що в Scala 2.12 Either типово зміщений праворуч, тож він працює так, як очікується, для таких операцій, як filter, map, flatMap, або в конструкції for. Якщо ми ще не знайомі з Either, можна прочитати цей посібник. Але варто памʼятати, що цей посібник стосується версій Scala до 2.12. У Scala 2.12 можна сміливо не зважати на RightProjection і не писати .right. Either - це так звана монада, яка охоплює «обчислювальний аспект», а саме обробку помилок. Правильне використання монад дає змогу писати дуже лаконічний, але елегантний і зрозумілий код. Неправильне використання легко призводить до протилежного. Щоб дізнатися більше, можна подивитися це відео.

Поширені пастки, яких варто уникати

Для Either є кілька орієнтовних правил:

  1. Якщо воно не потрібне, не варто його використовувати. Замість
def add1(x: Int): Either[String, Int] = Right(x + 1)

краще мати

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

(є Either.map, щоб застосовувати такі прості функції, тож не потрібно захаращувати їх Either). 2. Не варто «розгортати» значення, якщо це справді не потрібно. Часто для цього вже є вбудовані функції. Ознаки передчасного розгортання - це isLeft/isRight або зіставлення зі зразком. Наприклад, замість

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
}

краще мати

x fold (identity, _ + 1)
  1. Монади можна використовувати всередині конструкції for. І це чудово. Це радимо, коли потрібно «скомпонувати» кілька примірників Either. Замість
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)))

краще мати

for {
  x <- xo
  y <- yo
  z <- zo
} yield x + y + z
Редагувати через GitHub Посилання відкривається в новому вікні або вкладці
Scala Exercism

Час розпочати Підрахунок нуклеотидів?

Зареєструйтеся на Exercism, щоб вивчати й опановувати Scala, а також 95 вправ та справжнє наставництво від людей, і все це безкоштовно.