completed 2017.06.2

This commit is contained in:
dusk 2025-07-26 17:59:33 +00:00
parent 6ab8e45b17
commit e2c797cf55

81
2017/06/2memory-balance.py Executable file
View File

@ -0,0 +1,81 @@
#!/usr/bin/env python3
# this one seems fun!
# i have 16 memory banks, each with a number of blocks.
# every cycle, the banks are re-balanced according to the following:
# - the bank with the greatest number of blocks is the candidate to balance.
# - ties are broken by bank index: lowest wins candidacy.
# - remove all blocks from candidate bank, redistributing them
# one to each following bank (by index no.), wrapping at the end.
# - the candidate bank will only balance BACK to itself if it wraps.
# that is, make sure to re-balance starting from the NEXT bank.
# my puzzle is to solve after how many cycles will the banks be in
# a familiar state. that is, how many cycles in the cycle?
# i can number bank states as:
# - given input state is bank state 0
# - each following state is incremented by +1, so that state n
# represents the bank state after n cycles are completed.
if __name__ == '__main__':
def strings_to_ints(data):
for i in range(len(data)):
data[i] = int(data[i])
return data
def process_input(file):
list_of_strings = file.read().split()
list_of_ints = strings_to_ints(list_of_strings)
return list_of_ints
def find_greatest(ints):
index_of_greatest = 0
for i in range(len(ints)):
if ints[i] > ints[index_of_greatest]:
index_of_greatest = i
return index_of_greatest
def rebalance(ints):
candidate = find_greatest(ints)
to_rebalance = ints[candidate]
print(f'rebalancing the {candidate}th (i.e. {to_rebalance}) from {ints}...')
new_ints = []
for int in ints:
new_ints.append(int)
new_ints[candidate] = 0
for i in range(to_rebalance):
target_index = candidate + i + 1 # since i is between 0 and (to_rebalance - 1) incl.
target_index = target_index % len(new_ints)
new_ints[target_index] = new_ints[target_index] + 1
# what the fuck. why does bankstate get updated. huh
# after changing my simple new_ints = ints to a for-loop builder
# thing, the shit just fucking works. huh?? clearly the = operator
# isn't JUST a variable assignment button. something is afoot.....
print(f'rebalanced as {new_ints}')
return new_ints
def check_duplicate(intses):
has_duplicate = False
latest_ints = intses[len(intses)-1]
duplicate_index = ''
for i in range(len(intses)-1): # don't check final index. lol
if intses[i] == latest_ints:
has_duplicate = True
duplicate_index = i
return [has_duplicate,duplicate_index]
# the main script!
#
with open('input', 'r', encoding='utf-8') as file:
bankstate = [process_input(file)]
print(f'initialized bankstate as {bankstate}')
seen_before = False
cycles = 0 # initialize cycles counter. this matches current bankstate index
while not seen_before:
cycles += 1 # happy new cycles! *confetti*
last_state = bankstate[len(bankstate)-1] # note: bankstate's max index is cycles-1 currently
new_state = rebalance(last_state)
bankstate.append(new_state)
[seen_before, duplicate_index] = check_duplicate(bankstate)
print(f"we looped after {cycles} cycles! that's a lot... i'm so dizzy....")
print(f"this state last seen at index {duplicate_index}, i.e. the loop has {cycles-duplicate_index} cycles")