I just finished a small assignment and I would like to get some feedback about the implementation here. Basically, it was all about distributing items ("talks" in this case) throughout the day based on the time constraints (their duration). For instance, a given place have different "tracks" each of which has a morning (9AM - 12PM) and afternoon (1PM - 5PM) session.
The input data is a file with this structure:
Talk Name XYmin
(whereXY
are positive numbers).
This is what I came up with (I know it's a little bit silly but I guess it works for the most part):
public final class Conference {
private static final long MORNING_SPAN = 180; // 09:00 AM - 12:00PM
private static final long AFTERNOON_SPAN = 240; // 01:00 PM - 05:00 PM
private final List<Talk> talks;
private final List<Track> tracks;
private final long numberOfTracks;
public Conference(final List<Talk> talks) {
final var duration = talks.stream().mapToLong(Talk::duration).sum();
final var daySpan = MORNING_SPAN + AFTERNOON_SPAN;
this.talks = talks;
numberOfTracks = duration / daySpan + (duration % daySpan == 0L ? 0L : 1L);
tracks = new LinkedList<>();
}
public List<Track> getTracks() { return tracks; }
public void displaySchedule() {
if (tracks.isEmpty()) {
makeSchedule();
}
// More System.out.println statements for the required output
}
private void makeSchedule() { // ...this one is the deal!
for (int i = 0; i < numberOfTracks; i++) {
final var morning = new LinkedList<Talk>();
final var afternoon = new LinkedList<Talk>();
var morningSpan = MORNING_SPAN;
var afternoonSpan = AFTERNOON_SPAN;
final var iterator = talks.iterator();
while (iterator.hasNext()) {
final var talk = iterator.next();
if (talk.duration() <= morningSpan) {
morning.add(talk);
morningSpan -= talk.duration();
iterator.remove();
} else if (talk.duration() <= afternoonSpan) {
afternoon.add(talk);
afternoonSpan -= talk.duration();
iterator.remove();
}
}
tracks.add(new Track(morning, afternoon));
}
}
}
public final class Talk {
public final String title;
public final String duration;
public Talk(final String title, final String duration) {
this.title = title;
this.duration = duration;
}
public long duration() {
if ("lightning".equalsIgnoreCase(duration)) {
return Constant.LIGHTNING;
}
// Basically this returns the duration for the talk (as long)...that's it
return Long.parseLong(Constant.NON_NUMBERS.matcher(duration).replaceAll(""));
}
}
public final class Track {
private final List<Talk> morning;
private final List<Talk> afternoon;
public Track(final List<Talk> morning, final List<Talk> afternoon) {
this.morning = morning;
this.afternoon = afternoon;
}
// Some more stuff here to display the required output
}
The real deal here is Conference::makeSchedule
— that's where I would like to know if there is a better, more efficient way to approach this solution...probably using different data structures, etc. Thanks in advance!