-
-
Save purplemonkeymad/5f1d628ab5ea238dc23f8bd123b54f64 to your computer and use it in GitHub Desktop.
day 5
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import re | |
import argparse | |
import sys | |
def print_error(*args, **kwargs): | |
print(*args, file=sys.stderr, **kwargs) | |
def parse_section(section:str): | |
pass | |
def parse_map(section:str): | |
header,*lines = section.splitlines() | |
source,destination = (header.split(' ')[0]).split('-to-') | |
object = Map() | |
object.source_name = source | |
object.destination_name = destination | |
for range in lines: | |
dest,sour,size = range.strip().split(' ') | |
range_object = MapRange(int(sour),int(dest),int(size)) | |
object.mapping_list.append(range_object) | |
return object | |
class Map: | |
def __init__(self) -> None: | |
self.source_name = "" | |
self.destination_name = "" | |
self.mapping_list = list() | |
def __str__(self): | |
return f"Map: Source:{self.source_name}, Dest:{self.destination_name}, MappingCount:{len(self.mapping_list)}" | |
def convert_forward(self,number): | |
for range in self.mapping_list: | |
if range.in_range(number): | |
num2 = number - range.source_start + range.destination_start | |
return num2 | |
return number | |
def convert_backward(self,number): | |
for range in self.mapping_list: | |
if range.in_range(number): | |
num2 = number + range.source_start - range.destination_start | |
return num2 | |
return number | |
class MapRange: | |
source_start = -1 | |
destination_start = -1 | |
range_size = 0 | |
def __init__(self,source:int ,destination:int ,size:int ): | |
self.source_start = source | |
self.destination_start = destination | |
self.range_size = size | |
def __repr__(self): | |
return f"<MapRange source_start:{self.source_start}, destination_start:{self.destination_start}, range:{self.range_size}>" | |
def __str__(self): | |
return f"Range: {self.source_start}:{self.source_start+self.range_size} -> {self.destination_start}:{self.destination_start+self.range_size}" | |
def in_range(self,number:int): | |
source_end = self.source_start + self.range_size | |
return (number >= self.source_start and number < source_end) | |
def parse_seed(section:str): | |
header,seed_section = section.split(':') | |
if (header != 'seeds'): | |
print_error("seeds header missing, results might be wonky") | |
seed_id_list = [int(x) for x in re.split(' +',seed_section.strip())] | |
seed_list = list() | |
for id in seed_id_list: | |
object = Seed() | |
object.seed = id | |
seed_list.append(object) | |
return seed_list | |
class Seed: | |
seed = -1 | |
soil = -1 | |
fertilizer = -1 | |
water = -1 | |
light = -1 | |
temperature = -1 | |
humidity = -1 | |
location = -1 | |
def calculate_properties(self,maps:dict): | |
current_type = "seed" | |
while current_type in maps.keys() and hasattr(self,current_type): | |
new_n = maps[current_type].convert_forward(getattr(self,current_type)) | |
current_type = maps[current_type].destination_name | |
setattr(self,current_type,new_n) | |
def __repr__(self): | |
return f"<Seed: {self.seed}, soil={self.soil}, fert={self.fertilizer}, water={self.water}, light={self.water}, temp={self.temperature}, hum={self.humidity}, loc={self.location}>" | |
def __str__(self): | |
return f"Seed: {self.seed}, soil={self.soil}, fert={self.fertilizer}, water={self.water}, light={self.water}, temp={self.temperature}, hum={self.humidity}, loc={self.location}" | |
def main(file_string:str): | |
seed_part,*map_parts = file_string.split('\n\n') | |
if (not re.match('seeds:',seed_part)): | |
raise Exception("File Must start with seeds record.") | |
seeds = parse_seed(seed_part) | |
#print(seeds) | |
maps = [parse_map(x) for x in map_parts] | |
[print(str(x)) for x in maps] | |
maps_index = { x.source_name:x for x in maps} | |
#print (maps_index) | |
for t in seeds: | |
t.calculate_properties(maps_index) | |
print(f"{t}") | |
# seeds should be updated | |
seeds.sort(key=lambda x:x.location) | |
print("closest seed:") | |
print (seeds[0]) | |
if __name__ == "__main__": | |
parser = argparse.ArgumentParser(description="day 5 solver") | |
parser.add_argument("-input",type=str) | |
parser.add_argument("-part",type=int) | |
args = parser.parse_args() | |
filename = args.input | |
if filename == None: | |
parser.print_help() | |
exit(1) | |
file = open(filename,'r') | |
main(file.read()) | |
file.close() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment