Solution to problem 11 part 1 in Python

This commit is contained in:
David Doblas Jiménez 2022-07-13 20:06:42 +02:00
parent 27a15005ee
commit 0e4a70c163
2 changed files with 137 additions and 3 deletions

View File

@ -1,13 +1,13 @@
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.1.0
rev: v4.3.0
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
- id: check-yaml
- id: check-added-large-files
- repo: https://github.com/psf/black
rev: 22.3.0
rev: 22.6.0
hooks:
- id: black
- repo: https://github.com/PyCQA/isort
@ -15,7 +15,7 @@ repos:
hooks:
- id: isort
- repo: https://github.com/pre-commit/mirrors-mypy
rev: v0.931
rev: v0.961
hooks:
- id: mypy
additional_dependencies: [pydantic] # add if use pydantic

134
src/Year_2018/P11.py Normal file
View File

@ -0,0 +1,134 @@
# --- Day 11: Chronal Charge ---
# You watch the Elves and their sleigh fade into the distance as they head
# toward the North Pole.
# Actually, you're the one fading. The falling sensation returns.
# The low fuel warning light is illuminated on your wrist-mounted device.
# Tapping it once causes it to project a hologram of the situation: a 300x300
# grid of fuel cells and their current power levels, some negative. You're not
# sure what negative power means in the context of time travel, but it can't be
# good.
# Each fuel cell has a coordinate ranging from 1 to 300 in both the X
# (horizontal) and Y (vertical) direction. In X,Y notation, the top-left cell
# is 1,1, and the top-right cell is 300,1.
# The interface lets you select any 3x3 square of fuel cells. To increase your
# chances of getting to your destination, you decide to choose the 3x3 square
# with the largest total power.
# The power level in a given fuel cell can be found through the following
# process:
# 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.
# For example, to find the power level of the fuel cell at 3,5 in a grid with
# serial number 8:
# The rack ID is 3 + 10 = 13.
# The power level starts at 13 * 5 = 65.
# Adding the serial number produces 65 + 8 = 73.
# Multiplying by the rack ID produces 73 * 13 = 949.
# The hundreds digit of 949 is 9.
# Subtracting 5 produces 9 - 5 = 4.
# So, the power level of this fuel cell is 4.
# Here are some more example power levels:
# Fuel cell at 122,79, grid serial number 57: power level -5.
# Fuel cell at 217,196, grid serial number 39: power level 0.
# Fuel cell at 101,153, grid serial number 71: power level 4.
# Your goal is to find the 3x3 square which has the largest total power. The
# square must be entirely within the 300x300 grid. Identify this square using
# the X,Y coordinate of its top-left fuel cell. For example:
# For grid serial number 18, the largest total 3x3 square has a top-left corner
# of 33,45 (with a total power of 29); these fuel cells appear in the middle of
# this 5x5 region:
# -2 -4 4 4 4
# -4 4 4 4 -5
# 4 3 3 4 -4
# 1 1 2 4 -3
# -1 0 2 -5 -2
# For grid serial number 42, the largest 3x3 square's top-left is 21,61 (with a
# total power of 30); they are in the middle of this region:
# -3 4 2 2 2
# -4 4 3 3 4
# -5 3 3 4 -4
# 4 3 3 4 -3
# 3 3 3 -5 -1
# What is the X,Y coordinate of the top-left fuel cell of the 3x3 square with
# the largest total power?
from collections import defaultdict
with open("files/P11.txt") as f:
grid_serial_number = int(f.read().strip().split()[0])
def get_value(x: int, y: int) -> int:
rack_ID = x + 10
power_level = rack_ID * y
power_level += grid_serial_number
power_level *= rack_ID
power_level = (power_level // 100) % 10
return power_level - 5
def calculate_ps(x, y):
return (
get_value(x + 1, y + 1)
+ partial_sums[x, y - 1]
+ partial_sums[x - 1, y]
- partial_sums[x - 1, y - 1]
)
partial_sums = defaultdict(int)
def get_partial_sums(arr_size: int) -> dict[tuple[int, int], int]:
for y in range(arr_size):
for x in range(arr_size):
partial_sums[(x, y)] = calculate_ps(x, y)
return partial_sums
def part_1() -> None:
arr_size, square_size = 300, 3
grid_sums = {}
partial_sums = get_partial_sums(arr_size)
for size in range(1, square_size + 1):
for j in range(size - 1, arr_size):
for i in range(size - 1, arr_size):
gp = (
partial_sums[(i, j)]
+ partial_sums[(i - size, j - size)]
- partial_sums[(i - size, j)]
- partial_sums[(i, j - size)]
)
grid_sums[gp] = (i - size + 2, j - size + 2, size)
x3, y3, _ = grid_sums[max(grid_sums)]
print(f"Largest total power is located at {x3},{y3}")
if __name__ == "__main__":
part_1()