DEV Community

dev.to staff
dev.to staff

Posted on

Daily Challenge #175 - Complementary DNA

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!

Top comments (18)

Collapse
 
isaacdlyman profile image
Isaac Lyman • Edited

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('');
Enter fullscreen mode Exit fullscreen mode

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

Collapse
 
vanshxrajput profile image
Vansh.c

i am fresher can you tell me what does this ( => )operator do.

Your help is appreciated.

Collapse
 
isaacdlyman profile image
Isaac Lyman

It’s an arrow function (or anonymous function).

function(a, b) {return a + b;}

Is (almost) the same as:

(a, b) => a + b

There are a few differences but most of the time they aren’t anything to worry about. If you care, this is a good overview: levelup.gitconnected.com/7-differe...

Collapse
 
jehielmartinez profile image
Jehiel Martinez • Edited

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
};
```

Enter fullscreen mode Exit fullscreen mode
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
 
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
 
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
 
ryanbeckett profile image
Ryan Beckett • Edited

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
 
klaraneumannova 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
 
klaraneumannova 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 • Edited

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 • Edited
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
 
craigmc08 profile image
Craig McIlwrath • Edited

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
 
kesprit profile image
kesprit

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
 
zoejm profile image
zoe-j-m

Scala

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