import fileinput import itertools from pprint import pprint from typing import Any, Dict, List, Optional, Tuple def parse() -> List[int]: line = next(fileinput.input()).strip() return [int(cup) for cup in line] def step(cups: Dict[int, int], current_label: int, min_, max_) -> int: a = cups[current_label] b = cups[a] c = cups[b] picked_up: List[int] = [a, b, c] cups[current_label] = cups[c] destination = current_label - 1 if destination < min_: destination = max_ while destination in picked_up: destination -= 1 if destination < min_: destination = max_ cups[picked_up[2]] = cups[destination] cups[destination] = picked_up[0] return cups[current_label] def part1(labels): cups = [None] * (len(labels) + 1) for i in range(len(labels)): cups[labels[i]] = labels[(i + 1) % len(labels)] current = labels[0] min_ = min(labels) max_ = max(labels) for _ in range(100): current = step(cups, current, min_, max_) label = 1 print("Part 1: ", end="") for _ in range(8): label = cups[label] print(label, end="") print() def part2(labels): labels = labels + [i for i in range(max(labels) + 1, 1_000_001)] cups = [0] * (len(labels) + 1) for i in range(len(labels)): cups[labels[i]] = labels[(i + 1) % len(labels)] current = labels[0] min_ = min(labels) max_ = max(labels) for turn in range(10_000_000): current = step(cups, current, min_, max_) a = cups[1] b = cups[a] print("Part 2:", a * b) def main() -> None: labels = parse() part1(labels) part2(labels) if __name__ == "__main__": main()