aocpy/2018/d11.py

81 lines
2.3 KiB
Python
Raw Normal View History

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()