69 lines
2.0 KiB
Elixir
69 lines
2.0 KiB
Elixir
defmodule ProteinTranslation do
|
|
@doc """
|
|
Given an RNA string, return a list of proteins specified by codons, in order.
|
|
"""
|
|
@spec of_rna(String.t()) :: {:ok, list(String.t())} | {:error, String.t()}
|
|
def of_rna(""), do: {:ok, []}
|
|
|
|
def of_rna(rna) do
|
|
rna
|
|
|> String.graphemes()
|
|
|> Enum.chunk_every(3)
|
|
|> Enum.map(&Enum.join/1)
|
|
|> Enum.reduce_while([], &reducer/2)
|
|
|> case do
|
|
proteines when is_list(proteines) -> {:ok, Enum.reverse(proteines)}
|
|
{:error, error} -> {:error, error}
|
|
end
|
|
end
|
|
|
|
defp reducer(codon, proteines) do
|
|
case of_codon(codon) do
|
|
{:error, _error} -> {:halt, {:error, "invalid RNA"}}
|
|
{:ok, "STOP"} -> {:halt, proteines}
|
|
{:ok, proteine} -> {:cont, [proteine | proteines]}
|
|
end
|
|
end
|
|
|
|
@doc """
|
|
Given a codon, return the corresponding protein
|
|
|
|
UGU -> Cysteine
|
|
UGC -> Cysteine
|
|
UUA -> Leucine
|
|
UUG -> Leucine
|
|
AUG -> Methionine
|
|
UUU -> Phenylalanine
|
|
UUC -> Phenylalanine
|
|
UCU -> Serine
|
|
UCC -> Serine
|
|
UCA -> Serine
|
|
UCG -> Serine
|
|
UGG -> Tryptophan
|
|
UAU -> Tyrosine
|
|
UAC -> Tyrosine
|
|
UAA -> STOP
|
|
UAG -> STOP
|
|
UGA -> STOP
|
|
"""
|
|
@cysteines ~w(UGU UGC)
|
|
@leucines ~w(UUA UUG)
|
|
@tyrosines ~w(UAU UAC)
|
|
@phenylalanines ~w(UUU UUC)
|
|
@serines ~w(UCU UCC UCA UCG)
|
|
@methionines ~w(AUG)
|
|
@tryptophans ~w(UGG)
|
|
@stops ~w(UAA UAG UGA)
|
|
|
|
@spec of_codon(String.t()) :: {:ok, String.t()} | {:error, String.t()}
|
|
def of_codon(cysteine) when cysteine in @cysteines, do: {:ok, "Cysteine"}
|
|
def of_codon(leucine) when leucine in @leucines, do: {:ok, "Leucine"}
|
|
def of_codon(tyrosine) when tyrosine in @tyrosines, do: {:ok, "Tyrosine"}
|
|
def of_codon(phenylalanine) when phenylalanine in @phenylalanines, do: {:ok, "Phenylalanine"}
|
|
def of_codon(serine) when serine in @serines, do: {:ok, "Serine"}
|
|
def of_codon(methionine) when methionine in @methionines, do: {:ok, "Methionine"}
|
|
def of_codon(tryptophan) when tryptophan in @tryptophans, do: {:ok, "Tryptophan"}
|
|
def of_codon(stop) when stop in @stops, do: {:ok, "STOP"}
|
|
def of_codon(_invalid), do: {:error, "invalid codon"}
|
|
end
|