Panda Guru LogoPanda
Guru

Zomato SDE interview | Machine coding Alarm Clock

Round 1

Questions: Design an alarm clock with the following functions:

Write a program that, upon matching alarm times, the system should print "Wake Up".

Solution:

package main import ( "fmt" "time" ) type AlarmClock struct { alarms map[string]time.Time } // NewAlarmClock creates a new AlarmClock instance. func NewAlarmClock() *AlarmClock { return &AlarmClock{ alarms: make(map[string]time.Time), } } // AddAlarm adds a new alarm to the clock. func (ac *AlarmClock) AddAlarm(label string, alarmTime time.Time) { ac.alarms[label] = alarmTime fmt.Printf("Added alarm \'%s\' at %s\n", label, alarmTime.Format("15:04:05")) } // DeleteAlarm deletes an alarm from the clock. func (ac *AlarmClock) DeleteAlarm(label string) { if _, exists := ac.alarms[label]; exists { delete(ac.alarms, label) fmt.Printf("Deleted alarm \'%s\'\n", label) } else { fmt.Printf("Alarm \'%s\' does not exist\n", label) } } // UpdateAlarm updates an existing alarm to a new time. func (ac *AlarmClock) UpdateAlarm(label string, newTime time.Time) { if _, exists := ac.alarms[label]; exists { ac.alarms[label] = newTime fmt.Printf("Updated alarm \'%s\' to %s\n", label, newTime.Format("15:04:05")) } else { fmt.Printf("Alarm \'%s\' does not exist\n", label) } } // Snooze snoozes an alarm by adding a delay. func (ac *AlarmClock) Snooze(label string, delay time.Duration) { if alarmTime, exists := ac.alarms[label]; exists { newTime := alarmTime.Add(delay) ac.alarms[label] = newTime fmt.Printf("Snoozed alarm \'%s\' to %s\n", label, newTime.Format("15:04:05")) } else { fmt.Printf("Alarm \'%s\' does not exist\n", label) } } // Start checks for matching alarm times and prints "Wake Up". func (ac *AlarmClock) Start() { for { for label, alarmTime := range ac.alarms { if time.Now().After(alarmTime) { fmt.Printf("Wake Up! Alarm \'%s\' triggered at %s\n", label, alarmTime.Format("15:04:05")) delete(ac.alarms, label) // Remove the alarm after it triggers } } time.Sleep(1 * time.Second) } } func main() { ac := NewAlarmClock() // Add some alarms ac.AddAlarm("Morning Alarm", time.Now().Add(5*time.Second)) ac.AddAlarm("Meeting Reminder", time.Now().Add(10*time.Second)) // Update an alarm ac.UpdateAlarm("Morning Alarm", time.Now().Add(8*time.Second)) // Snooze an alarm ac.Snooze("Meeting Reminder", 5*time.Second) // Start the alarm clock go ac.Start() // Keep the main function alive select {} }

Follow-up Questions:

  1. The interviewer asked about the infinite loop and suggested improvements. I mentioned using a min heap to pull the next minimum alarm time and sleep until the next alarm. If an existing alarm is updated or snoozed, we would need to reset the sleep time if the updated alarm becomes the new minimum time.
  2. Feedback from the interviewer indicated that the expectation was to use the OS scheduler for the next trigger instead of time.Sleep(), explaining that this is how cron jobs work.
Candidate's Approach

The candidate proposed using a min heap to manage alarm times efficiently, allowing the program to sleep until the next alarm triggers. This approach would optimize the infinite loop by reducing unnecessary checks.

Interviewer's Feedback

The interviewer suggested that the candidate should consider using the OS scheduler for triggering alarms, similar to how cron jobs operate, rather than relying on time.Sleep().