Created
April 21, 2023 11:42
-
-
Save Prajwalprakash3722/be9098b5204358473852f61b3aec41de to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"fmt" | |
"math/rand" | |
"sync" | |
"time" | |
) | |
// Course struct | |
type Course struct { | |
name string | |
capacity int | |
regCounter int | |
regStudents []int | |
} | |
// CourseSystem struct | |
// to access this struct you need to acquire a lock | |
type CourseSystem struct { | |
courses map[string]*Course | |
mutex sync.Mutex | |
} | |
// Registers a dummy student for a course. | |
func (c *Course) Register(studentID int) bool { | |
if c.regCounter < c.capacity { | |
c.regCounter++ | |
c.regStudents = append(c.regStudents, studentID) | |
return true | |
} | |
return false | |
} | |
// GetCourse returns a course from the course system. | |
func (cs *CourseSystem) GetCourse(courseName string) *Course { | |
cs.mutex.Lock() | |
defer cs.mutex.Unlock() | |
return cs.courses[courseName] | |
} | |
// AddCourse adds a course to the course system. | |
func (cs *CourseSystem) AddCourse(course *Course) { | |
cs.mutex.Lock() | |
defer cs.mutex.Unlock() | |
cs.courses[course.name] = course | |
} | |
// registerStudentWithFallback tries to register a student for a course until it succeeds, if not then no course is registered. | |
func registerStudentWithFallback(studentID int, courseNames []string, cs *CourseSystem) { | |
remainingCourses := courseNames | |
for len(remainingCourses) > 0 { | |
// Randomly select a course to register for from the remaining courses. | |
courseIndex := rand.Intn(len(remainingCourses)) | |
courseName := remainingCourses[courseIndex] | |
// Try to register for the course. | |
success := registerStudent(studentID, courseName, cs) | |
if success { | |
fmt.Printf("Student %d registered for %s.\n", studentID, courseName) | |
return | |
} | |
// If the registration was not successful, remove the course from the list of remaining courses. | |
remainingCourses = append(remainingCourses[:courseIndex], remainingCourses[courseIndex+1:]...) | |
} | |
fmt.Printf("Student %d could not register for any course.\n", studentID) | |
} | |
// selectNewCourse selects a new course randomly from the remaining courses. | |
func selectNewCourse(courseNames []string, currentCourse string) string { | |
remainingCourses := make([]string, 0, len(courseNames)-1) | |
for _, c := range courseNames { | |
// We don't want to try the same course again. | |
if c != currentCourse { | |
remainingCourses = append(remainingCourses, c) | |
} | |
} | |
if len(remainingCourses) == 0 { | |
// If there are no more courses to try, give up. | |
return "" | |
} | |
return remainingCourses[rand.Intn(len(remainingCourses))] | |
} | |
// registerStudent tries to register a student for a course. | |
// Returns true if successful, false otherwise. | |
func registerStudent(studentID int, courseName string, cs *CourseSystem) bool { | |
c := cs.GetCourse(courseName) | |
if c == nil { | |
fmt.Printf("Course %s not found.\n", courseName) | |
return false | |
} | |
if c.Register(studentID) { | |
return true | |
} | |
fmt.Printf("Student %d could not register for %s (course full).\n", studentID, courseName) | |
return false | |
} | |
func main() { | |
cs := &CourseSystem{ | |
courses: make(map[string]*Course), | |
} | |
totalStudents := 25 | |
allotedStudents := 0 | |
cs.AddCourse(&Course{name: "Diaster Management", capacity: 10}) | |
cs.AddCourse(&Course{name: "System Engineering", capacity: 10}) | |
cs.AddCourse(&Course{name: "Mathematical Modelling", capacity: 2}) | |
simulateRegistration(totalStudents, []string{"Diaster Management", "System Engineering", "Mathematical Modelling"}, cs) | |
for _, c := range cs.courses { | |
fmt.Printf("Total Students registeted for %s: %d\n", c.name, len(c.regStudents)) | |
allotedStudents += len(c.regStudents) | |
} | |
fmt.Printf("Total Students alloted / Total Students: %d/%d\n", allotedStudents, totalStudents) | |
} | |
func simulateRegistration(numStudents int, courseNames []string, cs *CourseSystem) { | |
var wg sync.WaitGroup | |
for i := 1; i <= numStudents; i++ { | |
wg.Add(1) | |
go func(n int) { | |
defer wg.Done() | |
registerStudentWithFallback(n, courseNames, cs) | |
}(i) | |
time.Sleep(10 * time.Millisecond) // introduce a small delay to simulate concurrent requests | |
} | |
wg.Wait() | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment