Skip to content

Instantly share code, notes, and snippets.

@Prajwalprakash3722
Created April 21, 2023 11:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Prajwalprakash3722/be9098b5204358473852f61b3aec41de to your computer and use it in GitHub Desktop.
Save Prajwalprakash3722/be9098b5204358473852f61b3aec41de to your computer and use it in GitHub Desktop.
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