Article Categories
- All Categories
-
Data Structure
-
Networking
-
RDBMS
-
Operating System
-
Java
-
MS Excel
-
iOS
-
HTML
-
CSS
-
Android
-
Python
-
C Programming
-
C++
-
C#
-
MongoDB
-
MySQL
-
Javascript
-
PHP
-
Economics & Finance
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:
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:
Graph Construction: Creates adjacency lists for prerequisites (g1) and dependents (g2)
Weight Calculation: Assigns weights based on the number of courses that depend on each course
Semester Simulation: In each semester, finds courses with no remaining prerequisites
Priority Selection: If more than k courses are available, selects k courses with highest weights
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.
