Codility passing car - how to approach this problem
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
The Codility Passing Cars problem looks like a pair-counting problem, but the direct nested-loop approach is too slow for large inputs. The key observation is that every westbound car passes all eastbound cars that appeared earlier in the array. Once you see that, the solution becomes a simple linear scan.
Understand the Pair Definition
The array contains only two values:
- '
0means a car traveling east' - '
1means a car traveling west'
A passing pair is any index pair (P, Q) where:
- '
P < Q' - '
A[P] == 0' - '
A[Q] == 1'
So every time you encounter a 1, you want to know how many 0 values appeared before it.
That suggests a running counter rather than a brute-force comparison of every pair.
The Linear-Time Idea
Keep two variables:
- '
east_count: how many eastbound cars have been seen so far' - '
pairs: total number of passing pairs so far'
Then scan left to right:
- if the current value is
0, incrementeast_count - if the current value is
1, addeast_counttopairs
That works because each westbound car forms a passing pair with every earlier eastbound car.
Python Implementation
For the example [0, 1, 0, 1, 1], the answer is 5.
The passing pairs are:
- first
0with first1 - first
0with second1 - first
0with third1 - second
0with second1 - second
0with third1
Why This Is Better Than Nested Loops
A brute-force solution would test every pair of positions, which takes O(n^2) time.
For large arrays, that is too slow.
The running-counter solution touches each element once, so it runs in O(n) time and uses O(1) extra space.
That is exactly the kind of optimization interview and coding-platform problems are usually looking for: identify the cumulative information you need and update it incrementally.
Walk Through the Example
Take:
Step by step:
- see
0, soeast_count = 1 - see
1, sopairs += 1, nowpairs = 1 - see
0, soeast_count = 2 - see
1, sopairs += 2, nowpairs = 3 - see
1, sopairs += 2, nowpairs = 5
Done.
The trick is that the earlier eastbound cars do not need to be revisited. Their contribution is summarized in east_count.
Handling the Limit Condition
Codility adds one more rule: if the number of passing pairs exceeds 1,000,000,000, return -1.
That is easy to incorporate during the scan:
Doing this check as you go is cleaner than computing an enormous count first and checking later.
A More Formal View
You can think of the algorithm as counting inversions of a special kind. But you do not need a full inversion-counting algorithm because the array values are only 0 and 1.
The binary nature of the input simplifies the problem dramatically:
- all you need to remember is how many
0s have appeared - every
1consumes that count immediately
This is why the linear pass is enough.
Edge Cases
A few edge cases are worth checking mentally:
- all
0s, answer is0 - all
1s, answer is0 - empty array, answer is
0 - one eastbound car followed by many westbound cars, answer grows quickly
Example:
The logic handles all of these naturally.
Common Pitfalls
The biggest pitfall is reaching for nested loops immediately. They are easy to write and too slow.
Another issue is counting westbound cars first and then trying to reason backward, which usually complicates the logic unnecessarily.
Developers also sometimes forget the overflow-style rule that requires returning -1 after 1,000,000,000 pairs.
Finally, be clear that the pair must satisfy P < Q. The order in the array matters.
Summary
- Count eastbound cars as you scan from left to right.
- Every westbound car adds one passing pair for each earlier eastbound car.
- This gives an
O(n)time,O(1)space solution. - Check the
1,000,000,000limit during the scan and return-1if exceeded. - The core insight is to replace explicit pair testing with a running count of earlier
0values.

