def solution_firstAvailableElf(toy_file, soln_file): """ 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 my_elves: list of elves in a priority queue ordered by next available time :return: """ hrs = Hours() ref_time = datetime.datetime(2014, 1, 1, 0, 0) row_count = 0 toy_list = [] my_elves = create_elves(NUM_ELVES) #Build list of toys with open(toy_file, 'rb') as f: toysfile = csv.reader(f) toysfile.next() # header row for row in toysfile: current_toy = Toy(row[0], row[1], row[2]) toy_list.append(current_toy) big_toys = sorted([x for x in toy_list if x.duration > 600], key = lambda e: -e.duration) small_toys = sorted([x for x in toy_list if x.duration <= 600], key = lambda e: e.duration) toy_list = None gc.collect() sorted_toy_list = big_toys + small_toys big_toys = small_toys = None gc.collect() with open(soln_file, 'wb') as w: wcsv = csv.writer(w) wcsv.writerow(['ToyId', 'ElfId', 'StartTime', 'Duration']) while len(sorted_toy_list) > 0: elf_available_time, current_elf = heapq.heappop(my_elves) if current_elf.rating > 3: current_toy = sorted_toy_list.pop() else: val = hrs.get_sanctioned_time_left(elf_available_time) current_toy_idx = find_closest_idx(sorted_toy_list, current_elf.rating * (val*1.025)) current_toy = sorted_toy_list.pop(current_toy_idx) if len(sorted_toy_list) % 1000 == 0: print "[Elf %s @ %0.2f] => toy %s @ %s -- %0.2f%% done" % (current_elf.id, current_elf.rating, current_toy.id, current_toy.duration, len(sorted_toy_list) / 10000.0) # get next available elf work_start_time = elf_available_time #!# work_start_time cannot be before toy's arrival #!if work_start_time < current_toy.arrival_minute: #! print 'Work_start_time before arrival minute: {0}, {1}'.\ #! format(work_start_time, current_toy.arrival_minute) #! exit(-1) current_elf.next_available_time, work_duration = assign_elf_to_toy(work_start_time, current_elf, current_toy, hrs) current_elf.update_elf(hrs, current_toy, work_start_time, work_duration) # put elf back in heap heapq.heappush(my_elves, (current_elf.next_available_time, current_elf)) # write to file in correct format tt = ref_time + datetime.timedelta(seconds=60*work_start_time) time_string = " ".join([str(tt.year), str(tt.month), str(tt.day), str(tt.hour), str(tt.minute)]) wcsv.writerow([current_toy.id, current_elf.id, time_string, work_duration])
def solution_firstAvailableElf(toy_file, soln_file, myelves): """ 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() ref_time = datetime.datetime(2014, 1, 1, 0, 0) row_count = 0 toy_list = [] loop_count = 0 #Build list of toys with open(toy_file, 'rb') as f: toysfile = csv.reader(f) toysfile.next() # header row for row in toysfile: current_toy = Toy(row[0], row[1], row[2]) toy_list.append(current_toy) sorted_toy_list = sorted(toy_list,key = lambda e: e.duration) toy_list = None gc.collect() print 'All is sorted:' with open(soln_file, 'wb') as w: wcsv = csv.writer(w) wcsv.writerow(['ToyId', 'ElfId', 'StartTime', 'Duration']) while len(sorted_toy_list) > 0: elf_available_time, current_elf = heapq.heappop(myelves) if current_elf.rating > 3.9: current_toy = sorted_toy_list.pop() print 'Elf {0} eff {1} toy {2} duration {3} BIG TOY---------------------------------'.format(current_elf.id, current_elf.rating, current_toy.id, current_toy.duration) loop_count = loop_count + 1 else: val = hrs.get_sanctioned_time_left(elf_available_time) current_toy_idx = find_closest_idx(sorted_toy_list, current_elf.rating * (val*1.15)) current_toy = sorted_toy_list.pop(current_toy_idx) if len(sorted_toy_list) % 10 == 0: print 'Elf {0} eff {1} toy {2} duration {3} SMALL TOY {4}> {5}'.format(current_elf.id, current_elf.rating, current_toy.id, current_toy.duration, len(sorted_toy_list), len(sorted_toy_list)) # get next available elf work_start_time = elf_available_time #!# work_start_time cannot be before toy's arrival #!if work_start_time < current_toy.arrival_minute: #! print 'Work_start_time before arrival minute: {0}, {1}'.\ #! format(work_start_time, current_toy.arrival_minute) #! exit(-1) current_elf.next_available_time, work_duration = \ assign_elf_to_toy(work_start_time, current_elf, current_toy, hrs) current_elf.update_elf(hrs, current_toy, work_start_time, work_duration) # put elf back in heap heapq.heappush(myelves, (current_elf.next_available_time, current_elf)) # write to file in correct format tt = ref_time + datetime.timedelta(seconds=60*work_start_time) time_string = " ".join([str(tt.year), str(tt.month), str(tt.day), str(tt.hour), str(tt.minute)]) wcsv.writerow([current_toy.id, current_elf.id, time_string, work_duration]) print 'loop_count = {0}'.format(loop_count)