Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Select an option

  • Save arihantverma/2c96eb1b82f8252e3e9b952ddd5a9cab to your computer and use it in GitHub Desktop.

Select an option

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
Copy Markdown
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
Copy Markdown
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