from functools import lru_cache @lru_cache def score(serial, x, y): # Find the fuel cell's rack ID, which is its X coordinate plus 10. # Begin with a power level of the rack ID times the Y coordinate. # Increase the power level by the value of the grid serial number (your puzzle input). # Set the power level to itself multiplied by the rack ID. # Keep only the hundreds digit of the power level (so 12345 becomes 3; numbers with no hundreds digit become 0). # Subtract 5 from the power level. rack_id = x + 10 power_level = rack_id * y power_level += serial power_level *= rack_id try: return int(str(power_level)[-3]) - 5 except IndexError: return -5 def part_1(data): v = int(data.strip()) max_val = 0 max_coord = None assert score(8, 3, 5) == 4 assert score(57, 122, 79) == -5 assert score(39, 217, 196) == 0 for x in range(1, 299): for y in range(1, 299): s = 0 for x2 in range(x, x + 3): for y2 in range(y, y + 3): s += score(v, x2, y2) if x2 > 300 or y2 > 300: assert False if s > max_val: max_val = s max_coord = (x, y) assert max_coord is not None print(",".join(list(map(str, max_coord)))) def part_2(data): v = int(data.strip()) max_val = 0 max_coord = None # brute force, just tried if 15 is small enough for size in range(2, 15): for x in range(1, 299): for y in range(1, 299): s = 0 if x + size > 300 or y + size > 300: break for x2 in range(x, x + size): for y2 in range(y, y + size): s += score(v, x2, y2) if x2 > 300 or y2 > 300: assert False if s > max_val: max_val = s max_coord = (x, y, size) assert max_coord is not None print(",".join(list(map(str, max_coord)))) def main(): input_file = __file__.replace(".py", ".txt") with open(input_file) as f: data = f.read() part_1(data) part_2(data) if __name__ == "__main__": main()