loading...

Daily Challenge #175 - Complementary DNA

thepracticaldev profile image dev.to staff ・1 min read

Setup

Deoxyribonucleic acid (DNA) is a chemical found in the nucleus of cells and carries the "instructions" for the development and functioning of living organisms.

In DNA strings, symbols "A" and "T" and "C" and "G" are complements of each other. Implement a function DNA_strand to match the given side of DNA with its complementary side.

Examples

DNA_strand("ATTGC") # return TAACG
DNA_strand("GTTAAC") # return CAATTG

Tests

DNA_strand("AAAA")
DNA_strand("CTACC")
DNA_strand("GTAT")

Good luck!


This challenge comes from JustyFY on CodeWars. Thank you to CodeWars, who has licensed redistribution of this challenge under the 2-Clause BSD License!

Want to propose a challenge idea for a future post? Email yo+challenge@dev.to with your suggestions!

Discussion

pic
Editor guide
Collapse
cipharius profile image
Valts Liepiņš

Ruby keeps on pleasantly surprising me:

def DNA_strand str
    str.tr 'ATCG', 'TAGC'
end
Collapse
cipharius profile image
Valts Liepiņš

Seems like Lua also has a neat solution:

function DNA_strand(str)
    return (str:gsub('.', {A='T',T='A',C='G',G='C'}))
end
Collapse
isaacdlyman profile image
Isaac Lyman

This sounds like a one-liner in JS. Let's see...

const DNA_strand = str => str.split('').map(l => l === 'A' ? 'T' : l === 'T' ? 'A' : l === 'G' ? 'C' : l === 'C' ? 'G' : '').join('');

As a bonus, any non-DNA letters will be ignored.

Collapse
avalander profile image
Avalander

Another javascript solution

const complementaryKeys = (prev, [ a, b ]) =>
  Object.assign(prev, {
    [a]: b,
    [b]: a,
  })

const pair = (...entries) => {
  const pairs = entries.reduce(complementaryKeys, {})
  return x => pairs[x] || ''
}

const dnaPairs = pair(
  [ 'A', 'T' ],
  [ 'C', 'G' ]
)

const mapStr = fn => str =>
  str.split('')
    .map(fn)
    .join('')

const dnaStrand = mapStr(dnaPairs)
Collapse
ruanengelbrecht profile image
Ruan Engelbrecht

JavaScript:

const mapping = {
  A: 'T',
  T: 'A',
  C: 'G',
  G: 'C'
};

const DNA_strand = seq =>
  seq
    .split('')
    .map(x => mapping[x])
    .join('');
Collapse
jehielmartinez profile image
Jehiel Martinez

JS:

function DNA_strand (str) {
    let result = '';
    for(i=0; i<str.length; i++){    
        switch (str[i]) {
            case 'A':
                result = result + 'T';
                break;
            case 'T':
                result = result + 'A';
                break;
            case 'C':
                result = result + 'G';
                break;
            case 'G':
                result = result + 'C';
                break;
            default:
                return 'Your DNA is not from this planet';
        }
    }
    return result
};
Collapse
craigmc08 profile image
Craig McIlwrath

Haskell:

complement :: Char -> Either String Char
complement 'A' = Right 'T'
complement 'T' = Right 'A' 
complement 'C' = Right 'G' 
complement 'G' = Right 'C' 
complement c = Left $ "invalid nucleic acid " ++ [c]

dnaStrand :: String -> Either String String 
dnaStrand = sequence . map complement

Returns a Left value if there is a character other than AGTC

Collapse
kespri profile image
kespri

Swift solution :

func dnaStand(dna: String) -> String {
    let dnaMatching: [Character:Character] = ["A":"T","T":"A","C":"G","G":"C"]
    return dna.reduce(into: "") { $0.append(dnaMatching[$1] ?? "" as! Character) }
}


dnaStand(dna:"ATTGC")
dnaStand(dna:"GTTAAC")
dnaStand(dna:"AAAA")
dnaStand(dna:"CTACC")
dnaStand(dna:"GTAT")
Collapse
ryanbeckett profile image
Ryan Beckett

Swift:


func DNA_strand( _ dna: String) -> String {
  let swapTable = [("A", "T"), ("T", "A"), ("C", "G"), ("G", "C")]

  return dna.map { char in
    swapTable.map { (key, value) in
      String(char) == key ? value as String : ""
    }.joined()
  }.joined()

}

I'm trying to complete these everyday for 30 days (hopefully more) - feedback more that welcome here please, thank you! Github PR

Collapse
dimitrimarion profile image
Dimitri Marion

Javascript using Map:

const dnaMatch = new Map();
dnaMatch.set("A", "T");
dnaMatch.set("T", "A");
dnaMatch.set("C", "G");
dnaMatch.set("G", "C");

const DNA_strand = (dna) => {
    const matchedDNA = Array.prototype.map.call(dna, sym => dnaMatch.get(sym));

    return matchedDNA.join('');
};
Collapse
trinactka profile image
Klára Neumannová

PHP:

function dnaStrand(string $dnaString)
{
    $symbols = str_split($dnaString);

    $complementaryString = '';
    foreach ($symbols as $symbol) {
        switch ($symbol) {
            case 'A':
                $complementaryString .= 'T';
                break;
            case 'T':
                $complementaryString .= 'A';
                break;  
            case 'C':
                $complementaryString .= 'G';
                break;
            case 'G':
                $complementaryString .= 'C';
                break;
            default:
                return "Is '" . $symbol ."' really in your DNA?";
        }
    }

    return $complementaryString;
}

There is always a better solution, suggest one please - I'm here to learn more .)

Collapse
trinactka profile image
Klára Neumannová

OK, I found another one for PHP (7.2 and higher):

function dnaStrand(string $dnaString)
{
    $translateTable = ['A' => 'T', 'T' => 'A', 'C' => 'G', 'G' => 'C'];

    $symbols = str_split($dnaString);

    $complementaryString = '';
    foreach ($symbols as $symbol) {
        $complementaryString .= $translateTable[$symbol] ?? '';
    }

    return $complementaryString;
}
Collapse
kerldev profile image
Kyle Jones

In Python:

def DNA_strand(strand):
    '''
    Returns the complementary strand of DNA for a given strand.
    '''
    complementary_strand = ""
    for symbol in strand:
        if symbol == 'A':
            complementary_strand += 'T'
            continue
        if symbol == 'T':
            complementary_strand += 'A'
            continue
        if symbol == 'C':
            complementary_strand += 'G'
            continue
        if symbol == 'G':
            complementary_strand += 'C'
            continue
    return complementary_strand


print(DNA_strand("ATTGC"))
print(DNA_strand("GTTAAC"))
Collapse
dbarwikowski profile image
Daniel Barwikowski

C#

private static string DNA_strand(string dna)
{
    var sb = new StringBuilder();
    var bytes = Encoding.ASCII.GetBytes(dna);
    foreach (var b in bytes)
    {
        if ((b & 0b0000_0010) == 0)
        {
            sb.Append((char) (b ^ 0b0001_0101));
        }
        else
        {
            sb.Append((char) (b ^ 0b0000_0100));
        }
    }

    return sb.ToString();
}
Collapse
dbarwikowski profile image
Daniel Barwikowski
A   100 0001
T   101 0100

C   100 0011
G   100 0111

---- -|-- - this bit always changes

---| ---| - this bits only changes when ---- --|- is set to 0

Collapse
zoejm profile image
zoe-j-m

Scala

def DNA_strand(dna : String) : String = (dna flatMap ("ATCG" zip "TAGC").toMap.get ).mkString