Solution to problem 3 in Python
This commit is contained in:
parent
2e4f6be27d
commit
1defd41131
141
src/Year_2023/Day03.py
Normal file
141
src/Year_2023/Day03.py
Normal file
@ -0,0 +1,141 @@
|
||||
# --- Day 3: Gear Ratios ---
|
||||
|
||||
# You and the Elf eventually reach a gondola lift station; he says the gondola
|
||||
# lift will take you up to the water source, but this is as far as he can bring
|
||||
# you. You go inside.
|
||||
|
||||
# It doesn't take long to find the gondolas, but there seems to be a problem:
|
||||
# they're not moving.
|
||||
|
||||
# "Aaah!"
|
||||
|
||||
# You turn around to see a slightly-greasy Elf with a wrench and a look of
|
||||
# surprise. "Sorry, I wasn't expecting anyone! The gondola lift isn't working
|
||||
# right now; it'll still be a while before I can fix it." You offer to help.
|
||||
|
||||
# The engineer explains that an engine part seems to be missing from the engine,
|
||||
# but nobody can figure out which one. If you can add up all the part numbers in
|
||||
# the engine schematic, it should be easy to work out which part is missing.
|
||||
|
||||
# The engine schematic (your puzzle input) consists of a visual representation
|
||||
# of the engine. There are lots of numbers and symbols you don't really
|
||||
# understand, but apparently any number adjacent to a symbol, even diagonally,
|
||||
# is a "part number" and should be included in your sum. (Periods (.) do not
|
||||
# count as a symbol.)
|
||||
|
||||
# Here is an example engine schematic:
|
||||
|
||||
# 467..114..
|
||||
# ...*......
|
||||
# ..35..633.
|
||||
# ......#...
|
||||
# 617*......
|
||||
# .....+.58.
|
||||
# ..592.....
|
||||
# ......755.
|
||||
# ...$.*....
|
||||
# .664.598..
|
||||
|
||||
# In this schematic, two numbers are not part numbers because they are not
|
||||
# adjacent to a symbol: 114 (top right) and 58 (middle right). Every other
|
||||
# number is adjacent to a symbol and so is a part number; their sum is 4361.
|
||||
|
||||
# Of course, the actual engine schematic is much larger. What is the sum of all
|
||||
# of the part numbers in the engine schematic?
|
||||
|
||||
from re import finditer
|
||||
|
||||
with open("files/P3.txt") as f:
|
||||
grid = [line for line in f.read().strip().split()]
|
||||
|
||||
chars = {
|
||||
(row, col)
|
||||
for row, _ in enumerate(grid[0])
|
||||
for col, _ in enumerate(grid)
|
||||
if grid[row][col] not in "01234566789."
|
||||
}
|
||||
|
||||
|
||||
def part1():
|
||||
total = 0
|
||||
for idx_r, row in enumerate(grid):
|
||||
for num in finditer(r"\d+", row):
|
||||
surroundings = {
|
||||
(idx_r + di, idx_c + dj)
|
||||
for di in (-1, 0, 1)
|
||||
for dj in (-1, 0, 1)
|
||||
for idx_c in range(num.start(), num.end())
|
||||
}
|
||||
if chars & surroundings:
|
||||
total += int(num[0])
|
||||
|
||||
print(f"The sum of all of the part number is {total}")
|
||||
|
||||
|
||||
# --- Part Two ---
|
||||
|
||||
# The engineer finds the missing part and installs it in the engine! As the
|
||||
# engine springs to life, you jump in the closest gondola, finally ready to
|
||||
# ascend to the water source.
|
||||
|
||||
# You don't seem to be going very fast, though. Maybe something is still wrong?
|
||||
# Fortunately, the gondola has a phone labeled "help", so you pick it up and the
|
||||
# engineer answers.
|
||||
|
||||
# Before you can explain the situation, she suggests that you look out the
|
||||
# window. There stands the engineer, holding a phone in one hand and waving with
|
||||
# the other. You're going so slowly that you haven't even left the station. You
|
||||
# exit the gondola.
|
||||
|
||||
# The missing part wasn't the only issue - one of the gears in the engine is
|
||||
# wrong. A gear is any * symbol that is adjacent to exactly two part numbers.
|
||||
# Its gear ratio is the result of multiplying those two numbers together.
|
||||
|
||||
# This time, you need to find the gear ratio of every gear and add them all up
|
||||
# so that the engineer can figure out which gear needs to be replaced.
|
||||
|
||||
# Consider the same engine schematic again:
|
||||
|
||||
# 467..114..
|
||||
# ...*......
|
||||
# ..35..633.
|
||||
# ......#...
|
||||
# 617*......
|
||||
# .....+.58.
|
||||
# ..592.....
|
||||
# ......755.
|
||||
# ...$.*....
|
||||
# .664.598..
|
||||
|
||||
# In this schematic, there are two gears. The first is in the top left; it has
|
||||
# part numbers 467 and 35, so its gear ratio is 16345. The second gear is in the
|
||||
# lower right; its gear ratio is 451490. (The * adjacent to 617 is not a gear
|
||||
# because it is only adjacent to one part number.) Adding up all of the gear
|
||||
# ratios produces 467835.
|
||||
|
||||
# What is the sum of all of the gear ratios in your engine schematic?
|
||||
|
||||
from collections import defaultdict
|
||||
from math import prod
|
||||
|
||||
|
||||
def part2():
|
||||
gears = defaultdict(list)
|
||||
for idx_r, row in enumerate(grid):
|
||||
for num in finditer(r"\d+", row):
|
||||
surroundings = {
|
||||
(idx_r + di, idx_c + dj)
|
||||
for di in (-1, 0, 1)
|
||||
for dj in (-1, 0, 1)
|
||||
for idx_c in range(num.start(), num.end())
|
||||
}
|
||||
for c in surroundings & chars:
|
||||
gears[c].append(int(num[0]))
|
||||
|
||||
total = sum((prod(val) for val in gears.values() if len(val) == 2))
|
||||
print(f"The sum of all of the gear ratios if {total}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
part1()
|
||||
part2()
|
Loading…
Reference in New Issue
Block a user