Skip to content Skip to footer

Example CodeSignal questions for software engineering interviews

Curious about the types of questions we design at CodeSignal? In this blog post, we’ll walk through a few examples. Ranging from simple to very challenging, they represent the kinds of questions that we design as part of our General Coding Framework for evaluating the core programming skills of early-career talent. We’ll explain what these questions assess for and describe a sample good solution for each.

Question 1: Array Manipulation

Given an array a, your task is to output an array b of the same length by applying the following transformation: 
– For each i from 0 to a.length - 1 inclusive, b[i] = a[i - 1] + a[i] + a[i + 1]
– If an element in the sum a[i - 1] + a[i] + a[i + 1] does not exist, use 0 in its place
– For instance, b[0] = 0 + a[0] + a[1]

Example

For a = [4, 0, 1, -2, 3]
b[0] = 0 + a[0] + a[1] = 0 + 4 + 0 = 4
b[1] = a[0] + a[1] + a[2] = 4 + 0 + 1 = 5
b[2] = a[1] + a[2] + a[3] = 0 + 1 + (-2) = -1
b[3] = a[2] + a[3] + a[4] = 1 + (-2) + 3 = 2
b[4] = a[3] + a[4] + 0 = (-2) + 3 + 0 = 1

So, the output should be solution(a) = [4, 5, -1, 2, 1].

Taking a look at this question, you can see that it covers a basic array traversal and manipulation. The candidate simply needs to return the sum of each value in a, plus its right and left neighbors. 

At the same time, the question asks candidates to take into account corner cases with their implementation, which is an important fundamental skill. They need to correctly handle the first and last elements of the array. 

Question 1: Solution

def solution(a):
   n = len(a)
   b = [0 for _ in range(n)]
   for i in range(n):
       b[i] = a[i]
       if i > 0:
           b[i] += a[i - 1]
       if i < n - 1:
           b[i] += a[i + 1]
   return

Above is a simple 10-line implementation in Python. First, the solution gets the length of a and then creates a zeroed-out array b of the same length. Next, it uses a for loop to traverse through b and complete the operations as specified. Note that this solution handles the edge cases by checking if the a index is in range before adding the value to b.

Question 2: String Pattern Matching

You are given two strings: pattern and source. The first string pattern contains only the symbols 0 and 1, and the second string source contains only lowercase English letters.

Your task is to calculate the number of substrings of source that match pattern

We’ll say that a substring source[l..r] matches pattern if the following three conditions are met:
– The pattern and substring are equal in length.
– Where there is a 0 in the pattern, there is a vowel in the substring. 
– Where there is a 1 in the pattern, there is a consonant in the substring. 

Vowels are ‘a‘, ‘e‘, ‘i‘, ‘o‘, ‘u‘, and ‘y‘. All other letters are consonants.

Example

For pattern = "010" and source = "amazing", the output should be solution(pattern, source) = 2.
– “010” matches source[0..2] = "ama". The pattern specifies “vowel, consonant, vowel”. “ama” matches this pattern: 0 matches a, 1 matches m, and 0 matches a. 
– “010” doesn’t match source[1..3] = "maz" 
– “010” matches source[2..4] = "azi" 
– “010” doesn’t match source[3..5] = "zin" 
– “010” doesn’t match source[4..6] = "ing"

So, there are 2 matches. For a visual demonstration, see the example video

For pattern = "100" and source = "codesignal", the output should be solution(pattern, source) = 0.
– There are no double vowels in the string "codesignal", so it’s not possible for any of its substrings to match this pattern.

Guaranteed constraints:
1 ≤ source.length ≤ 103
1 ≤ pattern.length ≤ 103

This is a pattern-matching question where instances of a pattern need to be found inside of a larger array. It has the advantage of testing several fundamental programming skills at once: traversing multiple arrays with nested loops, working with subarrays, and performing basic collections/string operations.

Note that the guaranteed constraints in this question indicate that the candidate shouldn’t worry about optimizing their solution. 

Question 2: Solution

vowels = ['a', 'e', 'i', 'o', 'u', 'y'] 

def check_for_pattern(pattern, source, start_index):
   for offset in range(len(pattern)):
       if pattern[offset] == '0':
           if source[start_index + offset] not in vowels:
               return 0
       else:
           if source[start_index + offset] in vowels:
               return 0
   return 1
  def solution(pattern, source):
   answer = 0
   for start_index in range(len(source) - len(pattern) + 1):
       answer += check_for_pattern(pattern, source, start_index)
   return answer

In this solution, the candidate first defines the vowels. Then, they define a helper function, check_for_pattern, that their solution will call for every possible substring in source. For each character in the pattern string, the helper function checks if the character in the substring matches the pattern (0 for vowel, 1 for consonant). 

Question 3: Two-Dimensional Array Traversal 

You are given a matrix of integers field of size height × width representing a game field, and also a matrix of integers figure of size 3 × 3 representing a figure. Both matrices contain only 0s and 1s, where 1 means that the cell is occupied, and 0 means that the cell is free.

You choose a position at the top of the game field where you put the figure and then drop it down. The figure falls down until it either reaches the ground (bottom of the field) or lands on an occupied cell, which blocks it from falling further. After the figure has stopped falling, some of the rows in the field may become fully occupied.

demonstration

Your task is to find the dropping position such that at least one full row is formed. As a dropping position, you should return the column index of the cell in the game field which matches the top left corner of the figure’s 3 × 3 matrix. If there are multiple dropping positions satisfying the condition, feel free to return any of them. If there are no such dropping positions, return -1.

Note: The figure must be dropped so that its entire 3 × 3 matrix fits inside the field, even if part of the matrix is empty. 

Example

For
field = [[0, 0, 0],
         [0, 0, 0],
         [0, 0, 0],
         [1, 0, 0],
         [1, 1, 0]]

and
figure = [[0, 0, 1],
         [0, 1, 1],
         [0, 0, 1]]


the output should be solution(field, figure) = 0.

Because the field is a 3 x 3 matrix, the figure can be dropped only from position 0. When the figure stops falling, two fully occupied rows are formed, so dropping position 0 satisfies the condition.

example 1

For
field =  [[0, 0, 0, 0, 0],
          [0, 0, 0, 0, 0],
          [0, 0, 0, 0, 0],
          [1, 1, 0, 1, 0],
          [1, 0, 1, 0, 1]]


and
figure = [[1, 1, 1],
          [1, 0, 1],
          [1, 0, 1]]


the output should be solution(field, figure) = 2.

The figure can be dropped from three positions: 0, 1, and 2. As you can see below, a fully occupied row will be formed only when dropping from position 2:

example 2

For
field =  [[0, 0, 0, 0],
          [0, 0, 0, 0],
          [0, 0, 0, 0],
          [1, 0, 0, 1],
          [1, 1, 0, 1]]


and
figure = [[1, 1, 0],
          [1, 0, 0],
          [1, 0, 0]]


the output should be solution(field, figure) = -1.

The figure can be dropped from two positions, 0 and 1, and in both cases, a fully occupied row won’t be obtained:

example 3

Note that the figure could technically form a full row if it was dropped one position further to the right, but that is not a valid dropping position, because the 3 x 3 figure matrix wouldn’t be fully contained within the field.

This Tetris-inspired question is challenging. Candidates will have to traverse and manipulate two-dimensional arrays in a non-conventional way. As it’s an advanced question, it tests how well an engineer can understand a complex set of constraints and proceed with a non-trivial implementation.

Question 3: Solution

def solution(field, figure):
   height = len(field)
   width = len(field[0])
   figure_size = len(figure)
 
   for column in range(width - figure_size + 1):
       row = 1
       while row < height - figure_size + 1:
           can_fit = True
           for dx in range(figure_size):
               for dy in range(figure_size):
                   if field[row + dx][column + dy] == 1 and figure[dx][dy] == 1:
                       can_fit = False
           if not can_fit:
               break
           row += 1
       row -= 1
 
       for dx in range(figure_size):
           row_filled = True
           for column_index in range(width):
            if not (field[row + dx][column_index] == 1 or
                    (column <= column_index < column + figure_size and
                  figure[dx][column_index - column] == 1)):
                row_filled = False
           if row_filled:
               return column
   return -1

This solution starts by defining some dimensions that will be important for the problem. Then, for every valid dropping position—that is, columns in range(width - figure_size + 1)—the code goes row by row, seeing how far the figure will go until it will “stop.” 

To do this, it peeks at the next row and asks: can the figure fit there? If not, it stops at the previous row. The figure doesn’t fit if there is a 1 in the same place in both the figure and the field (offset by the row). The loop can stop when row == height - figure_size + 1, because then the bottom of the figure will have hit the bottom of the field.

Once the code figures out the last row the figure can drop to before it can’t fit anymore, it’s time to see if there’s a fully-filled row created anywhere. From where the figure “stopped,” the code iterates through the field and figure arrays row by row, checking to see if together, they’ve created a filled row. Cleverly, the code sets row_filled = True and then marks it False if one or both of these conditions are met:

  • Any of the field cells in the row are empty (not 1)
  • Any of the figure cells in the row are empty (not 1)

Question 4: Lookup Table 

Given an array of unique integers numbers, your task is to find the number of pairs of indices (i, j) such that i ≤ j and the sum numbers[i] + numbers[j] is equal to some power of 2.

Note: The numbers 20  = 1, 21 = 2, 22 = 4, 23 = 8, etc. are considered to be powers of 2.

Example

For numbers = [1, -1, 2, 3], the output should be solution(numbers) = 5.
– There is one pair of indices where the sum of the elements is 20 = 1: (1, 2): numbers[1] + numbers[2] = -1 + 2 = 1
– There are two pairs of indices where the sum of the elements is 21 = 2: (0, 0) and (1, 3)
– There are two pairs of indices where the sum of the elements is 22 = 4: (0, 3) and (2, 2)
– In total, there are 1 + 2 + 2 = 5 pairs summing to powers of 2.

For numbers = [2], the output should be solution(numbers) = 1.
– The only pair of indices is (0, 0) and the sum is equal to 22 = 4. So, the answer is 1.

For numbers = [-2, -1, 0, 1, 2], the output should be solution(numbers) = 5.
– There are two pairs of indices where the sum of the elements is 20 = 1: (2, 3) and (1, 4)
– There are two pairs of indices where the sum of the elements is 21 = 2: (2, 4) and (3, 3)
– There is one pair of indices where the sum of the elements is 22 = 4: (4, 4)
– In total, there are 2 + 2 + 1 = 5 pairs summing to powers of 2

Guaranteed constraints:

1 ≤ numbers.length ≤ 105
-106 ≤ numbers[i] ≤ 106

This problem could be solved in a straightforward way by having two nested loops to choose each pair and check whether their sum is a power of two. But since the numbers array could be quite large, quadratic time complexity would be too much for this question. (To get more precise, it is O(n2 * log(MAX_NUMBER)) where MAX_NUMBER is the largest number seen in the array.)

Therefore, this question tests whether candidates have the problem-solving and data structures skills to use a lookup table (hash set/dictionary) in their programming language of choice. It also involves a bit of tricky logic to avoid double-counting pairs. Finally, this question asks candidates to pay close attention to constraints, testing a key skill for real-world development.

Question 4: Solution

from collections import defaultdict

 def solution(numbers):
   counts = defaultdict(int)
   answer = 0
   for element in numbers:
       counts[element] += 1
       for two_power in range(21):
           second_element = (1 << two_power) - element
           answer += counts[second_element]
   return answer 

This Python solution uses collections.defaultdict to create a dictionary of integers. For each element in the array, the element is first counted in the dictionary. Then, the loop checks for sums of all of the powers of two that are less than 221. Why stop there? The constraint says that no element of the array can be greater than 106, or 1,000,000. 221 is 2,097,152, which is greater than 1 million when divided by two, so there is no way that two elements could sum to 221

To calculate the powers of two, the code uses a left shift bitwise operator: 1 << two_power in Python is the same as 2two_power. It defines second_element as the amount needed for the current element to sum to the power of two. Then it looks up the count for second_element in the dictionary. The number of second_elements already found in the array gets added to the answer, because this is the number of pairs (so far) that sum to that power of two. By the time it reaches the end of the array, this algorithm will have found all the pairs—in linear time.

We hope this has given you some insight into the kinds of technical interview questions we ask at CodeSignal. For developers looking to practice or further build their skills, check out CodeSignal Learn.

Learn a revolutionary learning product for anyone launching a technical career, pivoting into a new role, building competitive and in-demand skills for a job search, or leveling-up in their current role. Take courses in machine learning, data science, Python programming, and more with one-on-one support from the smartest AI guide in the universe, Cosmo. Sign up to get started for free.

Note: If you’re a hiring manager wanting to learn more about our skills evaluation frameworks and how we approach question design, schedule a discovery call with us today


Dmitry Filippov is the Technical Assessment Lead at CodeSignal, where he manages content development for all of CodeSignal’s technical assessments. He received his Master’s degree in Computer Science from ITMO University, and has been an active member of the International Collegiate Programming Contest community for over 10 years.