Advertisement
kupuguy

Advent Of Code 2024 Day 24 Part 1

Dec 24th, 2024
136
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 2.48 KB | Source Code | 0 0
  1. from pathlib import Path
  2.  
  3.  
  4. class Wire:
  5.     def value(self, state: dict[str, "Wire"]) -> int: ...
  6.     def show(self, state: dict[str, "Wire"]) -> str: ...
  7.  
  8.  
  9. class Input(Wire):
  10.     def __init__(self, name: str, value: int) -> None:
  11.         self.v = value
  12.         self.name = name
  13.  
  14.     def value(self, state: dict[str, "Wire"]) -> int:
  15.         return self.v
  16.  
  17.     def show(self, state: dict[str, "Wire"]) -> str:
  18.         return self.name
  19.  
  20.  
  21. class Gate(Wire):
  22.     op = "?"
  23.  
  24.     def __init__(self, name: str, left: str, right: str) -> None:
  25.         self.left = left
  26.         self.right = right
  27.         self.v = None
  28.         self.name = name
  29.  
  30.     def __repr__(self) -> str:
  31.         return f"{self.left}{self.op}{self.right}"
  32.  
  33.     def show(self, state: dict[str, "Wire"]) -> str:
  34.         return (
  35.             f"({state[self.left].show(state)}{self.op}{state[self.right].show(state)})"
  36.         )
  37.  
  38.  
  39. class And(Gate):
  40.     op = "&"
  41.  
  42.     def value(self, state: dict[str, "Wire"]) -> int:
  43.         if self.v is None:
  44.             self.v = state[self.left].value(state) & state[self.right].value(state)
  45.  
  46.         return self.v
  47.  
  48.  
  49. class Or(Gate):
  50.     op = "|"
  51.  
  52.     def value(self, state: dict[str, "Wire"]) -> int:
  53.         if self.v is None:
  54.             self.v = state[self.left].value(state) | state[self.right].value(state)
  55.  
  56.         return self.v
  57.  
  58.  
  59. class Xor(Gate):
  60.     op = "^"
  61.  
  62.     def value(self, state: dict[str, "Wire"]) -> int:
  63.         if self.v is None:
  64.             self.v = state[self.left].value(state) ^ state[self.right].value(state)
  65.  
  66.         return self.v
  67.  
  68.  
  69. GATES = {"AND": And, "OR": Or, "XOR": Xor}
  70.  
  71.  
  72. def parse(input: str) -> dict[str, "Wire"]:
  73.     wires: dict[str, Wire] = {}
  74.  
  75.     for line in input.splitlines():
  76.         key, _, value = line.partition(": ")
  77.         if value:
  78.             wires[key] = Input(key, int(value))
  79.         operation, _, out = line.partition(" -> ")
  80.         if out:
  81.             l, op, r = operation.split()
  82.             wires[out] = GATES[op](out, l, r)
  83.  
  84.     return wires
  85.  
  86.  
  87. def part1(data: dict[str, "Wire"]) -> int:
  88.     z_keys = sorted([k for k in data if k.startswith("z")], reverse=True)
  89.     # print(z_keys)
  90.     values = [data[k].value(data) for k in z_keys]
  91.     return int("".join(str(v) for v in values), 2)
  92.  
  93.  
  94. TEST = parse(Path("input/day24-test.txt").read_text())
  95. assert part1(TEST) == 2024
  96. INPUT = parse(Path("input/day24.txt").read_text())
  97. part1_total = part1(INPUT)
  98. print(f"{part1_total=:,}")  # 64,755,511,006,320
  99.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement