Solution to problem 3 in Python

This commit is contained in:
David Doblas Jiménez 2022-02-26 21:15:47 +01:00
parent 427519fa76
commit 9c3ed5544e

112
src/Year_2016/P3.py Normal file
View File

@ -0,0 +1,112 @@
# --- Day 3: Squares With Three Sides ---
# Now that you can think clearly, you move deeper into the labyrinth of
# hallways and office furniture that makes up this part of Easter Bunny HQ.
# This must be a graphic design department; the walls are covered in
# specifications for triangles.
# Or are they?
# The design document gives the side lengths of each triangle it describes,
# but... 5 10 25? Some of these aren't triangles. You can't help but mark the
# impossible ones.
# In a valid triangle, the sum of any two sides must be larger than the
# remaining side. For example, the "triangle" given above is impossible,
# because 5 + 10 is not larger than 25.
# In your puzzle input, how many of the listed triangles are possible?
from copy import copy
from itertools import combinations, zip_longest
from typing import Iterable, Iterator, Tuple
with open("files/P3.txt") as f:
triangles = [line for line in f.read().strip().split("\n")]
def part_1() -> None:
possible_triangles = 0
for triangle in triangles:
valid_triangles = 0
all_sides = triangle.split()
# make pairs of all combinations
two_sides = list(combinations(all_sides, 2))
for pair in two_sides:
# we need to remove from the list due to possible duplicates
all_sides_ = copy(all_sides)
all_sides_.remove(pair[0])
all_sides_.remove(pair[1])
missing = int(all_sides_[0])
sum_two_sides = sum(int(side) for side in pair)
if sum_two_sides > missing:
valid_triangles += 1
if valid_triangles == 3:
possible_triangles += 1
print(f"There are {possible_triangles} possible triangles")
# --- Part Two ---
# Now that you've helpfully marked up their design documents, it occurs to you
# that triangles are specified in groups of three vertically. Each set of three
# numbers in a column specifies a triangle. Rows are unrelated.
# For example, given the following specification, numbers with the same
# hundreds digit would be part of the same triangle:
# 101 301 501
# 102 302 502
# 103 303 503
# 201 401 601
# 202 402 602
# 203 403 603
# In your puzzle input, and instead reading by columns, how many of the listed
# triangles are possible?
# split by spaces, instead of newlines
with open("files/P3.txt") as f:
triangles_ = [line for line in f.read().strip().split()]
def grouper(iterable: Iterable[str], n: int) -> Iterator[Tuple[int, int, int]]:
"Collect data into fixed-length chunks or blocks"
# grouper('ABCDEFG', 3, 'x') --> ABC DEF Gxx"
args = [iter(iterable)] * n
return zip_longest(*args, fillvalue=None)
first_col = triangles_[::3]
second_col = triangles_[1::3]
third_col = triangles_[2::3]
triangles_vert = list(grouper(first_col + second_col + third_col, 3))
# almost identical to part 1
def part_2() -> None:
possible_triangles = 0
for triangle in triangles_vert:
valid_triangles = 0
all_sides = list(triangle)
# make pairs of all combinations
two_sides = list(combinations(all_sides, 2))
for pair in two_sides:
# we need to remove from the list due to possible duplicates
all_sides_ = copy(all_sides)
all_sides_.remove(pair[0])
all_sides_.remove(pair[1])
missing = int(all_sides_[0])
sum_two_sides = sum(int(side) for side in pair)
if sum_two_sides > missing:
valid_triangles += 1
if valid_triangles == 3:
possible_triangles += 1
print(f"There are {possible_triangles} possible triangles")
if __name__ == "__main__":
part_1()
part_2()