Solution to problem 6 part 1 in Python
This commit is contained in:
parent
a14b73ad1b
commit
3e35e6caf9
100
src/Year_2017/P6.py
Normal file
100
src/Year_2017/P6.py
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
# --- Day 6: Memory Reallocation ---
|
||||||
|
|
||||||
|
# A debugger program here is having an issue: it is trying to repair a memory
|
||||||
|
# reallocation routine, but it keeps getting stuck in an infinite loop.
|
||||||
|
|
||||||
|
# In this area, there are sixteen memory banks; each memory bank can hold any
|
||||||
|
# number of blocks. The goal of the reallocation routine is to balance the
|
||||||
|
# blocks between the memory banks.
|
||||||
|
|
||||||
|
# The reallocation routine operates in cycles. In each cycle, it finds the
|
||||||
|
# memory bank with the most blocks (ties won by the lowest-numbered memory
|
||||||
|
# bank) and redistributes those blocks among the banks. To do this, it removes
|
||||||
|
# all of the blocks from the selected bank, then moves to the next (by index)
|
||||||
|
# memory bank and inserts one of the blocks. It continues doing this until it
|
||||||
|
# runs out of blocks; if it reaches the last memory bank, it wraps around to
|
||||||
|
# the first one.
|
||||||
|
|
||||||
|
# The debugger would like to know how many countss can be done before a
|
||||||
|
# blocks-in-banks configuration is produced that has been seen before.
|
||||||
|
|
||||||
|
# For example, imagine a scenario with only four memory banks:
|
||||||
|
|
||||||
|
# The banks start with 0, 2, 7, and 0 blocks. The third bank has the most
|
||||||
|
# blocks, so it is chosen for counts.
|
||||||
|
# Starting with the next bank (the fourth bank) and then continuing to the
|
||||||
|
# first bank, the second bank, and so on, the 7 blocks are spread out over the
|
||||||
|
# memory banks. The fourth, first, and second banks get two blocks each, and
|
||||||
|
# the third bank gets one back. The final result looks like this: 2 4 1 2.
|
||||||
|
# Next, the second bank is chosen because it contains the most blocks
|
||||||
|
# (four). Because there are four memory banks, each gets one block. The result
|
||||||
|
# is: 3 1 2 3.
|
||||||
|
# Now, there is a tie between the first and fourth memory banks, both of
|
||||||
|
# which have three blocks. The first bank wins the tie, and its three blocks
|
||||||
|
# are distributed evenly over the other three banks, leaving it with none:
|
||||||
|
# 0 2 3 4.
|
||||||
|
# The fourth bank is chosen, and its four blocks are distributed such that
|
||||||
|
# each of the four banks receives one: 1 3 4 1.
|
||||||
|
# The third bank is chosen, and the same thing happens: 2 4 1 2.
|
||||||
|
|
||||||
|
# At this point, we've reached a state we've seen before: 2 4 1 2 was already
|
||||||
|
# seen. The infinite loop is detected after the fifth block counts
|
||||||
|
# cycle, and so the answer in this example is 5.
|
||||||
|
|
||||||
|
# Given the initial block counts in your puzzle input, how many counts
|
||||||
|
# cycles must be completed before a configuration is produced that has been
|
||||||
|
# seen before?
|
||||||
|
|
||||||
|
from collections import Counter, defaultdict
|
||||||
|
from itertools import cycle, islice
|
||||||
|
|
||||||
|
with open("files/P6.txt") as f:
|
||||||
|
values = [int(num) for num in f.read().strip().split()]
|
||||||
|
|
||||||
|
banks = defaultdict(int)
|
||||||
|
for idx, value in enumerate(values):
|
||||||
|
banks[str(idx)] = value
|
||||||
|
|
||||||
|
|
||||||
|
def cycle_through(dic: dict[str, int], starting: int, times: int) -> list[str]:
|
||||||
|
keys = list(dic.keys())
|
||||||
|
cycled = cycle(keys)
|
||||||
|
|
||||||
|
if starting == len(keys):
|
||||||
|
starting = 0
|
||||||
|
|
||||||
|
return list(
|
||||||
|
islice(
|
||||||
|
cycled,
|
||||||
|
keys.index(str(starting)),
|
||||||
|
keys.index(str(starting)) + times,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def part_1() -> None:
|
||||||
|
seen = []
|
||||||
|
repeated = False
|
||||||
|
iteration = 0
|
||||||
|
while not repeated:
|
||||||
|
iteration += 1
|
||||||
|
counts = Counter(banks).most_common()
|
||||||
|
# get the most common (tuple)
|
||||||
|
_most_common = counts[0]
|
||||||
|
# reset its key
|
||||||
|
banks[_most_common[0]] = 0
|
||||||
|
for key in cycle_through(
|
||||||
|
banks, int(_most_common[0]) + 1, int(_most_common[1])
|
||||||
|
):
|
||||||
|
banks[key] += 1
|
||||||
|
_iter = Counter(banks).most_common()
|
||||||
|
if _iter in seen:
|
||||||
|
repeated = True
|
||||||
|
else:
|
||||||
|
seen.append(_iter)
|
||||||
|
|
||||||
|
print(f"{iteration} cycles must be completed")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
part_1()
|
Loading…
Reference in New Issue
Block a user