Advertisement
hhoppe

Advent of code 2023 day 20

Dec 21st, 2023 (edited)
892
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 1.29 KB | None | 0 0
  1. def day20(s, *, part2=False, num_buttons=1000):
  2.   all_ch, outputs, flipflop, inputs = {}, {}, {}, collections.defaultdict(dict)
  3.   for line in s.splitlines():
  4.     ch, name, rhs = re.match(r'^(.)(\w+) -> (.*)$', line).groups()
  5.     all_ch[name], outputs[name], flipflop[name] = ch, rhs.split(', '), 0
  6.     for output in outputs[name]:
  7.       inputs[output][name] = 0
  8.  
  9.   counts = collections.Counter()
  10.   period = {name: 0 for name in inputs[next(iter(inputs['rx']))]} if part2 else {}
  11.  
  12.   for button_index in range(10**9 if part2 else num_buttons):
  13.     counts[0] += 1
  14.     pulses = collections.deque([('button', 0, 'broadcaster'[1:])])
  15.  
  16.     while pulses:
  17.       source, value, name = pulses.popleft()
  18.       if name in period and value == 0:
  19.         period[name] = button_index + 1
  20.         if all(period.values()):
  21.           return math.lcm(*period.values())
  22.       match all_ch[name]:
  23.         case '%':
  24.           if value == 1:
  25.             continue
  26.           value = flipflop[name] = 1 - flipflop[name]
  27.         case '&':
  28.           inputs[name][source] = value
  29.           value = 1 - all(inputs[name].values())
  30.       for output in outputs[name]:
  31.         counts[value] += 1
  32.         if output not in {'rx', 'output'}:
  33.           pulses.append((name, value, output))
  34.  
  35.   return math.prod(counts.values())
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement