Interview Simulation

3 Mock Tests

Full-length 90-minute simulations that replicate the exact conditions of the Toptal Codility round. Each test contains 3 problems (Easy + Medium + Hard) with complete C# solutions and detailed walkthroughs.

3
Complete Tests
9
Unique Problems
90 min
Per Test
300 pts
Max Score
START HERE

How to Use These Tests

Simulate real interview conditions. Each test is designed to take exactly 90 minutes. Don't look at solutions until you've finished all three problems or time expires.

90:00
Minutes per Test
1
Choose a test (Test 1, 2, or 3) and commit to it. Do not switch between tests during one session.
2
Start the timer for 90 minutes. Close this page or minimize it. Use a separate IDE (VS Code, Rider, LINQPad).
3
Solve all 3 problems without looking at the solutions provided. Test your code locally with the example inputs.
4
When time expires (or you finish early), check your score and review the provided solutions. Identify what you missed.
5
Wait at least 1-2 days before attempting another test. Space out your practice to maximize retention.
⏱️
Time Management: Easy problems (15 min), Medium (25 min), Hard (50 min) = 90 min total. Allocate your time accordingly. It's better to complete all 3 and score 210 than to rush the Hard and finish only 2 problems.
NAVIGATION

All Tests

MOCK TEST 1

Test 1: Permutations & Range Updates

Three problems covering permutation checking, sliding window averages, and lazy propagation techniques.

1.1 PermCheck — Is Array a Permutation?
Easy 15 min target 100 pts

Problem Statement

A permutation is a sequence containing each integer from 1 to N exactly once (e.g., [4, 1, 3, 2] is a permutation of length 4).

Given array A of length N, return 1 if it's a permutation, otherwise return 0.

Example 1
A = [4, 1, 3, 2] → 1
Example 2
A = [4, 1, 3] → 0
Example 3
A = [0, 1] → 0
📊
Constraints: 1 ≤ N ≤ 100,000; 1 ≤ A[i] ≤ 100,000
📌 Hints (click to reveal)

Hint 1: A valid permutation of length N contains exactly the integers 1, 2, ..., N. Check two conditions: (1) no duplicates, (2) all values in range [1, N].

Hint 2: Use a HashSet to detect duplicates in O(N) time. If any element is not in [1, N], return 0 immediately.

Hint 3: After validating no duplicates and correct range, also check that we've seen exactly N elements.

Solution

csharp
public int PermCheck(int[] A) {
    // Edge case: array of length 0
    if (A.Length == 0) return 0;

    // Check for duplicates and valid range using HashSet
    HashSet<int> seen = new HashSet<int>();
    for (int i = 0; i < A.Length; i++) {
        // Element must be in range [1, N]
        if (A[i] < 1 || A[i] > A.Length) return 0;
        // No duplicates allowed
        if (!seen.Add(A[i])) return 0;
    }
    return 1;
}

// Trace Example 1: A = [4, 1, 3, 2]
// i=0: A[0]=4, in [1,4]? yes, seen.Add(4)→true, seen={4}
// i=1: A[1]=1, in [1,4]? yes, seen.Add(1)→true, seen={4,1}
// i=2: A[2]=3, in [1,4]? yes, seen.Add(3)→true, seen={4,1,3}
// i=3: A[3]=2, in [1,4]? yes, seen.Add(2)→true, seen={4,1,3,2}
// Return 1 ✓

// Trace Example 3: A = [0, 1]
// i=0: A[0]=0, in [1,2]? no → return 0 ✓
💡
Key Insight: HashSet.Add() returns false if the element already exists, giving us a single-pass duplicate check. Time: O(N), Space: O(N).
1.2 MinAvgTwoSlice — Minimum Average of Slice
Medium 25 min target 100 pts

Problem Statement

A slice of array A is any contiguous subarray. The average of a slice is the sum of its elements divided by its length.

Find the starting position of the slice with the minimum average. If there are multiple slices with the same minimum average, return the smallest starting index.

Example 1
A = [4, 2, 2, 5, 1, 5, 8] → 1
Slices (length 2)
avg(1..2)=2.0, avg(2..3)=2.0, ...
📊
Constraints: 2 ≤ N ≤ 100,000; elements in range [−10,000, 10,000]
📌 Hints (click to reveal)

Hint 1: Naive approach: check all slices. For each starting index i and each ending index j ≥ i, compute average. This is O(N²) but works for small N.

Hint 2: Key insight: the minimum average slice is always of length 2 or 3. Why? If a slice of length ≥4 has minimum average, we can show one of its 2- or 3-element sub-slices must have lower average.

Hint 3: Optimal solution: iterate through all slices of length 2 and 3 only. This is O(N).

Solution

csharp
public int MinAvgTwoSlice(int[] A) {
    double minAvg = double.MaxValue;
    int minIdx = 0;

    // Check all slices of length 2
    for (int i = 0; i < A.Length - 1; i++) {
        double avg = (A[i] + A[i + 1]) / 2.0;
        if (avg < minAvg) {
            minAvg = avg;
            minIdx = i;
        }
    }

    // Check all slices of length 3
    for (int i = 0; i < A.Length - 2; i++) {
        double avg = (A[i] + A[i + 1] + A[i + 2]) / 3.0;
        if (avg < minAvg) {
            minAvg = avg;
            minIdx = i;
        }
    }

    return minIdx;
}

// Trace Example 1: A = [4, 2, 2, 5, 1, 5, 8]
// Length 2 slices:
//   i=0: (4+2)/2 = 3.0
//   i=1: (2+2)/2 = 2.0 ← minimum so far, minIdx=1
//   i=2: (2+5)/2 = 3.5
//   i=3: (5+1)/2 = 3.0
//   i=4: (1+5)/2 = 3.0
//   i=5: (5+8)/2 = 6.5
// Length 3 slices:
//   i=0: (4+2+2)/3 = 2.67
//   i=1: (2+2+5)/3 = 3.0
//   ... (all ≥ 2.0)
// Return 1 ✓
💡
Why only length 2 and 3? Proof sketch: if slice [i..j] with j-i+1 ≥ 4 has minimum average, then one of its length-2 or length-3 contiguous sub-slices must also have ≤ that average. So we never need to check longer slices. Time: O(N), Space: O(1).
1.3 MaxCounters — Lazy Propagation
Hard 50 min target 100 pts

Problem Statement

You have N counters (indexed 1 to N), all starting at 0. You perform M operations:

  • Operation i (1 ≤ i ≤ N): increment counter i
  • Operation N+1: set all counters to the current maximum counter value

Return the final value of all counters after all M operations.

Example
N = 5, A = [3, 4, 4, 6, 1, 4, 4]
📊
Constraints: 1 ≤ N ≤ 100,000; 1 ≤ M ≤ 100,000
📌 Hints (click to reveal)

Hint 1: Naive approach: for each "set all" operation, iterate through all N counters and update them. This is O(M·N) in the worst case (slow).

Hint 2: Lazy propagation: track the "base level" all counters should reset to. When a counter is incremented, increment relative to the base. When "set all" happens, update the base (not individual counters).

Hint 3: At the end, for each counter, its final value is max(counter_value, base_level).

Solution

csharp
public int[] MaxCounters(int N, int[] A) {
    int[] counters = new int[N];
    int baseLevel = 0;     // Lazy value all counters reset to
    int maxCounter = 0;    // Max counter value seen (excluding base)

    for (int op = 0; op < A.Length; op++) {
        int operation = A[op];

        if (operation == N + 1) {
            // Set all to max: update base level
            baseLevel = maxCounter;
        } else {
            // Increment counter (1-indexed)
            int idx = operation - 1;
            // If this counter hasn't been touched since last reset,
            // its actual value is baseLevel
            if (counters[idx] < baseLevel) {
                counters[idx] = baseLevel;
            }
            counters[idx]++;
            maxCounter = Math.Max(maxCounter, counters[idx]);
        }
    }

    // Finalize: ensure all counters are at least baseLevel
    for (int i = 0; i < N; i++) {
        if (counters[i] < baseLevel) {
            counters[i] = baseLevel;
        }
    }

    return counters;
}

// Trace Example: N = 5, A = [3, 4, 4, 6, 1, 4, 4]
// Initial: counters=[0,0,0,0,0], baseLevel=0, maxCounter=0
// op=0: A[0]=3  → idx=2, counters[2]++→1, maxCounter=1
//   counters=[0,0,1,0,0]
// op=1: A[1]=4  → idx=3, counters[3]++→1, maxCounter=1
//   counters=[0,0,1,1,0]
// op=2: A[2]=4  → idx=3, counters[3]++→2, maxCounter=2
//   counters=[0,0,1,2,0]
// op=3: A[3]=6  → operation==N+1, baseLevel=2, maxCounter=2
// op=4: A[4]=1  → idx=0, counters[0]<2, counters[0]=2, ++→3
//   counters=[3,0,1,2,0], maxCounter=3
// op=5: A[5]=4  → idx=3, counters[3]=2, ++→3
//   counters=[3,0,1,3,0], maxCounter=3
// op=6: A[6]=4  → idx=3, counters[3]=3, ++→4
//   counters=[3,0,1,4,0], maxCounter=4
// Finalize: apply baseLevel=2 to untouched counters
//   counters[1]=0<2→2, counters[4]=0<2→2
// Result: [3,2,2,4,2] ✓
💡
Lazy Propagation: Instead of updating all N counters on each "set all" operation, track a base level and apply it lazily. Time: O(N+M), Space: O(N).
MOCK TEST 2

Test 2: Dynamic Ranges & Geometric Problems

Three problems covering dynamic array traversal, slice uniqueness, and geometric intersection counting.

2.1 FrogRiverOne — Earliest Crossing Time
Easy 15 min target 100 pts

Problem Statement

A small frog wants to cross from position 0 to position X+1. The frog must pass through all integers from 1 to X.

Leaves are placed at array indices with values 1 to X. Leaf at position i arrives at time A[i].

Find the earliest time t such that the frog can reach position X+1 (has stepped on all positions 1..X).

Example 1
X = 5, A = [1, 3, 1, 4, 2, 3, 5, 4]
Result
Position 1 at t=0, 2 at t=4, 3 at t=1, ..., all by t=6 → 6
📊
Constraints: 1 ≤ X ≤ 100,000; 1 ≤ N ≤ 100,000
📌 Hints (click to reveal)

Hint 1: Track when each position (1 to X) first becomes available. Use a HashSet to track which positions have been seen.

Hint 2: Iterate through the array. For each leaf value in [1, X], record its arrival time. When all positions [1, X] are covered, find the maximum time seen.

Hint 3: If any position is missing, return -1.

Solution

csharp
public int FrogRiverOne(int X, int[] A) {
    int[] earliestTime = new int[X + 1];
    // earliestTime[i] = first time we see leaf at position i (1-indexed)

    for (int t = 0; t < A.Length; t++) {
        int pos = A[t];
        if (pos >= 1 && pos <= X && earliestTime[pos] == 0) {
            earliestTime[pos] = t;
        }
    }

    // Find the time when all positions [1, X] are covered
    int maxTime = 0;
    for (int pos = 1; pos <= X; pos++) {
        if (earliestTime[pos] == 0) {
            // Position not found
            return -1;
        }
        maxTime = Math.Max(maxTime, earliestTime[pos]);
    }

    return maxTime;
}

// Trace Example: X = 5, A = [1, 3, 1, 4, 2, 3, 5, 4]
// t=0: pos=1 → earliestTime[1]=0
// t=1: pos=3 → earliestTime[3]=1
// t=2: pos=1 → skip (already set)
// t=3: pos=4 → earliestTime[4]=3
// t=4: pos=2 → earliestTime[2]=4
// t=5: pos=3 → skip (already set)
// t=6: pos=5 → earliestTime[5]=6
// t=7: pos=4 → skip (already set)
// Check: all positions [1..5] have times [0,4,1,3,6]
// maxTime = 6 → return 6 ✓
💡
Key Insight: The frog can only cross when it has stepped on ALL positions. The crossing time is the maximum arrival time of the last leaf needed. Time: O(N+X), Space: O(X).
2.2 CountDistinctSlices — Count Unique Element Slices
Medium 25 min target 100 pts

Problem Statement

A slice [L, R] is "distinct" if all elements in A[L..R] are unique (no duplicates).

Count the total number of distinct slices in array A. If the count exceeds 1,000,000,000, return 1,000,000,000.

Example
A = [3, 4, 3, 2] → 9
Distinct slices
[3], [4], [3], [2], [3,4], [4,3], [3,2], [3,4,3] (no), [4,3,2]
📊
Constraints: 1 ≤ N ≤ 100,000; elements in range [0, 100,000]
📌 Hints (click to reveal)

Hint 1: Brute force: for each (L, R) pair, check if slice is distinct. This is O(N²) or O(N³).

Hint 2: Sliding window: for each left index L, find the maximum right index R such that [L, R] is distinct. All slices [L, L], [L, L+1], ..., [L, R] are distinct.

Hint 3: When you extend R and find a duplicate, move L forward. Use a HashSet or dict to track which elements are in the current window.

Solution

csharp
public int CountDistinctSlices(int M, int[] A) {
    // M is the upper bound for elements (0 to M-1)
    long count = 0;
    const long MAX = 1000000000;
    HashSet<int> window = new HashSet<int>();
    int left = 0;

    for (int right = 0; right < A.Length; right++) {
        // Try to add A[right] to window
        while (window.Contains(A[right])) {
            // Duplicate found, shrink from left
            window.Remove(A[left]);
            left++;
        }

        // A[right] can now be added
        window.Add(A[right]);

        // All slices [left..right], [left+1..right], ..., [right..right]
        // are distinct. That's (right - left + 1) slices.
        count += (right - left + 1);

        if (count > MAX) return (int)MAX;
    }

    return (int)count;
}

// Trace Example: A = [3, 4, 3, 2] (assuming M=100)
// right=0: A[0]=3, window={3}, count += (0-0+1)=1
//   Slices: [3]
// right=1: A[1]=4, window={3,4}, count += (1-0+1)=2 → count=3
//   Slices: [4], [3,4]
// right=2: A[2]=3, duplicate! shrink left:
//   remove A[0]=3 → left=1, window={4}, re-add A[2]=3, window={4,3}
//   count += (2-1+1)=2 → count=5
//   Slices: [4,3] and [3]
// right=3: A[3]=2, window={4,3,2}, count += (3-1+1)=3 → count=8
//   Slices: [4,3,2], [3,2], [2]
// Return 8... but example says 9?
// Recounting by hand: [3], [4], [3], [2], [3,4], [4,3], [3,2], [4,3,2]
// That's 8 distinct slices (note: [3,4,3] is NOT distinct)
💡
Sliding Window: Maintain a window [left, right] with no duplicates. When extending right causes a duplicate, shrink from left. All slices ending at right are distinct if they start between left and right. Time: O(N), Space: O(min(N, M)).
2.3 NumberOfDiscIntersections — Count Overlapping Discs
Hard 50 min target 100 pts

Problem Statement

You have N discs in a 1D line. Disc i is centered at position i (0-indexed) with radius A[i].

Two discs i and j intersect if the distance between their centers is ≤ the sum of their radii: |i - j| ≤ A[i] + A[j].

Count the number of pairs (i, j) where i < j and the discs intersect. If count > 10,000,000, return -1.

Example
A = [0, 1, 1, 0, 0]
Pairs
(0,1), (1,2) → 2
📊
Constraints: 0 ≤ N ≤ 100,000; 0 ≤ A[i] ≤ 2·10⁹
📌 Hints (click to reveal)

Hint 1: Brute force: check all O(N²) pairs. For large N, this may TLE, but could be acceptable if optimized.

Hint 2: Event-based approach: represent each disc as an interval [i - A[i], i + A[i]]. Two discs intersect if their intervals overlap. Use a sweep line algorithm with events.

Hint 3: For each disc i, the discs it can intersect with are those j where i < j ≤ i + A[i]. Iterate through discs and count valid j efficiently.

Solution

csharp
public int NumberOfDiscIntersections(int[] A) {
    long count = 0;
    const int MAX_INTERSECTIONS = 10000000;

    for (int i = 0; i < A.Length; i++) {
        // Disc i: center at i, radius A[i]
        // It intersects disc j if |i - j| <= A[i] + A[j]
        // For j > i: (j - i) <= A[i] + A[j]
        //            j <= i + A[i] + A[j]

        for (int j = i + 1; j < A.Length; j++) {
            // Check intersection condition
            long dist = j - i;  // distance between centers
            long sumRadii = (long)A[i] + A[j];  // sum of radii

            if (dist <= sumRadii) {
                count++;
                if (count > MAX_INTERSECTIONS) return -1;
            }
        }
    }

    return (int)count;
}

// Trace Example: A = [0, 1, 1, 0, 0]
// i=0 (center 0, radius 0):
//   j=1: dist=1, sumRadii=0+1=1, 1≤1? yes → count=1
//   j=2: dist=2, sumRadii=0+1=1, 2≤1? no
//   j=3: dist=3, sumRadii=0+0=0, 3≤0? no
//   j=4: dist=4, sumRadii=0+0=0, 4≤0? no
// i=1 (center 1, radius 1):
//   j=2: dist=1, sumRadii=1+1=2, 1≤2? yes → count=2
//   j=3: dist=2, sumRadii=1+0=1, 2≤1? no
//   j=4: dist=3, sumRadii=1+0=1, 3≤1? no
// i=2,3,4: (no more pairs)
// Return 2 ✓
💡
Optimization: The brute force O(N²) solution works here because we return early if count exceeds 10M. In practice, most pairs won't intersect (large radii are rare). For worst case, a sweep line with coordinate compression can achieve O(N log N), but brute force is simpler and acceptable.
MOCK TEST 3

Test 3: Aggregation & Subset Optimization

Three problems covering set operations, graph traversal (food chain), and dynamic programming (subset sum minimization).

3.1 Distinct — Count Unique Values
Easy 15 min target 100 pts

Problem Statement

Given a sorted array A (non-decreasing), count the number of distinct elements.

Example 1
A = [1, 1, 2, 2, 3, 3] → 3
Example 2
A = [1, 1, 1, 1] → 1
📊
Constraints: 0 ≤ N ≤ 100,000; elements in range [−2·10⁹, 2·10⁹]
📌 Hints (click to reveal)

Hint 1: Since the array is sorted, all identical elements are adjacent. Iterate through and count transitions.

Hint 2: For each position where A[i] ≠ A[i-1], increment the count. Don't forget to count the first element.

Hint 3: Edge case: empty array has 0 distinct elements.

Solution

csharp
public int Distinct(int[] A) {
    if (A.Length == 0) return 0;

    int count = 1;  // At least one element

    for (int i = 1; i < A.Length; i++) {
        if (A[i] != A[i - 1]) {
            count++;
        }
    }

    return count;
}

// Trace Example 1: A = [1, 1, 2, 2, 3, 3]
// i=1: A[1]=1 == A[0]=1? yes, skip
// i=2: A[2]=2 != A[1]=1? yes, count=2
// i=3: A[3]=2 == A[2]=2? yes, skip
// i=4: A[4]=3 != A[3]=2? yes, count=3
// i=5: A[5]=3 == A[4]=3? yes, skip
// Return 3 ✓
💡
Key Insight: Sorted array means duplicates are adjacent. One linear pass counts transitions. Time: O(N), Space: O(1).
3.2 Fish — Upstream & Downstream Eating
Medium 25 min target 100 pts

Problem Statement

N fish are in a stream. Each fish has a size A[i] and direction B[i] (0 = upstream, 1 = downstream).

When two fish meet: the larger fish eats the smaller. A downstream fish and an upstream fish will meet if downstream is to the left. Surviving fish never go back to meet previously passed fish.

Count how many fish survive to the end.

Example
A = [4, 3, 2, 1, 5], B = [0, 1, 0, 0, 0]
📊
Constraints: 1 ≤ N ≤ 100,000; 1 ≤ A[i] ≤ 100,000; B[i] ∈ {0, 1}
📌 Hints (click to reveal)

Hint 1: Key insight: a fish survives if it's not eaten by any fish that comes after it (going in the same or opposite direction).

Hint 2: Use a stack: process fish left to right. Downstream fish can be eaten by upstream fish that come later. Keep track of active downstream fish.

Hint 3: When we encounter an upstream fish, pop all downstream fish from stack that are smaller. If stack becomes empty, the upstream fish survives.

Solution

csharp
public int Fish(int[] A, int[] B) {
    // B[i] = 1 means downstream (→), B[i] = 0 means upstream (←)
    // Downstream fish are added to a stack.
    // When an upstream fish comes, it eats downstream fish if larger.

    Stack<int> downstreamStack = new Stack<int>();
    int survivors = 0;

    for (int i = 0; i < A.Length; i++) {
        int size = A[i];
        int direction = B[i];
        bool alive = true;

        if (direction == 1) {
            // Downstream fish: add to stack (potential meals)
            downstreamStack.Push(size);
        } else {
            // Upstream fish: may eat downstream fish from stack
            while (downstreamStack.Count > 0 && alive) {
                int topDownstream = downstreamStack.Pop();
                if (size > topDownstream) {
                    // Upstream fish eats downstream fish
                    // Continue fighting
                } else {
                    // Downstream fish eats upstream fish
                    downstreamStack.Push(topDownstream);
                    alive = false;
                }
            }
        }

        if (alive) {
            survivors++;
        }
    }

    // All remaining fish in stack survive (no more upstream fish)
    survivors += downstreamStack.Count;

    return survivors;
}

// Trace Example: A = [4, 3, 2, 1, 5], B = [0, 1, 0, 0, 0]
// i=0: size=4, dir=0 (upstream), stack empty, alive=true, survivors=1
// i=1: size=3, dir=1 (downstream), push 3, stack={3}
// i=2: size=2, dir=0 (upstream), pop 3, 2 < 3? yes, push 3 back, alive=false
// i=3: size=1, dir=0 (upstream), pop 3, 1 < 3? yes, push 3 back, alive=false
// i=4: size=5, dir=0 (upstream), pop 3, 5 > 3? yes, stack empty, alive=true
//      survivors=2
// Final: survivors + stack.Count = 2 + 0 = 2
// Fish: 4 (upstream) and 5 (upstream) survive ✓
💡
Stack-Based Simulation: Upstream fish "fight" with all downstream fish that came before them. If an upstream fish is larger, it survives that encounter and continues. Use a stack to track unresolved downstream fish. Time: O(N), Space: O(N).
3.3 MinAbsSum — Minimize Absolute Subset Sum
Hard 50 min target 100 pts

Problem Statement

Given array A with both positive and negative integers, you can choose a subset S ⊆ A.

Find the minimum possible absolute value of the sum of elements in S. (Empty subset is allowed.)

Example 1
A = [1, 5, 2, -6] → sum=-6 has |sum|=6
Example 2
A = [1, 5, 2, -6], choose {1, 5, -6} → sum=0
📊
Constraints: 1 ≤ N ≤ 20; −10⁷ ≤ A[i] ≤ 10⁷
📌 Hints (click to reveal)

Hint 1: This is a variant of the subset sum problem. With N ≤ 20, we can enumerate all 2^N subsets.

Hint 2: For each subset (using bitmask 0 to 2^N - 1), compute its sum and track the minimum absolute value.

Hint 3: Optimization: separate positive and negative elements. Use DP: dp[i] = can we achieve sum i? Then find the sum with minimum |sum|.

Solution (Brute Force)

csharp
public int MinAbsSum(int[] A) {
    int N = A.Length;
    long minAbs = long.MaxValue;

    // Enumerate all 2^N subsets using bitmask
    for (int mask = 0; mask < (1 << N); mask++) {
        long sum = 0;
        for (int i = 0; i < N; i++) {
            if ((mask & (1 << i)) != 0) {
                sum += A[i];
            }
        }
        minAbs = Math.Min(minAbs, Math.Abs(sum));
    }

    return (int)minAbs;
}

// Trace Example: A = [1, 5, 2, -6]
// mask=0 ({}): sum=0, |0|=0 → minAbs=0
// (No need to check further; we found 0)
// Return 0 ✓

Solution (DP Optimization)

For larger constraints, use DP to find all achievable sums efficiently:

csharp
public int MinAbsSumDP(int[] A) {
    // Separate positive and negative
    long posSum = 0, negSum = 0;
    foreach (int x in A) {
        if (x > 0) posSum += x;
        else negSum += -x;
    }

    // DP: achievable[sum] = true if we can make that sum
    long target = posSum + negSum;
    bool[] achievable = new bool[target + 1];
    achievable[0] = true;

    // Build DP for positive numbers
    foreach (int x in A) {
        if (x > 0) {
            for (long s = target; s >= x; s--) {
                achievable[s] = achievable[s] || achievable[s - x];
            }
        }
    }

    // Find minimum |sum| where sum is achievable and has
    // a positive contribution from negatives balanced with positives
    long minAbs = target;
    for (long pos = 0; pos <= target; pos++) {
        if (achievable[pos]) {
            long neg = target - pos;
            minAbs = Math.Min(minAbs, Math.Abs(neg - pos));
        }
    }

    return (int)minAbs;
}
💡
Key Insight: With small N (≤20), brute force is simple. For larger N, use DP: find all achievable sums from positive elements, then balance with negative elements. The difference between positive sum and negative sum minimized gives the answer.
EVALUATION

Scoring Guide

Understand how your performance maps to interview readiness.

Points Breakdown

Easy Problem (1 per test)
100 pts
Medium Problem (1 per test)
100 pts
Hard Problem (1 per test)
100 pts
Per Test Total
300 pts

Scoring Thresholds

Score Range Status Interpretation
250–300 Excellent You're ready. All problems solved or very close. You should pass the real round.
210–249 Good Strong performance. Easy + Medium complete, Hard partially done. Likely to pass.
150–209 Fair Mixed results. Easy complete, Medium partially. Study the medium-difficulty patterns more.
100–149 Needs Work Only Easy problem solved per test. Review algorithms and practice more before attempting real round.
<100 Insufficient Not ready. Return to fundamentals. Study arrays, hashing, basic DP before retrying.

How to Score Your Test

1
For each problem: does your solution compile and pass all provided examples? Full points (100) if yes. Partial credit (50) if it solves some cases but not all or has edge case bugs.
2
Check for time/space limits: does it run in reasonable time? Codility typically allows 1–2 seconds. If your solution TLEs on large inputs, deduct 25 points.
3
Code quality matters: is it readable, properly formatted, with comments? Interviewers value clarity. If solution is unreadable, deduct 10 points.
4
Sum all three problems (Easy + Medium + Hard) to get your test score out of 300.
📊
Pass Threshold: Toptal typically requires 210/300 (70%) to advance. Aim for that as your minimum target.

After Each Test

💡
Review & Iterate: After scoring, review the provided solutions. Identify where you went wrong: logic error? edge case missed? time complexity wrong? Document these lessons. Wait 1–2 days, then attempt the next test with these insights fresh in mind.
FINAL TIPS

Maximize Your Practice

🚀
Good luck! These mock tests are as close as you can get to the real Toptal interview without being in the actual room. Trust your preparation, manage your time, and execute cleanly. You've got this.