#!/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] for i in range(len(intses)-1): # don't check final index. lol if intses[i] == latest_ints: has_duplicate = True return has_duplicate # 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 = check_duplicate(bankstate) print(f"we looped after {cycles} cycles! that's a lot... i'm so dizzy....")