import aoclib DAY = 23 TEST_SOLUTION_PART1 = "67384529" TEST_SOLUTION_PART2 = 149245887792 class Cup: def __init__(self, label, left=None, right=None): self.label = label self.left = left self.right = right def buildDoubleLinkedListDict(cup_list): cups = {} left_cup = None first_cup = None last_cup = None for cup in cup_list: thisCup = Cup(cup, left_cup, None) if first_cup is None: first_cup = thisCup else: last_cup.right = thisCup left_cup = thisCup last_cup = thisCup cups[cup] = thisCup first_cup.left = last_cup last_cup.right = first_cup return cups, first_cup def play(cups, current_cup): first_pickup = current_cup.right first_after_pickup = current_cup.right.right.right.right current_cup.right = first_after_pickup first_after_pickup.left = current_cup pickup_cups = [first_pickup.label, first_pickup.right.label, first_pickup.right.right.label] current_label = current_cup.label - 1 if current_cup.label > 1 else max(cups.keys()) while current_label in pickup_cups: current_label -= 1 if current_label == 0: current_label = max(cups.keys()) desination_cup = cups[current_label] desination_right = desination_cup.right desination_cup.right = first_pickup first_pickup.left = desination_cup desination_right.left = first_pickup.right.right first_pickup.right.right.right = desination_right return cups, current_cup.right def part1(test_mode=False): my_input = aoclib.getInputAs2DArray(day=DAY, return_type=int, test=test_mode) cups, current_cup = buildDoubleLinkedListDict(my_input[0]) for round in range(100): cups, current_cup = play(cups, current_cup) answer = "" add_cup = cups[1] while add_cup.right.label != 1: answer += str(add_cup.right.label) add_cup = add_cup.right return answer def part2(test_mode=False): my_input = aoclib.getInputAs2DArray(day=DAY, return_type=int, test=test_mode) cups, current_cup = buildDoubleLinkedListDict(my_input[0] + list(range(max(my_input[0]) + 1, 1000001))) for round in range(10000000): cups, current_cup = play(cups, current_cup) return cups[1].right.label * cups[1].right.right.label