From 0e4a70c1632d58c5124246eb571a0d2a8495981e Mon Sep 17 00:00:00 2001 From: daviddoji Date: Wed, 13 Jul 2022 20:06:42 +0200 Subject: [PATCH] Solution to problem 11 part 1 in Python --- .pre-commit-config.yaml | 6 +- src/Year_2018/P11.py | 134 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 137 insertions(+), 3 deletions(-) create mode 100644 src/Year_2018/P11.py diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 796f9c6..c4f0997 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -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 diff --git a/src/Year_2018/P11.py b/src/Year_2018/P11.py new file mode 100644 index 0000000..1c368ec --- /dev/null +++ b/src/Year_2018/P11.py @@ -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()