def read_map(input): map = [] for line in input: if not line.strip(): break dst, src, count = nums(line) map.append((dst, src, count)) return map def lookup(map, n): for dst, src, count in map: if src <= n < src+count: return dst + (n-src) return n def reverse(map, n): for dst, src, count in map: if dst <= n < dst+count: return src + (n-dst) return n def nums(s): return [int(x) for x in s.split()] def read_puzzle(input): l = next(input) name,_, data = l.partition(": ") assert name == 'seeds' seeds = nums(data) maps = {} for l in input: if l.strip(): assert ':' in l name = l.split()[0] frm, _, to = name.partition('-to-') assert frm assert to map = read_map(input) maps[(frm,to)] = map print(seeds) print(maps) locs = [] for n in seeds: print(n, lookup(maps[('seed','soil')], n), seed2loc(maps, n)) locs.append(seed2loc(maps, n)) print(min(locs)) def seed2loc(maps, n): for a,b in [ ('seed', 'soil'), ('soil', 'fertilizer'), ('fertilizer', 'water'), ('water', 'light'), ('light', 'temperature'), ('temperature', 'humidity'), ('humidity', 'location'), ]: n = lookup(maps[a,b], n) return n def loc2seed(maps, n): for m in [ ('humidity', 'location'), ('temperature', 'humidity'), ('light', 'temperature'), ('water', 'light'), ('fertilizer', 'water'), ('soil', 'fertilizer'), ('seed', 'soil'), ]: n = reverse(maps[m], n) return n import sys read_puzzle(sys.stdin)