public void Report(TextWriter writer, Conductor conductor, Patron patron) { //TODO: also putting a cap on the minutes: 23:59? see example ... var earliestDepartureTimeMinutes = DepartureTimeMinutes + conductor.GetStopIntervalsMinutes(patron).Sum(); writer.WriteLine(earliestDepartureTimeMinutes.FormatMinutes()); }
/// <summary> /// Returns whether the <paramref name="trip"/> CanBeScheduled for the /// <paramref name="patron"/>, taking into consideration any <paramref name="deltas"/> /// incurred by boarding mid-line. /// </summary> /// <param name="trip"></param> /// <param name="patron"></param> /// <param name="deltas"></param> /// <returns></returns> public static bool CanBeScheduled(this Trip trip, Patron patron, GetStopIntervalsMinutesDelegate deltas) { // Deal with these couple of obvious criteria first. if (trip == null || trip.Direction != patron.Direction) return false; var totalDeltaMinutes = deltas(patron).Sum(); /* Now we can deal with the next obvious condition. Do not normalize the Patron time * after all. Not only is this acceptable as-is, I truly don't believe there is a way * for us to know otherwise; unless we wanted to incorporate actual DateTime dates * into the mix. */ return trip.DepartureTimeMinutes + totalDeltaMinutes >= patron.DepartureTimeMinutes; }
private void ScheduleTrip(Patron patron) { Trip last; /* Backfill the schedule until the Patron's request can be fulfilled, * if at all possible given known set of constraints. */ while ((last = _scheduledTrips .Where(t => t.IsNorthbound == patron.IsNorthbound) .OrderBy(t => t.DepartureTimeMinutes).LastOrDefault()) .CannotBeScheduled(patron, GetStopIntervalsMinutes)) { TripConstraint constraint; var nextDepartureTimeMinutes = GetNextDepartureTimeMinutes(last, patron, out constraint); // It is not possible to fulfill the Patron's itinerary given the allowable constraints. if (nextDepartureTimeMinutes == null) break; var trip = new Trip(constraint, nextDepartureTimeMinutes.Value); _scheduledTrips.Add(trip); } // Because Patron may have jumped into the queue midstream. patron.Itinerary = _scheduledTrips.First( t => t.CanBeScheduled(patron, GetStopIntervalsMinutes)); }
// ReSharper disable SuggestBaseTypeForParameter /// <summary> /// /// </summary> /// <param name="trip"></param> /// <param name="patron"></param> /// <param name="constraint"></param> /// <returns></returns> /// <remarks>This was another impacted area where not only calculating the desired /// departure time, but also knowing about the associated constraint, was desirable.</remarks> private int? GetNextDepartureTimeMinutes(Trip trip, Patron patron, out TripConstraint constraint) { // Should work for both Northbound (true/false), inverse of which is Southbound. constraint = Constraints.Single(t => t.IsNorthbound == patron.IsNorthbound); if (trip == null) return constraint.FirstDepartureTimeMinutes; var dtm = trip.DepartureTimeMinutes; // Which closing the loop the refactor should be relatively painless after all. var result = dtm + constraint.Frequencies.GetWaitTimeMinutes(dtm); return result > constraint.MaxAllowableDepartureTimeMinutes ? (int?) null : result; }
/// <summary> /// Returns a collection of stop intervals relevant from the <paramref name="patron"/> /// <see cref="Patron.StopNumber"/> in the appropriate <see cref="IDirectional.IsNorthbound"/>. /// This is a useful callback throughout the approach. /// </summary> /// <param name="patron"></param> /// <returns></returns> internal IEnumerable<int> GetStopIntervalsMinutes(Patron patron) { // No need to subtract one here just pass the StopNumber through in either case. return patron.IsNorthbound ? StopIntervalMinutes.Take(patron.StopNumber) : StopIntervalMinutes.Skip(patron.StopNumber); }
/// <summary> /// Returns whether the <paramref name="trip"/> CannotBeScheduled for the /// <paramref name="patron"/>, taking into consideration any <paramref name="deltas"/> /// incurred by boarding mid-line. /// </summary> /// <param name="trip"></param> /// <param name="patron"></param> /// <param name="deltas"></param> /// <returns></returns> public static bool CannotBeScheduled(this Trip trip, Patron patron, GetStopIntervalsMinutesDelegate deltas) { return !trip.CanBeScheduled(patron, deltas); }
public void Report(TextWriter writer, Conductor conductor, Patron patron) { var earliestDepartureTimeMinutes = DepartureTimeMinutes + conductor.GetStopIntervalsMinutes(patron).Sum(); writer.WriteLine(earliestDepartureTimeMinutes.FormatMinutes()); }