{ The Rithm Blog. }

How To Get Good At Coding Challenges March 04, 2020

Learning to code is a lot like learning an instrument. Before you can play a song, you need to learn how to make the notes, then you can put the notes together to make a song. Before attempting whiteboarding challenges it's important to first learn the basic fundamentals. Regardless of the language you are learning you will need to master the following:

 

(Today we will be using javascript)

Fundamental Concepts

  •   variables
  •   strings
  •   numbers
  •   booleans
  •   conditional logic
  •   functions
  •   Iteration
  •   arrays
  •   objects

 

Additional concepts to focus on:

  •   string and number concatenation, we need to understand the difference between 'n + 1' and 'n += 1'
  •   array.push() how we build arrays
  •   string.includes() and array.includes() gives us an easy way to determine if an element exists in a string or array
  •   string.split() allows us to convert a string to an array
  •   array.join() allows us to convert an array to a string
  •   string.slice() and array.slice() allows us to make a copy of a string or an array

 

If any of these are unfamiliar, take some time to dive into each. Once you are comfortable with these fundamental concepts you are ready to start problem-solving.

It can be really difficult to make the leap from learning the fundamentals to actually solving a problem with code. Just like an instrument, practice is important. However, it isn't all about effort, some guidance will accelerate our learning.

The good news is that there are common patterns that we can use to help us with most coding challenges. Since we are still learning these common patterns it is just as important to read code as it is to write our own.

The purpose of this article is to focus on one specific approach for problem-solving. I will refer to this approach as the three-step process. Inside of our solution function we should.

 

Step 1. Initialize the result data type

Step 2. Build the result using iteration

Step 3. Return the result

 

Step 1:

  When reading the problem, start with the output.

  For example, let's say we identify that the return value from our function should be a string.

  Most likely this means we need to initialize an empty string on the first line of our function.


Example 1

  Create a function that will accept a character (c) and a number (n) as an argument.

  The function should return a string of that character, that is the length of n.

    Input: c -> 'a'

              n -> 4

    Output: 'aaaa'

function repeat(c, n) {

  // do step 1 here

}

 

Step 2

  Next we build the result with iteration.

  This is the hardest step. It is where we have to figure out the logic of our problem.

  It starts with determining the pattern of our for loop.

  Then we need to figure out how we will interact with our data type from step one to build our result.

function repeat(c, n) {

  let result = '';

  // do step 2 here

}

 

Step 3

  The final step is the easiest, we simply have to return our result.

  This step is often overlooked, so don't forget it.

  If your function returns undefined you probably forgot to return your result.

 

function repeat(c, n) {

  let result = '';

  for (let i = 0; i < n; i++) {

    result += c;

  }

  // do step 3 here

}

Often the hardest part is getting started, hopeful now you will have a solid starting point.

Infact much of the code needed for these basic challenges starts to feel like boilerplate code after a while.

Once we get the boilerplate code out of the way we often only need to focus on two things.

  1. The pattern of our for loop

  2. Our interaction with the result data type on each iteration

 

In the following section I will give you an example problem for the data types of String, Number, Array and Boolean.

I will also give the boilerplate code for each, including the for loop.

Your task will be to fill in the logic for interacting with the resulting data type on each iteration.


 

Example 2 (String)

  Given a string of characters, return the string in reverse order.

    Input : 'hello'

    Output : 'olleh'

function reverse(string) {

  let result = ‘’;

  for (let i = 0; i < string.length; i++) {

    let cur = string[i]; // *intermediary variable

    // your code here

  }

  return result;

}

 

*An intermediary variable is used to make it easier to access the current element on the current iteration.

 It is good practice to use these, so we will include them in our boilerplate.

 Many times students ignore this step, please trust me, putting in that extra line of code will pay off.

 

Solution

function reverse(string) {

  let result = ‘’;

  for (let i = 0; i < string.length; i++) {

    let cur = string[i];

    result = cur + result;
  }    

  return result;

}

// an alternate approach would be to use a reverse for loop

Example 3 (Number)

  Return the sum of all numbers in an array

    Input: [2, 6, -5, 9]

    Output: 12

function sum(nums) {

  let result = 0;

  for (let i = 0; i < nums.length; i++) {

    let cur = nums[i];

    // your code here

  }    

  return result;

}

 

Solution

function sum(nums) {

  let result = 0;

  for (let i = 0; i < nums.length; i++) {

    let cur = nums[i];

    result += cur;

  }    

  return result;

}

 

Example 4 (Array)

  Given an array of characters, return an array of all the vowels.

    Input: ['c', 'a', 't', 'g', 'o', 'a', 't']

    Output: ['a', 'o', 'a']

function vowels(array) {

  let results = [];

  // you will need something more here see the *hint

  for (let i = 0; i < array.length; i++) {

    let cur = array[i];

    // your code here

  }    

  return result;

}

*hint: how can we determine if a character is a vowel?

 One way is to put all of our vowels in a string and then scan to see if our ‘cur’ character exists in our vowels string.

 Still not sure? check the list of additional concepts at the beginning of this article

 

Solution

function vowels(array) {

  let results = [];

  let vowels = 'aeiou';

  for (let i = 0; i < array.length; i++) {

    let cur = array[i];

    if (vowels.includes(cur)) {

      results.push(cur);

    }

  }    

  return results;

}

Booleans are a little different because they only return true or false, so we don't need to build a results value.

Instead, while we iterate if we find a certain condition we will stop and return either true or false.

If we get to the end of the iteration and the condition was never met we will return the opposing true or false.

 

Example 5 (Boolean)

  Does a string of characters include a number?

    Input : 'hello'

    Output : false

 

    Input : 'h2llo'

    Output : true

function hasNumber(str) {

  // no need to initialize an empty boolean 

  // but we do need a way to determine if something is a number or not

  for (let i = 0; i < str.length; i++) {
  
    let cur = str[i];

    // your code here

  }    

  return false; // if we get to the end of our iteration and our condition was never met, return false

}

Solution

 

function hasNumber(str) {

  let nums = '0123456789';

  for (let i = 0; i < str.length; i++) {

    let cur = str[i];

    if (nums.includes(cur) {

      return true; // if our current element is included in the nums array we can stop and return true

    }

  }

  return false; 

}

 

Bonus (String -> Array -> String)

  Given an string of lowercase words, return a string of all the words capitalized

    Input : 'the dog goes to the park'

    Output : 'The Dog Goes To The Park'

 

function upperCase(str) {

  // We need to iterate over the words in the string not the characters, so we should convert 'str' to an array of words

  let results = [];

  for (let i = 0; i < words.length; i++) {

    let word = words[i];

    // your code here

  }

  return results // This is incomplete, how do we convert the array of words to a string of words?

}

 

Solution

 

function upperCase(str) {

  let words = str.split(' ');

  let results = [];

  for (let i = 0; i < words.length; i++) {

    let word = words[i];

    word = word[0].toUpperCase() + word.slice(1); // uppercase the first character of the current word, copy the rest

    results.push(word);

 }

  return results.join(' ');

}

Hopefully you were able to follow the examples, you can use this as a cheat sheet until it becomes second nature. If there are any concepts from this article that you are not sure about, research them more or find someone who can help you, all of these concepts are absolutely essential.

Now that you have a process to follow, it’s time to start applying it to actual problems. Just like an instrument you have to spend a lot of time practicing.

Rithm School has put together a curated list of 50 problems that would be a good starting point.

I hope this approach helps you get to the next level faster!

Written by Nate

Back to all posts

Get Started with Rithm School