In this series I attempt to complete Free Code Camp as quickly as possible, without cutting too many corners. For an introduction to this series, see Free Code Camp #0: Speedrunning Free Code Camp.

I have now completed all the intermediate algorithm challenges. Functional programming is fun! Some solutions were particularly beautiful, so I will post the code for those.

Roman Numeral Converter

Challenge description on Free Code Camp. Convert numbers to roman numerals.

function partial(digit, pos) {
  var values = {
    1: ["", "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX"],
    2: ["", "X", "XX", "XXX", "XL", "L", "LX", "LXX", "LXXX", "XC"],
    3: ["", "C", "CC", "CCC", "CD", "D", "DC", "DCC", "DCCC", "CM"],
    4: ["", "M", "MM", "MMM"]
  };
  return values[pos][digit];
}

function convertToRoman(num) {
  var pos = 1;
  var digits = num.toString().split("");
  var parts = [];
  while (digits.length > 0) {
    var digit = digits.pop();
    parts.unshift(partial(digit, pos));
    pos++;
  }
 return parts.join("");
}

Where art thou

Challenge description on Free Code Camp. See the description.

function whereAreYou(collection, source) {
  return collection.filter(function(obj) {
    for (var key in source) {
      if (!obj.hasOwnProperty(key) || obj[key] != source[key]) {
        return false;
      }
    }
    return true;
  });
}

Pig Latin

Challenge description on Free Code Camp. Convert word to pig latin.

function translatePigLatin(str) {
  var match = str.match(/^[BCDFGHJKLMNPQRSTVXZWY]+/i);
  if (match) {
    return str.slice(match[0].length) + match[0] + "ay";
  } else {
    return str + "way";
  }
}

DNA Pairing

Challenge description on Free Code Camp. Replaces "G" with ["G","T"] and so on, returning a nested array of base pairs.

function pairElement(str) {
  return str.split("").map(function(base) {
    return {
      G: ["G", "C"],
      C: ["C", "G"],
      A: ["A", "T"],
      T: ["T", "A"]
    }[base];
  });
}

pairElement("GCG");

Missing letters

Challenge description on Free Code Camp. Finds the missing letter in a string. E.g, "abcefg" is missing "d".

function fearNotLetter(str) {
  for (var i = 0; i < str.length-1; i++) {
    if (str.charCodeAt(i) + 1 != str.charCodeAt(i+1)) {
      return String.fromCharCode(str.charCodeAt(i)+1);
    }
  }
  return undefined;
}

Sorted Union

Challenge description on Free Code Camp. Concatenates a list of arrays in order, removing duplicate elements. The leftmost duplicate is kept.

function uniteUnique() {
  return Array.prototype.reduce.call(arguments, function(left, curr) {
    return left.concat(curr.filter(function(val) {
      return left.indexOf(val) == -1;
    }));
  }, []);
}

Convert HTML Entities

Challenge description on Free Code Camp. Replace "&" in a string with &amp; and so on.

function convertHTML(str) {
  return str.replace(/[&<>"']/g, function(char) {
    return {
      "&": "&amp;",
      "<": "&lt;",
      ">": "&gt;",
      '"': "&quot;",
      "'": "&apos;"
    }[char];
  });
}

Spinal Tap Case

Challenge description on Free Code Camp

spinalCase("AllThe-small Things") should return "all-the-small-things"

This was a fun one with a beautiful solution.

function spinalCase(str) {
  return str.replace(/([a-z])([A-Z])/g, function(match) {
    console.log(match);
    return match.charAt(0) + "-" + match.charAt(1).toLowerCase();
  }).replace(/[ _]/g, "-").toLowerCase();
}

Smallest Common Multiple

Challenge description on Free Code Camp. Find the smallest common multiple (LCM) of a range of numbers.

function gcd(a, b) {
  if (b === 0) {
    return a;
  }
  return gcd(b, a%b);
}

function lcm(a, b) {
  return a*b/gcd(a,b);
}

function smallestCommons(arr) {
  var a = Math.min(arr[0], arr[1]);
  var b = Math.max(arr[0], arr[1]);
  var m = 1;
  for (var i=a; i <= b; i++) {
    m = lcm(m, i);
  }
  return m;
}

Drop it

Challenge description on Free Code Camp. While func(head) is true, remove head from list.

function dropElements(arr, func) {
  while (arr.length > 0 && !func(arr[0])) {
    arr.shift();
  }
  return arr;
}

Steamroller

Challenge description on Free Code Camp. Flatten an array.

steamrollArray([1, [], [3, [[4]]]]) should return [1, 3, 4]

function steamrollArray(arr) {
  return arr.reduce(function(left, curr) {
    if (Array.isArray(curr)) {
      return left.concat(steamrollArray(curr));
    } else {
      return left.concat(curr);
    }
  }, []);
}

Binary Agents

Challenge description on Free Code Camp. Convert a "binary" string to ASCII.

binaryAgent("01001001 00100000 01101100 01101111 01110110 01100101 00100000 01000110 01110010 01100101 01100101 01000011 01101111 01100100 01100101 01000011 01100001 01101101 01110000 00100001") should return "I love FreeCodeCamp!".

function binaryAgent(str) {
  return str.split(" ").map(function(byte) {
    return String.fromCharCode(parseInt(byte, 2));
  }).join("");
}