freeCodeCamp Challenge Guide: DNA Pairing

freeCodeCamp Challenge Guide: DNA Pairing
0

Dna Pairing


Problem Explanation

  • You will get a DNA strand sequence and you need to get the pair and return it as a 2D array of the base pairs. Keep in mind that the provided strand should be first always.

  • Another way to interpret the problem: there are four potential characters that exist in DNA: “A”, “T”, “G”, and “C”. “A” and “T” are always paired together, and “G” and “C” are always paired together.
    This problem presents you with an input, e.g. “ATCGA”. Each of those five characters are missing their pairs.
    E.g. the first character “A” needs to be paired with “T” to give the array element [“A”, “T”].
    The second character “T” needs to be paired with “A” to give the array element [“T”, “A”].
    The number of elements in the final output equals the number of characters in the input.

This problem does not involve rearranging the input into different combinations or permutations.

Relevant Links


Hints

Hint 1

  • There are two base case, A-T and C-G, these go both way. You can use regular expression, if statements of anything that you can think of.

Hint 2

  • I would recommend using a switch, as it makes things a lot smoother.

Hint 3

  • The result must be an array of arrays, so keep that in mind when pushing things.

Solutions

Solution 1 (Click to Show/Hide)
function pairElement(str) {
  // Return each strand as an array of two elements, the original and the pair.
  var paired = [];

  // Function to check with strand to pair.
  var search = function(char) {
    switch (char) {
      case "A":
        paired.push(["A", "T"]);
        break;
      case "T":
        paired.push(["T", "A"]);
        break;
      case "C":
        paired.push(["C", "G"]);
        break;
      case "G":
        paired.push(["G", "C"]);
        break;
    }
  };

  // Loops through the input and pair.
  for (var i = 0; i < str.length; i++) {
    search(str[i]);
  }

  return paired;
}

// test here
pairElement("GCG");

Code Explanation

  • The program is very simple, the best solution that I have come up with is to use a switch to catch all the possible four elements. Using if statements would take too much code. You could also use Regular Expressions.
  • Since we have to the original and the pair, I decided to take all four cases instead of the base two.
  • Create an empty array and use the search function to push the right values to the array and return them.

Relevant Links

Solution 2 (Click to Show/Hide)
function pairElement(str) {
  //create object for pair lookup
  var pairs = {
    A: "T",
    T: "A",
    C: "G",
    G: "C"
  };
  //split string into array of characters
  var arr = str.split("");
  //map character to array of character and matching pair
  return arr.map(x => [x, pairs[x]]);
}

//test here
pairElement("GCG");

Code Explanation

  • First define an object with all pair possibilities, this allows us to easily find by key or value.
  • Split str into a characters array so we can use each letter to find its pair.
  • Use the map function to map each character in the array to an array with the character and its matching pair, creating a 2D array.

Relevant Links

9 Likes

Just done this today with my messy code ^^ https://jsfiddle.net/ufs59ngb/

Didnt realise until i found this topic that i dont need two full arrays from WikiPedia example, could just limit it to 4 letters.

Also messy forEach and for loops instead of your flashy .map :((

1 Like

Simple solution with map:

function pairElement(str) {
  
  return str.split("").map(function (el) {
    if (el === "A") {
      return ["A", "T"];
    } else  if (el === "T") {
      return ["T", "A"];
    } else if (el === "C") {
      return ["C", "G"];
    } else {
      return ["G", "C"];
    }
  });
}
10 Likes
function pairElement(str) {
  var pairs = {
    "A": ["A", "T"],
    "T": ["T", "A"],
    "C": ["C", "G"],
    "G": ["G", "C"]
  };
  
  return str.split("").map(function(elem) {
    return pairs[elem];
  });
}
38 Likes

This is the solution I ended up using. Very clean, very to the point.

function pairElement(str) {
  const characters = str.split("");
  const map = {T:'A', A:'T', G:'C', C:'G'};
  const pairs = characters.map(character => {
    return [character, map[character]];
  });
  return pairs;
}

pairElement("GCG");

Using the map array helper method, but with the object of pairs from the above solution makes for a nice clean result I think.

3 Likes

This is how I did it:

function pairElement(str) {
  var newArr = [];
  for (var i = 0; i < str.length; i++){
    if(str[i] === "C"){
      newArr.push((str[i] + "G").split(""));
    } else if (str[i] === "G"){
      newArr.push((str[i] + "C").split(""));
    } else if (str[i] === "T"){
      newArr.push((str[i] + "A").split(""));
    } else if (str[i] == ="A"){
      newArr.push((str[i] + "T").split(""));
    }  
  }
  return newArr;
}

I was wondering how to paste my code nicely here in the forums. I will research how to do it but any suggestions/help/hints would be really appreciated.

[edit] Found It!

2 Likes
function pairElement(str) {
  var dnArray = []; //creates a new array into which we will push new arrays
   for (var i=0;i<str.length;i++){ //iterates through the str
if (str.charAt(i) === "G"){ //if the current str character is a G...
dnArray.push(["G", "C"]); //...push this array into dnArray
} else if (str.charAt(i) === "C"){  //if the current str character is a C...
dnArray.push(["C", "G"]); //push this arra into dnArray
} else if (str.charAt(i) === "A"){ //and so on...
dnArray.push(["A", "T"]);
} else if (str.charAt(i) === "T"){
dnArray.push(["T", "A"]);
}
}
return dnArray; //return the, now populated, dnArray
}

pairElement("ATCGA");

This is my solution with comments. I didn’t find that using if-statements took that much more code than using the switch method.

1 Like

Using map & switch:

function pairElement(str) {  
  return str.split("").map(function (x) {
    switch (x) {
      case "G":
       return ["G","C"];       
      case "C":   
       return ["C","G"];        
      case "T":
       return ["T","A"];       
      case "A":
       return ["A","T"];       
    }    
  });
}
3 Likes

My solution seems to be a bit different than everyone else’s.

function pairElement(str) {
 
  var thePairs = ["A", "C", "G", "T"];
  var myPairs = [];
  
  for (var i = 0, l = str.length; i < l; i++) {
    var thePair = '';
    thePair = thePairs[thePairs.length - thePairs.indexOf(str[i]) - 1];
    myPairs.push([str[i], thePair]);
  }

  return myPairs;
}

Short solution using map, arrow function, and object as key-value pair store:

//jshint esversion:6
function pairElement(str) {
  const mapping = {'A': 'T', 'T': 'A', 'C': 'G', 'G': 'C'};
  return str.split('').map(item => [item, mapping[item]]);
}
7 Likes

I need to get more familiar with map, as well as the arrow notation. Would have saved me a few lines here:


function pairElement(str) {
  var pairs = { "A": "T", "T": "A", "C": "G", "G": "C" };
  var pArr = [];
  for(var i of str) {
    pArr.push([i, pairs[i]]);
  }
  str = pArr;
  return str;
}

My solution(s).

// SOLUTION #1
// function pairElement(str) {

//   function getBasePair(val){
//     switch (val) {
//       case 'A': return 'T';
//       case 'T': return 'A';
//       case 'C': return 'G';
//       case 'G': return 'C';
//     }
//   }
  
//   var output = [];

//   str.split('').map(function(val){
//     var tmp = [];
//     tmp.push(val);
//     tmp.push(getBasePair(val));
//     output.push(tmp);
//   });
   
//   return output;
// }


// SOLUTION #2
function pairElement(str) {

  function getBasePair(val){
    switch (val) {
      case 'A': return ['A','T'];
      case 'T': return ['T','A'];
      case 'C': return ['C','G'];
      case 'G': return ['G','C'];
    }
  }
  
  var output = [];

  str.split('').map(function(val){
    output.push(getBasePair(val));
  });
   
  return output;
}

pairElement("GCG");

Probably not the most efficient solution, but for beginners like myself, it seems like possibly the easiest/simplest since I only used very basic string and array methods as well as one for loop and if statements.

function pairElement(str) {
  //set up a new array, to store the arrays you will be making for the final product
  var newArray = [];
  
  //split the string into an array in order to acces each character of the string easier
  var array = str.split('');
  
  
  //loop through your array
  //create if statements for each possible input
  //use "if statement breakpoints" to push newly paired arrays into NewArray
  for (var i = 0; i < array.length; i++)
    if (array[i] == "G"){
      newArray.push(["G","C"]);
    } else if (array[i] == "C"){
      newArray.push(["C","G"]);
    } else if (array[i] == "A"){
      newArray.push(["A","T"]);
    } else if (array[i] == "T"){
      newArray.push(["T","A"]);
    }
  
  
  //return new paired multi-dimensional array
  return newArray;
}

pairElement("GCG");
function pairElement(str) {
  str = str.split('');
  for (var i=0; i<str.length; i++) {
    str[i] = [str[i]];
    if (str[i][0]==='G') {
      str[i].push('C');
    } else if (str[i][0]==='C') {
      str[i].push('G');
    } else if (str[i][0]==='A') {
      str[i].push('T');
    } else if (str[i][0]==='T') {
      str[i].push('A');
    }
  }
  return str;
}
var basePairs = {
    'A': 'T',
    'T': 'A',
    'G': 'C',
    'C': 'G'
};
function pairElement(str) {
  return str.split('').map(function(key) {
    return [key, basePairs[key]];
  });
}
2 Likes

Noobs Unite!

function pairElement(str) {
  var pair = [];
  
  str = str.split('');
  
  for (var i = 0; i < str.length; i++) {
    if (str[i] === 'A') {
      pair.push(['A', 'T']);
    } else if (str[i] === 'T') {
      pair.push(['T', 'A']);
    } else if (str[i] === 'C') {
      pair.push(['C', 'G']);
    } else if (str[i] === 'G') {
      pair.push(['G', 'C']);
    }
  }
  
  return pair;
}

My solution:

function pairElement(str) {
  
  var split   = str.split(''),
      pair    = split.map(item => {
                  switch(item) {
                    case 'G':
                      return (item + 'C').split('');
                    case 'C':
                      return (item + 'G').split('');
                    case 'A':
                      return (item + 'T').split('');
                    case 'T':
                      return (item + 'A').split('');
                    default:
                      console.log('Not a valid pair');
                    return 'Not a valid pair';
                   }
                 });
 return pair;
}

pairElement("GCG");