Skip to content

Instantly share code, notes, and snippets.

@toanpv
Last active September 12, 2024 16:46
Show Gist options
  • Save toanpv/1a965c239107463658d8a5839a7ea86c to your computer and use it in GitHub Desktop.
Save toanpv/1a965c239107463658d8a5839a7ea86c to your computer and use it in GitHub Desktop.

Case Study 1

Question 1:

In a typical scenario, the countdown should begin when the doctor starts seeing the first patient in the queue. However, to improve the user experience, we can implement a more dynamic approach:

Since we know the time when the doctor starts seeing patients and the user's position in the queue, we can display a countdown in the UI that reflects this information.

  • UI Enhancement: We can show both the current queue index and the user’s position in the queue. This will give the user a clearer understanding of whether the doctor has started seeing patients and how many remain before their turn.

Additionally, to manage user expectations, we could:

  • Tooltip: Add an information icon next to the countdown text. When clicked, it can display a tooltip explaining that the countdown may change due to factors like emergencies. This tooltip can be highlighted the first time a user engages with the online queue feature.
  • Alternative: Show a brief description below the countdown text, such as "Estimated time may vary due to unexpected delays."

The answer for this question is that the countdown should begin right when the user queues online, with a well-considered UI/UX approach.

Question 2:

To calculate John’s estimated waiting time based on Peter’s current consultation, we can use the following formula:

  • Definitions:

    • consultingPatientIndex: The index of the patient currently being seen (Peter).
    • AVG_TIME: The average consultation time per patient (3 minutes).
    • userQueueIndex: John’s position in the queue.
    • actualCurrentPatientTime: The actual time Peter has spent in the consultation room.
    • totalPatients: The total number of patients in the queue.
  • Formula: waitingTime = (userQueueIndex - consultingPatientIndex - 1) * AVG_TIME + max(AVG_TIME - actualCurrentPatientTime, 0)

  • Explanation:

    • (userQueueIndex - consultingPatientIndex - 1) calculates how many patients are between John and Peter.
    • max(AVG_TIME - actualCurrentPatientTime, 0) ensures that if Peter finishes early, the waiting time doesn't become negative.

This formula accurately reflects the remaining waiting time for John based on the current status of Peter's consultation.

Applying the above formula, assuming Peter is the 3rd patient currently being consulted for:

  • (a) 2 minutes => waitingTime = (6 - 3 - 1) * 3 + max(3 - 2, 0) = 7 minutes
  • (b) 5 minutes => waitingTime = (6 - 3 - 1) * 3 + max(3 - 5, 0) = 6 minutes

Case Study 2

Honestly, I haven’t found a mathematical formula to calculate the waiting time for the nth patient yet, so I used a programming algorithm to solve the problem instead.

My approach simulates the allocation of patients to doctors based on their average consultation times. From this, I determine which doctor will see patient N and the time they need to wait before their turn from the moment the doctors start working.

This algorithm can address both questions with comments to explaint the logic.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
Question 1 Case 1 Doctor A 1 1 1 3 3 3 5 5 5 7 7 7 8 8 8 10 10 10
Doctor B 2 2 2 2 4 4 4 4 6 6 6 6 9 9 9 9 11 11 11 11
Question 1 Case 2 Doctor A 1 1 1 3 3 3 5 5 5 7 7 7 9 9 9 10 10 10
Doctor B 2 2 2 2 4 4 4 4 6 6 6 6 8 8 8 8 11 11 11 11
Question 2 Doctor A 2 2 2 4 4 4 6 6 6 7 7 7 9 9 9 11 11 11
Doctor B 1 1 1 1 3 3 3 3 5 5 5 5 8 8 8 8 10 10 10 10

Question 1:

Patient 11 will be seen by Doctor B. The estimated waiting time is 16 minutes, after 4 other patients.

Question 2:

Assuming when John joins the queue, Doctor B has already been consulting patient Lucas for 2 minutes, and Doctor A starts working:

The result is that Patient 11 will be seen by Doctor A, and the estimated waiting time is 15 minutes, after 5 other patients.

Please review the algorithm written in Kotlin and the functions provided for both Question 1 and Question 2.

import java.util.PriorityQueue
data class Doctor(val name: String, val consultationTime: Int, var endTime: Int = 0)
data class Patient(val index: Int, val startTime: Int)
data class Appointment(
val doctorIndex: Int,
var endTime: Int,
var patientsSeen: Int = 0,
var patientIndex: Int = 0
)
class AppointmentAllocator {
fun scheduleAppointmentForPatient(
doctors: List<Doctor>, patientNumber: Int
): Appointment? {
// Priority queue (min-heap) to track doctors' availability (earliest available doctor)
val heap = PriorityQueue<Appointment>(compareBy { it.endTime })
// Initialize the heap with each doctor available at time 0 and with no patients seen yet
doctors.forEachIndexed { index, doctor ->
heap.add(Appointment(index, doctor.endTime, 0, 0))
}
var currentTime = 0
var lastDoctorIndex: Int
var result: Appointment? = null
// Iterate over patients to assign them to doctors
for (patientIndex in 1..patientNumber) {
// Find the next available doctor
val nextAvailableDoctor = heap.poll()
if (nextAvailableDoctor != null) {
result = nextAvailableDoctor.copy()
// Update the current time to the doctor's next available time
currentTime = maxOf(currentTime, nextAvailableDoctor.endTime)
// Assign the patient to this doctor
lastDoctorIndex = nextAvailableDoctor.doctorIndex
// Increase the number of patients this doctor has seen
nextAvailableDoctor.patientsSeen += 1
result.patientIndex = patientIndex
// Calculate when the doctor will finish with this patient and add back to the queue
nextAvailableDoctor.endTime =
currentTime + doctors[lastDoctorIndex].consultationTime
heap.add(nextAvailableDoctor)
}
}
// Return the doctor name, the time, and the number of patients the doctor has seen
return result
}
}
fun main() {
val patientNumber = 11
//Question 1:
val doctors = listOf(
Doctor("Doctor A", 3),
Doctor("Doctor B", 4)
)
AppointmentAllocator().scheduleAppointmentForPatient(doctors, patientNumber = patientNumber)
?.let {
println(
"Patient ${it.patientIndex} will see Dr. ${doctors[it.doctorIndex].name} next. " +
"Please expect a wait of ${it.endTime} minutes after ${it.patientsSeen} other patients."
)
}
//Question 2:
val doctors2 = listOf(
Doctor("Doctor A", 3, 2),
Doctor("Doctor B", 4)
)
AppointmentAllocator().scheduleAppointmentForPatient(doctors2, patientNumber = patientNumber)
?.let {
println(
"Patient ${it.patientIndex} will see Dr. ${doctors[it.doctorIndex].name} next. " +
"Please expect a wait of ${it.endTime - doctors2[0].endTime} minutes after ${it.patientsSeen} other patients."
)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment