Program to count minimum semesters to cover all different courses in Python

Suppose we have a number n, indicating that there are n different courses labeled from 1 to n. We also have an array called relations where relations[i] contains a pair (prevCourse_i, nextCourse_i), representing a prerequisite relationship between the course prevCourse_i and the course nextCourse_i: so course prevCourse_i has to be taken before the course nextCourse_i. The last parameter we have is k. In one semester, we can take at most k number of courses as long as we have taken all the prerequisites in the previous semester for the courses we are taking. We have to find the minimum number of semesters needed to take all courses.

Problem Understanding

Given the example with 6 courses and relations [(1,3), (2,5), (2,4), (5,6)] with k=2:

1 2 3 4 5 6 Semester 1: Blue | Semester 2: Red | Semester 3: Orange

The output will be 3 because in the first semester we can take courses 1 and 2, now we are eligible for courses 3, 4 and 5. If we take 5 and any one of 3 or 4 for the second semester, then we can end all courses in the next semester. So we need 3 semesters in total.

Algorithm Approach

To solve this, we will follow these steps:

  • Build a graph to represent course dependencies

  • Use topological sorting with priority to handle the k constraint

  • Simulate semester-by-semester course taking

  • Count the minimum semesters required

Implementation

def solve(n, relations, k):
    taken = set()
    # g1[i] stores prerequisites for course i
    g1 = [[] for _ in range(n)]
    # g2[i] stores courses that depend on course i
    g2 = [[] for _ in range(n)]
    w = [0] * n
    semester = 0
    
    # Build the dependency graph
    for x in relations:
        g1[x[1]-1].append(x[0]-1)
        g2[x[0]-1].append(x[1]-1)

    # Calculate weights (number of prerequisites)
    weight = list(map(len, g1))
    for i in range(n):
        for x in g1[i]:
            w[x] = max(w[x], weight[i])

    # Simulate semester by semester
    while len(taken) < n:
        courses = []
        
        # Find available courses (no prerequisites left)
        for i in range(n):
            if (not g1[i]) and (i not in taken):
                courses.append([i, w[i]])
        
        # If more courses available than k, prioritize by weight
        if len(courses) > k:
            courses = sorted(courses, key=lambda x: x[1], reverse=True)
            courses = courses[:k]

        semester += 1

        # Take the selected courses
        for x in courses:
            # Remove this course as prerequisite from dependent courses
            for y in g2[x[0]]:
                g1[y].remove(x[0])
            g2[x[0]] = []
            taken.add(x[0])
    
    return semester

# Test the function
n = 6
relations = [(1,3), (2,5), (2,4), (5,6)]
k = 2
print(solve(n, relations, k))
3

How It Works

The algorithm works by:

  1. Graph Construction: Creates adjacency lists for prerequisites (g1) and dependents (g2)

  2. Weight Calculation: Assigns weights based on the number of courses that depend on each course

  3. Semester Simulation: In each semester, finds courses with no remaining prerequisites

  4. Priority Selection: If more than k courses are available, selects k courses with highest weights

  5. Dependency Update: Removes completed courses from prerequisite lists of dependent courses

Example Walkthrough

For n=6, relations=[(1,3), (2,5), (2,4), (5,6)], k=2:

  • Semester 1: Courses 1 and 2 have no prerequisites ? take both

  • Semester 2: Courses 3, 4, 5 become available ? take 5 and one of 3/4 (limited by k=2)

  • Semester 3: Take remaining courses including course 6

Conclusion

This solution uses topological sorting with capacity constraints to find the minimum semesters needed. The algorithm efficiently handles prerequisite dependencies while respecting the maximum courses per semester limit.

Updated on: 2026-03-26T14:03:39+05:30

485 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements