from tools.aoc import AOCDay from typing import Any, List def getTheNumberFast(pushpull, adders, subbers, part2=False): if part2: number_init = [9] + [1] * 13 inc = 1 else: number_init = [9] * 14 inc = -1 z = int(1e9) number = number_init.copy() while z > 0: z = 0 down = False for i, inp in enumerate(number.copy()): if pushpull[i]: z = z * 26 + adders[i] + inp else: if 0 < z % 26 + subbers[i] < 10: number[i] = z % 26 + subbers[i] else: for j in range(i - 1, -1, -1): if pushpull[j] and 0 < number[j] + inc < 10: number[j] += inc for k in range(j + 1, 14): number[k] = number_init[k] down = True break z //= 26 if down: break return int("".join(map(str, number))) class Day(AOCDay): inputs = [ [ (99598963999971, "input24") ], [ (93151411711211, "input24") ] ] def getInputNumbers(self): pushpull = [] adders = [] subbers = [] next_add = False for line in self.getInput(): if line.startswith("div z"): pushpull.append(line.endswith(" 1")) if line.startswith("add x") and line[-1] != "z": subbers.append(int(line.split()[-1])) if line.startswith("add y") and next_add: adders.append(int(line.split()[-1])) next_add = False if line == "add y w": next_add = True return pushpull, adders, subbers def part1(self) -> Any: pushpull, adders, subbers = self.getInputNumbers() return getTheNumberFast(pushpull, adders, subbers) def part2(self) -> Any: pushpull, adders, subbers = self.getInputNumbers() return getTheNumberFast(pushpull, adders, subbers, part2=True) if __name__ == '__main__': day = Day(2021, 24) day.run(verbose=True)