Introduction
You work for a bioengineering company that specializes in developing therapeutic solutions.
Your team has just been given a new project to develop a targeted therapy for a rare type of cancer.
It's all very complicated, but the basic idea is that sometimes people's bodies produce too much of a given protein.
That can cause all sorts of havoc.
But if you can create a very specific molecule (called a micro-RNA), it can prevent the protein from being produced.
This technique is called [RNA Interference][rnai].
[rnai]: https://admin.acceleratingscience.com/ask-a-scientist/what-is-rnai/
Instructions
Instructions
Your task is to determine the RNA complement of a given DNA sequence.
Both DNA and RNA strands are a sequence of nucleotides.
The four nucleotides found in DNA are adenine (A), cytosine (C), guanine (G), and thymine (T).
The four nucleotides found in RNA are adenine (A), cytosine (C), guanine (G), and uracil (U).
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 want to look at how the inputs and outputs are structured, take a look at the examples in the test suite.
Dig Deeper
Map function
strings.Map() function
// Package strand is a small library for returning the RNA complement of a DNA strand.
package rnatranscription
import "strings"
// toRNA returns the RNA complement of the input DNA strand.
func ToRNA(dna string) string {
return strings.Map(func(r rune) rune {
switch r {
case 'G':
return 'C'
case 'C':
return 'G'
case 'T':
return 'A'
case 'A':
return 'U'
}
return r
}, dna)
}
This approach passes the input string into the strings Map() function.
The function uses a switch statement to translate the DNA character into an RNA character.
map object
map object
// Package strand is a small library for returning the RNA complement of a DNA strand.
package rnatranscription
var translate = map[rune]byte{
'G': 'C',
'C': 'G',
'T': 'A',
'A': 'U',
}
// ToRNA returns the RNA complement of the input DNA strand.
func ToRNA(dna string) string {
rna := make([]byte, len(dna))
for i, c := range dna {
rna[i] = translate[c]
}
return string(rna)
}
This approach starts be defining a map to translate the DNA rune to an RNA byte.
It does this outside of the ToRNA() function, so it is not created every time ToRNA() is called.
A byte slice is defined using make, which is passed the len() of the input string in bytes.
A string can be seen as bytes or runes.
As of the time of this writing, all of the characters in the input string are single-byte ASCII characters,
so they can be treated as bytes.
The ways to iterate characters are by Unicode runes, or by each letter being a string, or by each letter being a byte.
The runes are from range on a string, the strings from Split(), and the bytes from indexing into the string.
Another way to iterate runes is to convert the string to a rune slice and range on it.
The difference between ranging on a rune slice vs ranging on a string is that the index returned from a string is the position of the next rune in bytes,
not which rune it is.
For example, if the first unicode character is two bytes,
then the second unicode character index will be 2 when ranging on a string and 1 when ranging on a rune slice.
This iterates over the runes of the input string and passes them as the key to the map.
For this exercise we are not concerned with validating the letter and handling an error for an illegal character.
The map returns the matching RNA byte value for the DNA rune, which is placed at the same index in the byte slice.
This iterates over the runes of the input `string` and places them at the same index in the byte slice.
That works in this case, because the input is all single-byte ASCII characters.
But, if the input included any multi-byte Unicode characters, the indexes would not match.
After the iteration of the input string finishes, the function returns the byte slice converted to a string.
switch statement
switch statement
// Package strand is a small library for returning the RNA complement of a DNA strand.
package rnatranscription
func nucComp(nuc byte) byte {
switch nuc {
case 'G':
return 'C'
case 'C':
return 'G'
case 'T':
return 'A'
case 'A':
return 'U'
default:
panic(string(nuc) + " is an invalid nucleotide")
}
}
// toRNA returns the RNA complement of the input DNA strand.
func ToRNA(dna string) string {
length := len(dna)
var output = make([]byte, length)
for i := range length {
output[i] = (nucComp(dna[i]))
}
return string(output)
}
This approach starts be defining a helper function which contains a switch statement to map the DNA byte to an RNA byte.
The ToRNA() function begins by getting the len() of the input string in bytes.
A string can be seen as bytes or runes.
As of the time of this writing, all of the characters in the input string are single-byte ASCII characters,
so they can be treated as bytes.
A byte slice is defined using make, which is passed the length of the input string in bytes.
The ways to iterate characters are by Unicode runes, or by each letter being a string, or by each letter being a byte.
The runes are from range on a string, the strings from Split(), and the bytes from indexing into the string.
Another way to iterate runes is to convert the string to a rune slice and range on it.
The difference between ranging on a rune slice vs ranging on a string is that the index returned from a string is the position of the next rune in bytes,
not which rune it is.
For example, if the first unicode character is two bytes,
then the second unicode character index will be 2 when ranging on a string and 1 when ranging on a rune slice.
As of the time of this writing we can iterate bytes, since all of the characters are ASCII.
This iterates over the bytes of the input string and passes them as the argument to the helper function.
The helper function returns the matching RNA byte for the DNA byte, which is placed at the same index in the byte slice.
Although the values used in the switch are rune literals, they are treated as bytes, since their values are within the byte range,
and the type of the argument and return type are byte.
After the iteration of the input string finishes, the function returns the byte slice converted to a string.
Source: Exercism go/rna-transcription