from itertools import zip_longest def grouper(n, iterable, fillvalue=None): "grouper(3, 'ABCDEFG', 'x') --> ABC DEF Gxx" args = [iter(iterable)] * n return zip_longest(fillvalue=fillvalue, *args) def part1(sections): # consume seed section _, seeds = next(sections) seeds = [int(s) for s in seeds] print(seeds) for name, numbers in sections: # item: range_start, len, offset #mapping = [] #for dst, src, length in grouper(3, numbers): #mapping.append((src, lenght, dst)) #src = range(int(src), int(src) + int(length)) #dst = range(int(dst), int(dst) + int(length)) #for k, v in zip(src, dst): # mapping[k] = v # apply current mapping on input (using linear search) new_seeds = [] for seed in seeds: for dst, src, length in grouper(3, numbers): src, length, dst = int(src), int(length), int(dst) end = dst + (length - 1) if src <= seed < end: new_seed = seed + (dst-src) new_seeds.append(new_seed) break else: new_seeds.append(seed) seeds = new_seeds print(seeds) #seeds = [mapping.get(s, None) or s for s in seeds] print(f"Part 1, lowest location number = {min(seeds)}") def parse_input(infile): with open(infile) as f: sections = f.read().split("\n\n") sections = ((title, numbers) for title, numbers in (s.split(":") for s in sections)) sections = ((title, numbers.split()) for title, numbers in sections) return sections if __name__ == "__main__": import sys import os SCRIPTPATH = os.path.dirname(os.path.realpath(__file__)) infile = next(iter(sys.argv[1:]), None) sections = parse_input(infile or os.path.join(SCRIPTPATH, "example.txt")) part1(sections)