Find the nearest free slot in the temporary array

I am working on a queue system for the clinic. The person at the front desk has two options for adding patients to the queue.

  • Patients with fixed appointments
  • Pleasure Patients

So, for example, there are already four patients in the queue, my existing array of appointments looks like

existing_appointments = ["09:30", "10:00", "12:15", "13:45"];

And the average scan time for a patient is 15 minutes.

avg_wait_per_patient = 15;

As soon as the patient enters, I will find for him the best available time interval.

Say it is now 09:00

current_time = "09:00";

The following function find_free_slot()does not work, because it returns 09:15 instead of 09:00, since there is no destination in this slot.

, current_time + avg_wait_per_patient, current_time. , , , . , last_index_of_array + avg_wait.

function toMinutes(t) {
    return 60 * Number(t.split(":")[0]) + Number(t.split(":")[1]);
}
function reverse_toMinutes(t) {
    return ("0" + Math.floor(t / 60)).slice(-2) + ":" + ("0" + t % 60).slice(-2);
}
function find_free_slot(ct,appointments,avg_wait) {
    ct = toMinutes(ct);
    free_slot = '';
    if(appointments.length==0) {
        free_slot = ct;
    } else {
        for(i=0; i<appointments.length; i++) {
            appointment = toMinutes(appointments[i]);
            if(free_slot <= appointment - avg_wait) {
                i == 0 ?
                    free_slot = ct + avg_wait :
                    free_slot = toMinutes(appointments[i - 1]) + avg_wait;
                break;
            }
        }   
    }
    return reverse_toMinutes(free_slot);
}

jsfiddle

+4
4

:

i == 0 ?
    free_slot = ct + avg_wait :
    free_slot = toMinutes(appointments[i - 1]) + avg_wait;

(9:30) <= (9:30 - 15), ct + avg_wait, 9:00 + 15.

, :

function toMinutes(t) {
  return 60 * Number(t.split(":")[0]) + Number(t.split(":")[1]);
}

function reverse_toMinutes(t) {
  return ("0" + Math.floor(t / 60)).slice(-2) + ":" + ("0" + t % 60).slice(-2);
}

function find_free_slot(ct, appointments, avg_wait) {
  ct = toMinutes(ct);
  free_slot = ct;   // The first slot you want to check is "right now"

  if (appointments.length == 0)
    return reverse_toMinutes(ct);

  for (i = 0; i < appointments.length; i++) {
    appointment = toMinutes(appointments[i]);
    if (ct <= appointment + avg_wait) {        // The appointment must be later than the current appointment end time.
      if (free_slot <= appointment - avg_wait) // Free slot is enough time before the current appointment
        return reverse_toMinutes(free_slot);   // Return the free slot

      free_slot = toMinutes(appointments[i]) + avg_wait; // Otherwise, set the free slot to `avg` after the current appointment, to check the next iteration of the loop.
    }
  }
  return reverse_toMinutes(free_slot); // No free slot has been found, `free_slot` is `last appointment + avg`
}

var appointments = ["09:30", "10:00", "12:15", "13:45"];

console.log(" time - appointment");
console.log(" 9:00 -", find_free_slot("9:00", appointments, 15));
console.log(" 9:15 -", find_free_slot("9:15", appointments, 15));
console.log(" 9:16 -", find_free_slot("9:16", appointments, 15));
console.log(" 9:31 -", find_free_slot("9:31", appointments, 15));
console.log("10:09 -", find_free_slot("10:09", appointments, 15));
console.log("11:59 -", find_free_slot("11:59", appointments, 15));
console.log("12:00 -", find_free_slot("12:00", appointments, 15));
console.log("12:01 -", find_free_slot("12:01", appointments, 15));
Hide result
+4

, , .

true, , , , .

function getMinutes(t) {
    var p = t.split(':');
    return 60 * p[0] + +p[1];
}

function find_free_slot(current_time) {
    var next_time = getMinutes(current_time);

    existing_appointments.some(function (a) {
        var minutes = getMinutes(a);
        if (next_time + avg_wait_per_patient <= minutes) {
            return true;
        }
        next_time = minutes + avg_wait_per_patient >= next_time  ? minutes + avg_wait_per_patient : next_time;
    });
    return ('0' + Math.floor(next_time / 60)).slice(-2) + ':' + ('0' +  next_time % 60).slice(-2);
}

var existing_appointments = ["09:30", "10:00", "12:15", "13:45"],
    avg_wait_per_patient = 15;

console.log(find_free_slot('09:00')); // 09:00
console.log(find_free_slot('09:15')); // 09:15
console.log(find_free_slot('09:16')); // 09:45
console.log(find_free_slot('09:45')); // 09:45
console.log(find_free_slot('09:46')); // 10:15
console.log(find_free_slot('10:00')); // 10:15
console.log(find_free_slot('10:09')); // 10:15
console.log(find_free_slot('11:59')); // 11:59
console.log(find_free_slot('12:00')); // 12:00
console.log(find_free_slot('12:01')); // 12:30
Hide result
0

I made some changes, now everything is in order, you may also need to close_time and start_time.

function toMinutes(t) {
	return 60 * Number(t.split(":")[0]) + Number(t.split(":")[1]);
}
function reverse_toMinutes(t) {
	return ("0" + Math.floor(t / 60)).slice(-2) + ":" + ("0" + t % 60).slice(-2);
}

var existing_appointments = ["09:30", "10:00", "12:55", "13:45"];
var avg_wait_per_patient = 15; // in minutes
var current_time = "10:00";

function find_free_slot(ct,appointments,avg_wait) {
	ct = toMinutes(ct);
	var free_slot = '';
   
	if(appointments.length==0) {
		free_slot = ct;
	}
  else if (appointments.length==1) {
  	free_slot = toMinutes(appointments[0])+avg_wait;
	}  
  else {
    var i=0;
  	for (i=1;i<appointments.length;i++){
    	if (toMinutes(appointments[i])-toMinutes(appointments[i-1])>=2*avg_wait){
      	free_slot=toMinutes(appointments[i-1])+avg_wait;
            break;
        }    
      }
	}
  
  if (free_slot=='') free_slot=toMinutes(appointments[appointments.length-1])+avg_wait;

	return reverse_toMinutes(free_slot);
}

document.write( find_free_slot(current_time,existing_appointments,avg_wait_per_patient) );
Run codeHide result
-1
source

I suggest you use the momentjs library to perform such calculations and formatting. Here is an example of how to achieve what you want using the moment.

function find_free_slot(ct,appointments,avg_wait) {
  existing_appointments.sort((a,b) => a-b);
  let possibleSlot = ct;
  for(let i=0; i<appointments.length; i++) {
    const a = appointments[i];
    if(a >= +possibleSlot + (avg_wait * 60000)) {
      appointments.splice(i, 0, possibleSlot);
      return possibleSlot;
    }
    const endOfCurrentSlot = a.clone().add(avg_wait,'minute');
    if(endOfCurrentSlot > possibleSlot) {
      possibleSlot = endOfCurrentSlot;
    }
  }
  appointments.push(possibleSlot);
  return possibleSlot;
  
}

const existing_appointments = [
  moment('09:30','HH:mm'),
  moment('10:00','HH:mm'),
  moment('13:45','HH:mm')
];
const avg_wait_per_patient = 15; // in minutes

function getSlotStr(time) {
  var slot = find_free_slot(time, existing_appointments, avg_wait_per_patient);
  return time.format('HH:mm') + ' --> ' + slot.format('HH:mm');
}

document.write( getSlotStr(moment('09:00','HH:mm')) + '<br />');
document.write( getSlotStr(moment('09:10','HH:mm')) + '<br />');
document.write( getSlotStr(moment('09:20','HH:mm')) + '<br />');
document.write( getSlotStr(moment('09:30','HH:mm')) + '<br />');
document.write( getSlotStr(moment('09:40','HH:mm')) + '<br />');
document.write( getSlotStr(moment('10:10','HH:mm')) + '<br />');
document.write( getSlotStr(moment('13:00','HH:mm')) + '<br />');
document.write( getSlotStr(moment('13:40','HH:mm')) + '<br />');
document.write( getSlotStr(moment('13:50','HH:mm')) + '<br />');
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.17.1/moment.min.js"></script>
Run codeHide result
-1
source

Source: https://habr.com/ru/post/1670035/


All Articles