Advent-of-Code/2020/Day 10/Solution.py

68 lines
2.6 KiB
Python

input_file = "input.txt"
adapters = []
with open(input_file) as adapter_ratings:
line = adapter_ratings.readline()
while line and line != "\n":
adapters.append(int(line))
line = adapter_ratings.readline()
adapters.sort()
computer_adapter = max(adapters) + 3
# List of couples separated by three, which must be present to have a working chain
fixed_points = []
one_diffs = 0
three_diffs = 1 # As the computer adapter is always the highest one we got plus three
# The charging outlet is 0, compute the difference now
if adapters[0] == 1:
one_diffs += 1
elif adapters[0] == 3:
fixed_points.append((adapters[0], 0))
three_diffs += 1
for index in range(len(adapters)-1):
current_difference = adapters[index+1] - adapters[index]
if current_difference == 1:
one_diffs += 1
elif current_difference == 3:
if (adapters[index], index) not in fixed_points:
fixed_points.append((adapters[index], index))
fixed_points.append((adapters[index+1], index+1))
three_diffs += 1
print(f"The product of one and three differences is : {one_diffs}*{three_diffs} = {one_diffs*three_diffs}")
# The last adapter is always needed as it is the only link possible to the computer adapter
if (adapters[-1], len(adapters)-1) not in fixed_points:
fixed_points.append((adapters[-1], len(adapters)-1))
# Compute the distance separating each fixed point. If they are not successive, it means that there are possible
# permutations between those two fixed points. Store the count of numbers we can choose from
separation_distance = []
for index in range(len(fixed_points) - 1):
if fixed_points[index + 1][1] - fixed_points[index][1] > 1:
separation_distance.append(fixed_points[index + 1][1] - fixed_points[index][1] - 1)
# Distance between 0 and the first fixed point
separation_distance.insert(0, fixed_points[0][1])
total_combinations = 1
# This would probably not work in a general case other than this puzzle, as I only take into account small possible
# separations, which is all I have got.
for separation in separation_distance:
# If we have three numbers, it means that we have at least a separation of 4 jolts between the two fixed points,
# which is not possible to cross if we do not choose any number between those two. So, do not count this choice.
if separation == 3:
# Number of subsets of a set is 2^n where n is the number of elements in the set.
total_combinations *= 2**3 - 1
else:
total_combinations *= 2**separation
print(f"The number of combinations is : {total_combinations}")