import time import cProfile import line_profiler #from rich import print start_time = time.time() with open('puzzle.txt', 'r') as f: line = f.read() stones = {} for stone in list(map(int, line.split(' '))): length = len(str(stone)) splittable = True if length % 2 == 0 else False if splittable: half = 10 ** (length // 2) first_half = stone // half second_half = stone % half stones[stone] = { 'number': 1, 'length': length, 'splittable': splittable, 'first_half': first_half, 'second_half': second_half } else: stones[stone] = { 'number': 1, 'length': length, 'splittable': splittable } @line_profiler.profile def run_puzzle(stones): for i in range(0, 75): loop_start = time.time() stones_update = {} for stone in stones: if stones[stone]['number'] > 0: if stones[stone]['splittable']: if stones[stone]['first_half'] in stones_update: stones_update[stones[stone]['first_half']]['number'] += stones[stone]['number'] else: if stones[stone]['first_half'] in stones: if stones[stones[stone]['first_half']]['splittable']: stones_update[stones[stone]['first_half']] = { 'number': stones[stone]['number'], 'length': stones[stones[stone]['first_half']]['length'], 'splittable': stones[stones[stone]['first_half']]['splittable'], 'first_half': stones[stones[stone]['first_half']]['first_half'], 'second_half': stones[stones[stone]['first_half']]['second_half'] } else: stones_update[stones[stone]['first_half']] = { 'number': stones[stone]['number'], 'length': stones[stones[stone]['first_half']]['length'], 'splittable': stones[stones[stone]['first_half']]['splittable'] } else: length = len(str(stones[stone]['first_half'])) splittable = True if length % 2 == 0 else False if splittable: half = 10 ** (length // 2) first_half = stones[stone]['first_half'] // half second_half = stones[stone]['first_half'] % half stones_update[stones[stone]['first_half']] = { 'number': stones[stone]['number'], 'length': length, 'splittable': splittable, 'first_half': first_half, 'second_half': second_half } else: stones_update[stones[stone]['first_half']] = { 'number': stones[stone]['number'], 'length': length, 'splittable': splittable } if stones[stone]['second_half'] in stones_update: stones_update[stones[stone]['second_half']]['number'] += stones[stone]['number'] else: if stones[stone]['second_half'] in stones: if stones[stones[stone]['second_half']]['splittable']: stones_update[stones[stone]['second_half']] = { 'number': stones[stone]['number'], 'length': stones[stones[stone]['second_half']]['length'], 'splittable': stones[stones[stone]['second_half']]['splittable'], 'first_half': stones[stones[stone]['second_half']]['first_half'], 'second_half': stones[stones[stone]['second_half']]['second_half'] } else: stones_update[stones[stone]['second_half']] = { 'number': stones[stone]['number'], 'length': stones[stones[stone]['second_half']]['length'], 'splittable': stones[stones[stone]['second_half']]['splittable'] } else: length = len(str(stones[stone]['second_half'])) splittable = True if length % 2 == 0 else False if splittable: half = 10 ** (length // 2) first_half = stones[stone]['second_half'] // half second_half = stones[stone]['second_half'] % half stones_update[stones[stone]['second_half']] = { 'number': stones[stone]['number'], 'length': length, 'splittable': splittable, 'first_half': first_half, 'second_half': second_half } else: stones_update[stones[stone]['second_half']] = { 'number': stones[stone]['number'], 'length': length, 'splittable': splittable } elif stone != 0: number = stone * 2024 if number in stones_update: stones_update[number]['number'] += stones[stone]['number'] else: if number in stones: if stones[number]['splittable']: stones_update[number] = { 'number': stones[stone]['number'], 'length': stones[stone]['length'], 'splittable': stones[number]['splittable'], 'first_half': stones[number]['first_half'], 'second_half': stones[number]['second_half'] } else: stones_update[number] = { 'number': stones[stone]['number'], 'length': stones[number]['length'], 'splittable': stones[number]['splittable'] } else: length = len(str(number)) splittable = True if length % 2 == 0 else False if splittable: half = 10 ** (length // 2) first_half = number // half second_half = number % half stones_update[number] = { 'number': stones[stone]['number'], 'length': length, 'splittable': splittable, 'first_half': first_half, 'second_half': second_half } else: stones_update[number] = { 'number': stones[stone]['number'], 'length': length, 'splittable': splittable } else: number = 1 if number in stones_update: stones_update[number]['number'] += stones[stone]['number'] else: if number in stones: stones_update[number] = { 'number': stones[stone]['number'], 'length': stones[stone]['length'], 'splittable': stones[stone]['splittable'] } else: stones_update[number] = { 'number': stones[stone]['number'], 'length': 1, 'splittable': False } stones[stone]['number'] = 0 stones.update(stones_update) print(f'loop {i} completed in {time.time() - loop_start} seconds') return stones cProfile.run('run_puzzle(stones)') stone_total = 0 for stone in stones: stone_total += stones[stone]['number'] print(stone_total) print(f'Total time: {time.time() - start_time}')