Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save arihantverma/2c96eb1b82f8252e3e9b952ddd5a9cab to your computer and use it in GitHub Desktop.
Save arihantverma/2c96eb1b82f8252e3e9b952ddd5a9cab to your computer and use it in GitHub Desktop.
/* Problem Name is &&& Run Length Encoding &&& PLEASE DO NOT REMOVE THIS LINE. */
/**
* Instructions to candidate.
* 1) Run this code in the REPL to observe its behaviour.
* 2) Consider adding some additional tests in doTestsPass().
* 3) Implement rle() correctly.
* 4) If time permits, try to improve your implementation.
*/
/**
* rle ( testString )
*
* Implement a run length encoding function.
*
* For a string input the function returns output encoded as follows:
*
* "a" -> "a1"
* "aa" -> "a2"
* "aabbb" -> "a2b3"
* "aabbbaa" -> "a2b3a2"
* "" -> ""
*
*/
const _ = require("underscore");
const rle = ( input ) => {
// write your code here
}
/**
* boolean doTestsPass()
* Returns true if all the tests pass. Otherwise returns false.
*/
/**
* Returns true if all tests pass; otherwise, returns false.
*/
const doTestsPass = () => {
const VALID_COMBOS = {"aaa": "a3", "aaabbc":"a3b2c1"};
let testPassed = true;
_.forEach(VALID_COMBOS, function(value, key) {
console.log(key, rle(key));
if (value !== rle(key)) {
testPassed = false;
}
});
return testPassed;
}
/**
* Main execution entry.
*/
if(doTestsPass())
{
console.log("All tests pass!");
}
else
{
console.log("There are test failures.");
}
@arihantverma
Copy link
Author

arihantverma commented Mar 17, 2021

Solution

repl link for the code below

/* Problem Name is &&& Run Length Encoding &&& PLEASE DO NOT REMOVE THIS LINE. */

/**
 * Instructions to candidate.
 *  1) Run this code in the REPL to observe its behaviour.
 *  2) Consider adding some additional tests in doTestsPass().
 *  3) Implement rle() correctly.
 *  4) If time permits, try to improve your implementation.
 */


/**
 * rle ( testString )
 *
 * Implement a run length encoding function.
 *
 * For a string input the function returns output encoded as follows:
 *
 * "a"     -> "a1"
 * "aa"    -> "a2"
 * "aabbb" -> "a2b3"
 * "aabbbaa" -> "a2b3a2"
 * ""      -> ""
 *
 */

const _ = require("underscore");

/**
 * the given problem is a windowing problem,
 * for knowing what is windowing, go through this
 * youtube video: https://www.youtube.com/watch?v=jSvoE-_Yhs4
 * the solution the video is tiny miny more difficult than
 * this one
 */
const rle = ( input ) => {

  // trim the input for sanity
  const trimmedInput = input.trim();

  // if empty string return empty string;
  if (!trimmedInput.length) {
    return '';
  }

  // to traverse the input string, convert it into an array
  const inputArr = input.split('');

  /**
   * for an example string 'aaabbc'
   * 
   * We start iterating with the first 'a' and we also
   * keep a track of what the next character is. So
   * for the first iteration (when `traversedLength` is 0)
   * our first char is 'a' ( first character overall) and the 
   * next char is also 'a' (second character overall) ,
   * since they are same, we increment the count
   * 
   * After this we increment our iterator count
   * `traversedLength` by one, then we have our current char
   * as 'a' ( which is the second character overall), and
   * its next char is also 'a' ( third character overall )
   * since they are both same, we increase the count again.
   * 
   * At this point of time our count is 3.
   * 
   * We increment our iterator count by one again. So `traversedLength` is 3. Our current char is 'a' ( third 
   * character overall), and *now* our next char is 'b'.
   * Since they are different, we push the value 'a' and its
   * count '3' in the array 'retVal'. After doing that we set
   * our count to 1 again, and start all over.
   * 
   * So basically we have a window of size 2, that we are
   * sliding by one each time we are increasing our iterator by
   * one. Some edge cases are handled, comments are written.
   * 
   * If you get any other edge case in your mind, or find something
   * wrong with this implementation kindly reply on this gist :)
   */


  let retVal = [];
  let count = 1;

  let traversedLength = 0;
  // let charInDiscussion = arr[traversedLength];

  let currentChar = inputArr[traversedLength];
  let nextChar = inputArr[traversedLength + 1];

  
  while (traversedLength < input.length) {   

    if (currentChar === nextChar) {
      count++
    } else {
      if (nextChar !== undefined) {
        //https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/apply#using_apply_to_append_an_array_to_another
        retVal.push.apply(retVal, [currentChar, count]);
        count = 1;
      } else {
        // last iteration
        retVal.push.apply(retVal, [currentChar, count]);
      }
    }

    if (inputArr.length === 1) {
      count++
    }

    traversedLength++;

    currentChar = inputArr[traversedLength];
    nextChar = inputArr[traversedLength + 1];

  } 
  

  return retVal.join('')
  
}

/**
 * boolean doTestsPass()
 * Returns true if all the tests pass. Otherwise returns false.
 */
/**
 * Returns true if all tests pass; otherwise, returns false.
 */
const doTestsPass = () => {

  const VALID_COMBOS = {"aaa": "a3", "aaabbc":"a3b2c1"};

  let testPassed = true;

  _.forEach(VALID_COMBOS, function(value, key) {
  console.log(key, rle(key));
  if (value !== rle(key)) {
    testPassed = false;
  }
  });

  return testPassed;
}

/**
 * Main execution entry.
 */
if(doTestsPass())
{
  console.log("All tests pass!");
}
else
{
  console.log("There are test failures.");
}

@arihantverma
Copy link
Author

arihantverma commented Mar 17, 2021

If you find any edge case, unhandled use case, or find something wrong in this implementation, kindly reply here with it :) And I'll update the solution.

If you find this solution helpful, kindly star the gist :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment