81 lines
2.3 KiB
Python
81 lines
2.3 KiB
Python
|
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()
|