Skip to main content
Practice questions · Checked November 3, 2026

CodeSignal Practice Test: 8 GCA-Style Questions with Solutions

These are 8 original practice questions shaped like the CodeSignal General Coding Assessment (GCA): two rounds of 4 questions that get harder, each round meant to be done in 70 minutes. In each round, questions 1 and 2 are quick implementation tasks, question 3 is a longer simulation, and question 4 needs an efficient data structure to pass large hidden tests. Every question has examples, an approach, a tested Python 3 solution and the edge cases hidden tests would check. None of them are real GCA questions, so pair them with CodeSignal's free practice assessments in the real editor.

The GCA format in 30 seconds

  • The General Coding Assessment is 4 questions of varying difficulty in 70 minutes, taken in one sitting.
  • You can answer in any order and submit as often as you like. Your highest-scoring submission counts.
  • Sample tests are visible. Submit runs the full suite, including hidden tests, and points come from the tests you pass.
  • Certified results are scored from 200 to 600. There is no official passing score; each company sets its own bar.
  • Proctoring records your camera, microphone and screen.

Scoring, proctoring and retakes are in our CodeSignal guide.

A 70-minute plan for each round

  1. 1Minutes 0-5: open all 4 questions and read them. You can answer in any order.
  2. 2Minutes 5-20: solve and submit questions 1 and 2, about 7 minutes each.
  3. 3Minutes 20-45: question 3. Get it passing the sample tests, submit, then fix edge cases.
  4. 4Minutes 45-68: question 4. Submit a simple version first for partial points, then make it fast.
  5. 5Last 2 minutes: check that every question has a submission. Your best one counts.

The 8 CodeSignal practice questions

Do round 1 (questions 1-4) in one 70-minute sitting and round 2 (questions 5-8) in another. Try each question before you open its solution.

#ProblemDifficultyRoundPattern
1Turning points in a heart-rate logEasy1Array scan
2Cut a playlist into radio blocksEasy1Greedy simulation
3Slide and merge tilesMedium1Matrix simulation
4Balanced windows in a sign-in logHard1Prefix sums + hash map
5Password rulesEasy2String checks
6Shift each word by its positionEasy2String manipulation
7Parking garage spotsMedium2Min-heap + hash map
8Shortest stretch with every categoryHard2Sliding window
Problem 1EasyRound 1Array scan

Turning points in a heart-rate log

def solution(readings: list[int]) -> int

A fitness tracker logs your heart rate once a minute in the array readings. A reading is a turning point if it is strictly higher than both of its neighbors or strictly lower than both. The first and last readings have only one neighbor, so they never count. Return the number of turning points.

Examples

Input
readings = [70, 75, 72, 72, 80, 78]
Output
2
Why
75 and 80 are peaks. The two 72s do not count: a reading equal to a neighbor is not strictly higher or lower.
Input
readings = [60, 61]
Output
0

Constraints

  • 1 <= len(readings) <= 1,000
  • 30 <= readings[i] <= 220
Show approach and solution

Approach

Walk the inner positions 1 to n - 2 and compare each reading with its two neighbors. Count it when it is above both or below both. Arrays shorter than 3 have no inner positions, so the loop never runs and the answer is 0.

Python 3 solution
def solution(readings):
    count = 0
    for i in range(1, len(readings) - 1):
        left, mid, right = readings[i - 1], readings[i], readings[i + 1]
        if (mid > left and mid > right) or (mid < left and mid < right):
            count += 1
    return count

Complexity: O(n) time, O(1) extra space.

What the hidden tests check: Arrays of length 1 and 2, flat stretches of equal values, strictly increasing arrays (answer 0), and zigzag arrays where every inner reading counts.

Problem 2EasyRound 1Greedy simulation

Cut a playlist into radio blocks

def solution(lengths: list[int], limit: int) -> int

You are cutting a playlist into radio blocks. Songs stay in order. Add songs to the current block one at a time; if the next song would push the block's total past limit seconds, close the block and start a new one with that song. A song longer than limit gets a block to itself. Return the number of blocks.

Examples

Input
lengths = [200, 180, 240, 90, 300], limit = 450
Output
3
Why
Blocks are [200, 180], [240, 90] and [300]. Adding 240 to the first block would make 620, which is past 450.
Input
lengths = [500, 100], limit = 300
Output
2
Why
The 500-second song is longer than the limit, so it sits alone.

Constraints

  • 0 <= len(lengths) <= 10,000
  • 1 <= lengths[i] <= 3,600
  • 1 <= limit <= 100,000
Show approach and solution

Approach

Keep the running total of the open block. For each song, start a new block if there is no block yet or the song would push the total past the limit; otherwise add it. A block that lands exactly on the limit is allowed, because "past" means greater than.

Python 3 solution
def solution(lengths, limit):
    blocks = 0
    current = 0
    for song in lengths:
        if blocks == 0 or current + song > limit:
            blocks += 1
            current = song
        else:
            current += song
    return blocks

Complexity: O(n) time, O(1) extra space.

What the hidden tests check: An empty playlist (0 blocks), a block that ends exactly at the limit, songs longer than the limit, and a single song.

Problem 3MediumRound 1Matrix simulation

Slide and merge tiles

def solution(board: list[list[int]]) -> list[list[int]]

A puzzle board is a grid of non-negative integers where 0 is an empty cell. When the player swipes left, every row changes the same way: tiles slide left past empty cells, and two equal tiles that end up next to each other merge into one tile with double the value. A tile made by a merge cannot merge again in the same swipe, and merges are resolved from left to right. Return the board after one swipe left.

Examples

Input
board = [[2, 0, 2, 4],
         [4, 4, 4, 4],
         [2, 2, 2, 0],
         [0, 0, 0, 8]]
Output
[[4, 4, 0, 0],
 [8, 8, 0, 0],
 [4, 2, 0, 0],
 [8, 0, 0, 0]]
Why
In row 1 the two 2s merge into a 4, and that new 4 does not merge with the existing 4. In row 3 the leftmost pair merges first, so the third 2 stays on its own.
Input
board = [[0, 0], [3, 3]]
Output
[[0, 0], [6, 0]]

Constraints

  • 1 <= rows, cols <= 100
  • 0 <= board[i][j] <= 2^20
Show approach and solution

Approach

Handle each row on its own. Drop the zeros, then walk the remaining tiles left to right: if a tile equals the next one, write their sum and skip both; otherwise write the tile and move one step. Skipping both tiles is what stops a merged tile from merging again. Pad the row with zeros back to its width.

Python 3 solution
def solution(board):
    result = []
    for row in board:
        tiles = [value for value in row if value != 0]
        merged = []
        i = 0
        while i < len(tiles):
            if i + 1 < len(tiles) and tiles[i] == tiles[i + 1]:
                merged.append(tiles[i] * 2)
                i += 2
            else:
                merged.append(tiles[i])
                i += 1
        merged += [0] * (len(row) - len(merged))
        result.append(merged)
    return result

Complexity: O(rows x cols) time, O(cols) extra space per row.

What the hidden tests check: Rows of all zeros, rows with no merges, four equal tiles in a row (two merges, not one), a single column, and zeros between two equal tiles.

Problem 4HardRound 1Prefix sums + hash map

Balanced windows in a sign-in log

def solution(log: str) -> int

A server log is a string of 'I' (a user signs in) and 'O' (a user signs out). A window is any contiguous substring of the log. Return the number of windows that contain the same number of 'I' and 'O' characters.

Examples

Input
log = "IOIO"
Output
4
Why
The balanced windows are "IO" (twice), "OI" and "IOIO".
Input
log = "IIO"
Output
1
Input
log = "III"
Output
0

Constraints

  • 1 <= len(log) <= 100,000
  • Checking every window is O(n^2), which is too slow for the largest tests.
Show approach and solution

Approach

Keep a running balance: +1 for I and -1 for O. A window is balanced exactly when the balance at its end equals the balance just before its start. So count, for every position, how many earlier positions had the same balance, using a hash map from balance to count. Seed the map with balance 0 seen once, for windows that start at the beginning.

Python 3 solution
def solution(log):
    seen = {0: 1}
    balance = 0
    windows = 0
    for event in log:
        balance += 1 if event == 'I' else -1
        windows += seen.get(balance, 0)
        seen[balance] = seen.get(balance, 0) + 1
    return windows

Complexity: O(n) time, O(n) space for the map.

What the hidden tests check: Long strings of one letter (answer 0), perfectly alternating strings (the answer grows to about n^2 / 4), and 100,000 characters to rule out the O(n^2) check.

Problem 5EasyRound 2String checks

Password rules

def solution(passwords: list[str]) -> int

A sign-up form accepts a password only if all four rules hold: it has at least 8 characters, at least one digit, at least one uppercase letter, and no character appears three or more times in a row. Given a list of passwords, return how many are accepted.

Examples

Input
passwords = ["Summer2026", "password1", "AAAbbb123", "Ok1"]
Output
1
Why
"password1" has no uppercase letter, "AAAbbb123" has three A's in a row and "Ok1" is too short.
Input
passwords = ["Xx11Yy22", "Xx111Yy2"]
Output
1

Constraints

  • 1 <= len(passwords) <= 1,000
  • Each password has 1 to 100 printable ASCII characters and no spaces.
Show approach and solution

Approach

Write one helper that checks a single password and returns early on the first broken rule, then count the passwords that pass. For the run rule, compare each character with the two before it.

Python 3 solution
def is_valid(password):
    if len(password) < 8:
        return False
    if not any(ch.isdigit() for ch in password):
        return False
    if not any(ch.isupper() for ch in password):
        return False
    for i in range(2, len(password)):
        if password[i] == password[i - 1] == password[i - 2]:
            return False
    return True


def solution(passwords):
    return sum(1 for password in passwords if is_valid(password))

Complexity: O(total characters) time, O(1) extra space.

What the hidden tests check: Passwords of exactly 8 characters, a triple at the very end, symbols that are neither letters nor digits, and passwords that break only one rule.

Problem 6EasyRound 2String manipulation

Shift each word by its position

def solution(message: str) -> str

Encode a message by shifting every letter forward in the alphabet by the index of the word it belongs to: letters in the first word (index 0) stay the same, letters in the second word move 1 place, the third word 2 places, and so on. Shifts wrap from z back to a, uppercase letters stay uppercase, and anything that is not a letter stays as it is. Words are separated by single spaces.

Examples

Input
message = "meet at noon"
Output
"meet bu pqqp"
Input
message = "Zoo Zebra!"
Output
"Zoo Afcsb!"
Why
The second word shifts by 1, so Z wraps to A, and the ! is left alone.

Constraints

  • 0 <= len(message) <= 10,000
  • There can be thousands of words, so shifts go far past 26.
Show approach and solution

Approach

Split on single spaces, shift each letter by the word index modulo 26 using its offset from 'a' or 'A', and join the words back with single spaces. Taking the shift modulo 26 handles word 26 and later.

Python 3 solution
def shift_letter(ch, k):
    if 'a' <= ch <= 'z':
        return chr((ord(ch) - ord('a') + k) % 26 + ord('a'))
    if 'A' <= ch <= 'Z':
        return chr((ord(ch) - ord('A') + k) % 26 + ord('A'))
    return ch


def solution(message):
    words = message.split(' ')
    encoded = []
    for index, word in enumerate(words):
        encoded.append(''.join(shift_letter(ch, index) for ch in word))
    return ' '.join(encoded)

Complexity: O(n) time and space for the new string.

What the hidden tests check: Word 26 and later (the shift wraps back to no change), digits and punctuation inside words, uppercase Z, and the empty string.

Problem 7MediumRound 2Min-heap + hash map

Parking garage spots

def solution(n: int, events: list[str]) -> list[int]

A garage has n spots numbered 1 to n. You get a list of events in time order. "arrive <plate>" parks that car in the lowest-numbered free spot; "leave <plate>" frees the car's spot. Return a list with one entry per arrival: the spot the car got, or -1 if the garage was full (that car drives away). A leave event for a car that is not parked does nothing.

Examples

Input
n = 2
events = ["arrive A1", "arrive B2", "arrive C3", "leave A1", "arrive D4"]
Output
[1, 2, -1, 1]
Why
C3 finds the garage full. After A1 leaves, spot 1 is free again, so D4 gets it.
Input
n = 3
events = ["arrive X", "arrive Y", "leave X", "leave Z", "arrive Z", "arrive W"]
Output
[1, 2, 1, 3]

Constraints

  • 1 <= n <= 100,000
  • 1 <= len(events) <= 100,000
  • A plate never arrives while it is already parked.
Show approach and solution

Approach

Scanning for the lowest free spot on every arrival is O(n) each time, too slow at 100,000 events. Keep the free spots in a min-heap so the lowest one pops in O(log n), and a dict from plate to spot so a leave can push the spot back. A car that was turned away is never in the dict, so its leave event is ignored.

Python 3 solution
import heapq


def solution(n, events):
    free = list(range(1, n + 1))
    heapq.heapify(free)
    parked = {}
    assigned = []
    for event in events:
        action, plate = event.split()
        if action == 'arrive':
            if free:
                spot = heapq.heappop(free)
                parked[plate] = spot
                assigned.append(spot)
            else:
                assigned.append(-1)
        elif plate in parked:
            heapq.heappush(free, parked.pop(plate))
    return assigned

Complexity: O((n + m) log n) time for m events, O(n) space.

What the hidden tests check: A full garage, leave events for cars that were turned away, spots freed out of order (the next car must still get the lowest number), and 100,000 events.

Problem 8HardRound 2Sliding window

Shortest stretch with every category

def solution(items: list[str]) -> int

A store's checkout log lists product categories in the order they were scanned during the day. Find the shortest contiguous stretch of the log that includes every category that appears anywhere in the log at least once. Return its length.

Examples

Input
items = ["milk", "eggs", "milk", "bread", "eggs", "milk"]
Output
3
Why
There are 3 categories, and ["eggs", "milk", "bread"] holds all of them.
Input
items = ["tea", "tea", "tea"]
Output
1

Constraints

  • 1 <= len(items) <= 100,000
  • Checking every stretch is O(n^2) or worse, too slow for the largest tests.
Show approach and solution

Approach

Count the distinct categories first. Then grow a window to the right, keeping a count per category and how many categories are covered. Whenever the window covers them all, record its length and shrink it from the left until it no longer does. Each index enters and leaves the window once.

Python 3 solution
from collections import defaultdict


def solution(items):
    needed = len(set(items))
    counts = defaultdict(int)
    covered = 0
    best = len(items)
    left = 0
    for right, item in enumerate(items):
        counts[item] += 1
        if counts[item] == 1:
            covered += 1
        while covered == needed:
            best = min(best, right - left + 1)
            counts[items[left]] -= 1
            if counts[items[left]] == 0:
                covered -= 1
            left += 1
    return best

Complexity: O(n) time, O(k) space for k categories.

What the hidden tests check: A single category, every item different (the answer is the whole log), the shortest stretch at the very end, and 100,000 items so the O(n^2) scan is too slow.

How to practice for the CodeSignal round

  1. Step 1

    Do one round per sitting

    Set a 70-minute timer and open all 4 questions of a round at once, like the real test. No AI, and look up syntax only, which is what the GCA allows.

  2. Step 2

    Submit a working version first

    Get each question passing its examples before you polish it. On the GCA your best submission counts and partial credit comes from tests passed, so a working first version is never wasted.

  3. Step 3

    Grade yourself with the hidden-test notes

    When the timer ends, run your code on the edge cases listed under each solution. Write down the ones you missed; they are the habits to fix.

  4. Step 4

    Finish in the real editor

    Take CodeSignal's free practice assessment so the editor, the sample tests and the submit flow feel familiar on test day. Companies cannot see your practice activity.

OphyAI Desktop for Mac and Windows

Practice with these, then use Coding Copilot in your CodeSignal interview

Coding Copilot in the OphyAI desktop app reads the coding problem on your screen with one hotkey and returns an approach, complexity notes and working code in your language.

Practice with these, then bring Coding Copilot into the real CodeSignal interview. While you practice, press Cmd/Ctrl + Shift + A to snap the problem window, or Cmd/Ctrl + Shift + S to drag a box around one question, and Coding Copilot returns an answer card: how it read the problem, what to say first, the code with line numbers, a dry run with edge cases, and the Big O. Compare it with your own attempt.

In a live CodeSignal interview, press Space or Cmd/Ctrl + Shift + L and it transcribes the question your interviewer asks out loud. The card shows in a floating overlay that macOS and Windows leave out of screen sharing and recording. It stays on top of a full-screen editor or browser and opens without taking focus from your editor.

  • Cmd/Ctrl + Shift + A snaps the problem window, even when other windows cover it, and Cmd/Ctrl + Shift + S lets you drag a box around part of the screen. In a live interview, Space or Cmd/Ctrl + Shift + L transcribes the question the interviewer asks out loud.

  • Answers show as a card in a floating overlay that macOS and Windows leave out of screen sharing and recording. It stays on top of a full-screen editor or browser and opens without taking the keyboard from your editor.

  • Each answer card shows how OphyAI read the problem, what to say first, the code with line numbers, a dry run with edge cases, and the Big O. Follow-ups remember the problem, so "now handle duplicates" updates the same code.

Free download. Coding Interview is on the Premium plan ($59 a month, 500 credits) and uses 15 credits per session. See everything it does

What it is hidden from, and what it is not

On the proctored GCA, CodeSignal records your camera, microphone and screen. Companies can also turn on CodeSignal's own AI assistant for an assessment.

The OphyAI window is hidden from screen sharing and recording, but not from a webcam, a person watching, or the platform's own keystroke, paste and tab tracking.

CodeSignal practice test FAQ

Start with CodeSignal's free practice assessments, which use the real editor; companies cannot see your activity there. Then use the 8 original questions on this page for full timed runs of 4 questions in 70 minutes.

No. CodeSignal's practice area shows the editor and the question types, and this page copies the GCA's shape of 4 questions that get harder, but the real test draws from a very large pool. CodeSignal says the GCA has over 628,000 variations, so practice the patterns, not specific questions.

The one you write fastest without looking things up. The GCA lists 38 languages, including Python 3, Java, C++, JavaScript and Go. The solutions here are in Python 3 because it keeps the code short.

There is no official passing score; each company sets its own. Points come from the test cases your submissions pass, so a partial solution still scores, and bonus points come only from fully solving a group of questions.

Our plan: read all 4 first, then about 15 minutes for questions 1 and 2 together, about 25 for question 3, and the rest for question 4. Submit something on every question, because your best submission counts.

The proctored GCA records your camera, microphone and screen for the whole test. Our CodeSignal assessment guide covers proctoring and scoring in full.

Yes. Coding Copilot in the OphyAI desktop app reads a problem on your screen with Cmd/Ctrl + Shift + A and returns an approach, complexity notes and working code, so you can check your attempts at these questions. It also works on the CodeSignal test itself and in live CodeSignal interviews, in an overlay that screen sharing and recording leave out. It does not hide from your webcam or from CodeSignal's own proctoring.

Practice here, then take Coding Copilot into your CodeSignal interview

Download OphyAI Desktop and bring Coding Copilot into your next coding interview: it hears the question, reads the problem, and shows the approach and code in an overlay your screen share leaves out.