RNA Transcription Problem - Exercism Elixir Solution & Tutorial


Percy Grunwald's Profile Picture

Written by Percy Grunwald

— Last Updated February 22, 2019

This was a fairly easy problem to solve compared to the previous one – bracket push, which took me 2 hours to solve after going down the wrong path and not realizing the correct approach.

Live solution video

This is my daily live stream video solution to this problem.

Explanation of the solution

Map of DNA nucleotide charcodes to RNA nucleotide charcodes

The bulk of the heavy lifting in this solution comes from the map of DNA nucleotide charcodes to RNA nucleotide charcodes:

@dna_nucleotide_to_rna_nucleotide_map %{
  # `G` -> `C`
  71 => 67,

  # `C` -> `G`
  67 => 71,

  # `T` -> `A`
  84 => 65,

  # `A` -> `U`
  65 => 85
}

These mappings came directly from the README:

Given a DNA strand, its transcribed RNA strand is formed by replacing
each nucleotide with its complement:

* `G` -> `C`
* `C` -> `G`
* `T` -> `A`
* `A` -> `U`

If you’re curious how to get the charcodes, you can use IO.inspect/2 with the charlists: false option:

iex> IO.inspect('GCTAU', charlists: false)
[71, 67, 84, 65, 85]
'GCTAU'

Function to map a DNA nucleotide charlist to RNA nucleotide charlist

The function to map the charlist of DNA nucleotides to RNA nucleotides is really simple, it’s just an Enum.map/2 over the charcodes in the DNA nucleotide charlist:

@spec to_rna([char]) :: [char]
  def to_rna(dna) do
    dna
    |> Enum.map(&get_rna_for_dna/1)
  end

  defp get_rna_for_dna(dna_nucleotide) do
    @dna_nucleotide_to_rna_nucleotide_map[dna_nucleotide]
  end

Enum.map/2 calls the get_rna_for_dna/1 function for each charcode. get_rna_for_dna/1 simply does a lookup in @dna_nucleotide_to_rna_nucleotide_map, which we defined earlier.

For example, if we call get_rna_for_dna(71) it will return 67 (71 being the charcode for G and 67 being the charcode forC`).

Full solution in text form

Here’s the full solution in text form, in case you want to look over the final product:

defmodule RNATranscription do
  @dna_nucleotide_to_rna_nucleotide_map %{
    # `G` -> `C`
    71 => 67,

    # `C` -> `G`
    67 => 71,

    # `T` -> `A`
    84 => 65,

    # `A` -> `U`
    65 => 85
  }

  @doc """
  Transcribes a character list representing DNA nucleotides to RNA

  ## Examples

  iex> RNATranscription.to_rna('ACTG')
  'UGAC'
  """
  @spec to_rna([char]) :: [char]
  def to_rna(dna) do
    dna
    |> Enum.map(&get_rna_for_dna/1)
  end

  defp get_rna_for_dna(dna_nucleotide) do
    @dna_nucleotide_to_rna_nucleotide_map[dna_nucleotide]
  end
end

Comments