Solution to problem 16 in Python

This commit is contained in:
David Doblas Jiménez 2023-09-30 17:57:45 +02:00
parent 20b5223e8d
commit 4f397ec288

119
src/Year_2017/P16.py Normal file
View File

@ -0,0 +1,119 @@
# --- Day 16: Permutation Promenade ---
# You come upon a very unusual sight; a group of programs here appear to be
# dancing.
# There are sixteen programs in total, named a through p. They start by standing
# in a line: a stands in position 0, b stands in position 1, and so on until p,
# which stands in position 15.
# The programs' dance consists of a sequence of dance moves:
# Spin, written sX, makes X programs move from the end to the front, but
# maintain their order otherwise. (For example, s3 on abcde produces cdeab).
# Exchange, written xA/B, makes the programs at positions A and B swap
# places.
# Partner, written pA/B, makes the programs named A and B swap places.
# For example, with only five programs standing in a line (abcde), they could do
# the following dance:
# s1, a spin of size 1: eabcd.
# x3/4, swapping the last two programs: eabdc.
# pe/b, swapping programs e and b: baedc.
# After finishing their dance, the programs end up in order baedc.
# You watch the dance for a while and record their dance moves (your puzzle
# input). In what order are the programs standing after their dance?
with open("files/P16.txt") as f:
dance_moves = f.read().strip().split(",")
def spin(p, operand):
return p[-operand:] + p[:-operand]
def exchange(p, a, b):
p[a], p[b] = p[b], p[a]
return p
def partner(p, a, b):
a, b = p.index(a), p.index(b)
p[a], p[b] = p[b], p[a]
return p
def part1():
programs = list("abcdefghijklmnop")
for move in dance_moves:
operation, operands = move[0], move[1:].split("/")
if operation == "s":
programs = spin(programs, int(operands[0]))
elif operation == "x":
a, b = map(int, operands)
programs = exchange(programs, a, b)
elif operation == "p":
a, b = operands
programs = partner(programs, a, b)
res = "".join(programs)
print(f"The final order is {res}")
# --- Part Two ---
# Now that you're starting to get a feel for the dance moves, you turn your
# attention to the dance as a whole.
# Keeping the positions they ended up in from their previous dance, the programs
# perform it again and again: including the first dance, a total of one billion
# (1000000000) times.
# In the example above, their second dance would begin with the order baedc, and
# use the same dance moves:
# s1, a spin of size 1: cbaed.
# x3/4, swapping the last two programs: cbade.
# pe/b, swapping programs e and b: ceadb.
# In what order are the programs standing after their billion dances?
def lets_dance(programs):
for move in dance_moves:
operation, operands = move[0], move[1:].split("/")
if operation == "s":
programs = spin(programs, int(operands[0]))
elif operation == "x":
a, b = map(int, operands)
programs = exchange(programs, a, b)
elif operation == "p":
a, b = operands
programs = partner(programs, a, b)
return programs
def part2():
programs = list("abcdefghijklmnop")
it = 0
while it == 0 or programs != list("abcdefghijklmnop"):
programs = lets_dance(programs)
it += 1
for _ in range(1_000_000_000 % it):
programs = lets_dance(programs)
res = "".join(programs)
print(f"The final order is {res}")
if __name__ == "__main__":
part1()
part2()