/ Python / 2021 / 16.py
16.py
 1  from lib import *
 2  
 3  input = read_input(2021, 16)
 4  
 5  lines = input.splitlines()
 6  
 7  
 8  bits = io.StringIO("".join(bin(int(x, 16))[2:].zfill(4) for x in lines[0]))
 9  
10  
11  def read(n):
12      return int(bits.read(n), 2)
13  
14  
15  def parse1():
16      version = read(3)
17      t = read(3)
18      if t == 4:
19          lit = 0
20          while True:
21              c = read(1)
22              lit *= 16
23              lit += read(4)
24              if not c:
25                  break
26          return version
27      else:
28          vals = []
29          if not read(1):
30              c = read(15) + bits.tell()
31              while bits.tell() < c:
32                  vals.append(parse1())
33          else:
34              for _ in range(read(11)):
35                  vals.append(parse1())
36          return version + sum(vals)
37  
38  
39  print(parse1())
40  
41  
42  bits = io.StringIO("".join(bin(int(x, 16))[2:].zfill(4) for x in lines[0]))
43  
44  
45  def parse2():
46      read(3)
47      t = read(3)
48      if t == 4:
49          lit = 0
50          while True:
51              c = read(1)
52              lit *= 16
53              lit += read(4)
54              if not c:
55                  break
56          return lit
57      else:
58          vals = []
59          if not read(1):
60              c = read(15) + bits.tell()
61              while bits.tell() < c:
62                  vals.append(parse2())
63          else:
64              for _ in range(read(11)):
65                  vals.append(parse2())
66          match t:
67              case 0:
68                  return sum(vals)
69              case 1:
70                  return product(vals)
71              case 2:
72                  return min(vals)
73              case 3:
74                  return max(vals)
75              case 5:
76                  return int(vals[0] > vals[1])
77              case 6:
78                  return int(vals[0] < vals[1])
79              case 7:
80                  return int(vals[0] == vals[1])
81  
82  
83  print(parse2())