Monday, January 8, 2024

Passing Cars (Count the number of passing cars on the road) - Problem on Prefix Sums

Passing Cars
Count the number of passing cars on the road.
Problem on Prefix Sums

Problem

A non-empty array A consisting of N integers is given. The consecutive elements of array A represent consecutive cars on a road.

Array A contains only 0s and/or 1s:

0 represents a car traveling east,

1 represents a car traveling west.

The goal is to count passing cars. We say that a pair of cars (P, Q), where 0 ≤ P < Q < N, is passing when P is traveling to the east and Q is traveling to the west.

Write a function:

def solution(A)

that, given a non-empty array A of N integers, returns the number of pairs of passing cars.

The function should return −1 if the number of pairs of passing cars exceeds 1,000,000,000.

Write an efficient algorithm for the following assumptions:

N is an integer within the range [1..100,000];

each element of array A is an integer that can have one of the following values: 0, 1.

Example

For example, consider array A such that:

A[0] = 0

A[1] = 1

A[2] = 0

A[3] = 1

A[4] = 1

We have five pairs of passing cars: (0, 1), (0, 3), (0, 4), (2, 3), (2, 4).

For example, given:

the function should return 5, as explained above.

Hint

Code (I)

def solution(A):
    # In the question, it is given that 0 are travelling east. We assume it to be the direction of prefix sums.
    # So if we implement using prefix counts, we would have to count zeroes.

    # '1' is going to the west, that is having the direction of suffix sums.

    prefix_counts = [0] * (len(A) + 1)

    for i in range(len(A)):
        if A[i] == 0:
            prefix_counts[i+1] = prefix_counts[i] + 1
        else:
            prefix_counts[i+1] = prefix_counts[i] + 0

    passing_cars = 0 
    for i in range(len(A)):
        if A[i] == 1:
            passing_cars += prefix_counts[i+1]

    if passing_cars > 1000000000:
        passing_cars = -1

    return passing_cars

Code (II): Now Using Suffix Sums

def solution(A):
    # In the question, it is given that 0 are traveling east. We assume it to be the direction of prefix sums.

    # '1' is going to the west, that is having the direction of suffix sums.
    # So if we implement using suffix counts, we would have to count ones.

    suffix_counts = [0] * (len(A) + 1)

    for i in range(len(A) - 1, -1, -1):
        if A[i] == 1:
            suffix_counts[i] = suffix_counts[i+1] + 1
        else:
            suffix_counts[i] = suffix_counts[i+1] + 0

    passing_cars = 0 
    for i in range(len(A)):
        if A[i] == 0:
            passing_cars += suffix_counts[i]

    if passing_cars > 1000000000:
        passing_cars = -1

    return passing_cars

Time Complexity

Detected time complexity:

O(N)

Tests

Correctness tests

single element

double

two elements

simple

simple test

small_random

random, length = 100

small_random2

random, length = 1000

Performance tests

medium_random

random, length = ~10,000

large_random

random, length = ~100,000

large_big_answer

0..01..1, length = ~100,000

large_alternate

0101..01, length = ~100,000

large_extreme

large test with all 1s/0s, length = ~100,000

No comments:

Post a Comment