class SolutionWriter: def __init__(self, soln_file): self.w = open(soln_file, 'wt') self.wcsv = csv.writer(self.w) self.wcsv.writerow(['ToyId', 'ElfId', 'StartTime', 'Duration']) self.ref_time = datetime.datetime(2014, 1, 1, 0, 0) self.hours = Hours() def write(self, toy, elf, work_start_time, work_duration): time_string = self.hours.get_time_string(work_start_time) self.wcsv.writerow([toy.id, elf.id, time_string, work_duration]) def close(self): self.w.close()
def solution(toy_file, soln_file, num_elves, TARGET): """ Creates a simple solution where the next available elf is assigned a toy. Elves do not start work outside of sanctioned hours. :param toy_file: filename for toys file (input) :param soln_file: filename for solution file (output) :param myelves: list of elves in a priority queue ordered by next available time :return: """ hrs = Hours() toy_loader = ToyLoader(toy_file) solution_writer = SolutionWriter(soln_file) busy_elves_heap = BusyElvesHeap(num_elves) elves_ready = ElvesReady() scheduler = Scheduler(TARGET, num_elves) start = time.time() current_time = 497340 print("Getting initial toys") print('time taken = {0}, current_time = {1}'.format(time.time() - start, hrs.get_time_string(current_time))) new_toy_orders = toy_loader.get_toys_up_to_minute(current_time) print("Loading initial toys into backlog") print('time taken = {0}, current_time = {1}'.format(time.time() - start, hrs.get_time_string(current_time))) toy_backlog = ToyBacklogV2(new_toy_orders) print("Finished initializing toys into backlog") print('time taken = {0}, current_time = {1}'.format(time.time() - start, hrs.get_time_string(current_time))) toys_finished = 0 toys_left_at_end = [] time_of_last_toy_assigned = current_time while not (toy_loader.done() and toy_backlog.done() and len(toys_left_at_end) == 0): # step 1 process newly arrived toys and fresh elves new_elves = busy_elves_heap.get_elves_for_min(current_time) elves_ready.add_elves(new_elves) if (current_time % 120 == 60): print('time taken = {0}, current_time = {1}'.format(time.time() - start, hrs.get_time_string(current_time))) print('easy_toys:{0},\t constant_toys:{1},\t variable_toys:{2},\t hardest_toys:{3},\t toys_left_at_end:{4}'.format( toy_backlog.easy_toy_list.size, len(toy_backlog.constant_rating_list), len(toy_backlog.variable_toy_list), len(toy_backlog.hardest_toy_list), len(toys_left_at_end))) print('elves ready:{0}, high-perf-elves:{1}'.format(len(elves_ready.training_elf_list), len(elves_ready.high_performance_elf_list))) print('toys finished = {0}'.format(toys_finished)) if (len(elves_ready.training_elf_list) + len(elves_ready.high_performance_elf_list)) == 0: current_time = hrs.next_sanctioned_minute(current_time) continue if (toy_loader.done() and current_time - time_of_last_toy_assigned > 2880 and len(elves_ready.training_elf_list) == num_elves and len(toys_left_at_end) == 0): print("starting cleanup") for toy in toy_backlog.easy_toy_list.all_toys(): toys_left_at_end.append(toy) toy_backlog.easy_toy_list.clear() for toy in toy_backlog.constant_rating_list: toys_left_at_end.append(toy) toy_backlog.constant_rating_list = [] while len(toy_backlog.variable_toy_list) > 0: toys_left_at_end.append(toy_backlog.pop_variable_toy()) while len(toy_backlog.hardest_toy_list) > 0: toys_left_at_end.append(toy_backlog.pop_hardest_toy()) if (toy_loader.done() and len(toys_left_at_end) > 0): # clean up last toys toys_finished += scheduler.clean_up(toys_left_at_end, elves_ready, busy_elves_heap, current_time, solution_writer) else: # step 2 pair off as many elves and toys as possible toys_newly_finished = scheduler.schedule(toy_backlog, elves_ready, busy_elves_heap, current_time, solution_writer, toy_loader) toys_finished += toys_newly_finished if (toys_newly_finished > 0): time_of_last_toy_assigned = current_time current_time = hrs.next_sanctioned_minute(current_time) toy_loader.close() solution_writer.close()