"""Solution to 2020/23""" from collections import deque EXAMPLE = '389125467' INPUT = '952316487' # INPUT = EXAMPLE MOVES = 10_000_000 INPUT = list(map(int, INPUT)) INPUT = INPUT + list(range(max(INPUT) + 1, 1_000_000 + 1)) def main(): cups = CrabCups(INPUT) print(cups) for move in range(MOVES): if move % 1_000_000 == 0: print(f'-- MOVE {move} --') cups.move() print() print('finished') print(cups._nodes[1].next.value * cups._nodes[1].next.next.value) exit() class CrabCups: def __init__(self, cups): nodes = dict() i = 0 prev = None while i < len(cups): node = Node(cups[i]) if prev: node.prev = prev prev.next = node prev = node nodes[cups[i]] = node i += 1 nodes[cups[0]].prev = nodes[cups[-1]] nodes[cups[-1]].next = nodes[cups[0]] self._nodes = nodes self.cur = nodes[cups[0]] self.cup_count = len(cups) self.last_cur = None self.last_pick_up = None self.last_destination = None def move(self): pick_up = set() link = self.cur self.last_cur = self.cur self.last_pick_up = link.next for _ in range(3): link = link.next pick_up.add(link.value) # wire cur with cup after pickups link.next.prev = self.cur self.cur.next = link.next # find dest dest = self.cur.value - 1 dest = dest if dest != 0 else self.cup_count while dest in pick_up: dest -= 1 dest = dest if dest != 0 else self.cup_count dest = self._nodes[dest] self.last_dest = dest dest.next.prev = link link.next = dest.next link = link.prev.prev dest.next = link link.prev = dest self.cur = self.cur.next def as_list(self, start): cups = [start.value] cur = start.next while not cur is start: cups.append(cur.value) cur = cur.next return cups class Node: next = None prev = None def __init__(self, val): self.value = val main()