Advertisement
illuminati229

AoC 2022 Day 22

Dec 22nd, 2022
1,097
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 11.47 KB | None | 0 0
  1. from time import time
  2. import re
  3.  
  4. D = {0: 1, 1: 1j, 2: -1, 3: -1j}
  5. T = {'R': 1, 'L': -1, 'X': 0}
  6.  
  7.  
  8. def timer_func(func):
  9.     # This function shows the execution time of
  10.     # the function object passed
  11.     def wrap_func(*args, **kwargs):
  12.         t1 = time()
  13.         result = func(*args, **kwargs)
  14.         t2 = time()
  15.         print(f'Function {func.__name__!r} executed in {(t2 - t1):.4f}s')
  16.         return result
  17.  
  18.     return wrap_func
  19.  
  20.  
  21. @timer_func
  22. def day22(filepath, test, part2=False):
  23.     with open(filepath) as fin:
  24.         board_map, instructions = fin.read().split('\n\n')
  25.     path = re.findall(r'(\d+)([LRX])', instructions)
  26.     b_map = {}
  27.     for y, line in enumerate(board_map.split('\n')):
  28.         for x, c in enumerate(line):
  29.             if c in '.#':
  30.                 b_map[complex(x, y)] = c
  31.     cp = 0
  32.     f = 0  # facing
  33.     if not part2:
  34.         if test:
  35.             cp = 8  # current point
  36.             for steps, turn in path:
  37.                 for _ in range(int(steps)):
  38.                     ns = cp + D[f]  # next step
  39.                     if ns in b_map:
  40.                         if b_map[ns] == '.':
  41.                             cp = ns
  42.                         elif b_map[ns] == '#':
  43.                             f = (f + T[turn]) % 4
  44.                             break
  45.                     else:
  46.                         if f == 0:
  47.                             if 0 <= cp.imag < 4:
  48.                                 ns = complex(8, cp.imag)
  49.                             elif 4 <= cp.imag < 8:
  50.                                 ns = complex(0, cp.imag)
  51.                             elif 8 <= cp.imag < 12:
  52.                                 ns = complex(0, cp.imag)
  53.                         elif f == 1:
  54.                             if 0 <= cp.real < 8:
  55.                                 ns = complex(cp.real, 4)
  56.                             elif 8 <= cp.real < 12:
  57.                                 ns = complex(cp.real, 0)
  58.                             elif 12 <= cp.real < 16:
  59.                                 ns = complex(cp.real, 8)
  60.                         elif f == 2:
  61.                             if 0 <= cp.imag < 8:
  62.                                 ns = complex(11, cp.imag)
  63.                             elif 8 <= cp.imag < 12:
  64.                                 ns = complex(15, cp.imag)
  65.                         elif f == 3:
  66.                             if 0 <= cp.real < 8:
  67.                                 ns = complex(cp.real, 7)
  68.                             elif 8 <= cp.real < 16:
  69.                                 ns = complex(cp.real, 11)
  70.                         if b_map[ns] == '.':
  71.                             cp = ns
  72.                         elif b_map[ns] == '#':
  73.                             f = (f + T[turn]) % 4
  74.                             break
  75.                 else:
  76.                     f = (f + T[turn]) % 4
  77.  
  78.         else:
  79.             cp = 50  # current point
  80.             for steps, turn in path:
  81.                 for _ in range(int(steps)):
  82.                     ns = cp + D[f]  # next step
  83.                     if ns in b_map:
  84.                         if b_map[ns] == '.':
  85.                             cp = ns
  86.                         elif b_map[ns] == '#':
  87.                             f = (f + T[turn]) % 4
  88.                             break
  89.                     else:
  90.                         if f == 0:
  91.                             if 0 <= cp.imag < 100:
  92.                                 ns = complex(50, cp.imag)
  93.                             elif 100 <= cp.imag < 200:
  94.                                 ns = complex(0, cp.imag)
  95.                         elif f == 1:
  96.                             if 0 <= cp.real < 50:
  97.                                 ns = complex(cp.real, 100)
  98.                             elif 50 <= cp.real < 150:
  99.                                 ns = complex(cp.real, 0)
  100.                         elif f == 2:
  101.                             if 0 <= cp.imag < 50:
  102.                                 ns = complex(149, cp.imag)
  103.                             elif 50 <= cp.imag < 150:
  104.                                 ns = complex(99, cp.imag)
  105.                             elif 150 <= cp.imag < 200:
  106.                                 ns = complex(49, cp.imag)
  107.                         elif f == 3:
  108.                             if 0 <= cp.real < 50:
  109.                                 ns = complex(cp.real, 199)
  110.                             elif 50 <= cp.real < 100:
  111.                                 ns = complex(cp.real, 149)
  112.                             elif 100 <= cp.real < 149:
  113.                                 ns = complex(cp.real, 49)
  114.                         if b_map[ns] == '.':
  115.                             cp = ns
  116.                         elif b_map[ns] == '#':
  117.                             f = (f + T[turn]) % 4
  118.                             break
  119.                 else:
  120.                     f = (f + T[turn]) % 4
  121.  
  122.     # part 2
  123.     else:
  124.         if test:
  125.             cp = 8  # current point
  126.             for steps, turn in path:
  127.                 for _ in range(int(steps)):
  128.                     ns = cp + D[f]  # next step
  129.                     if ns in b_map:
  130.                         if b_map[ns] == '.':
  131.                             cp = ns
  132.                         elif b_map[ns] == '#':
  133.                             f = (f + T[turn]) % 4
  134.                             break
  135.                     else:
  136.                         if f == 0:
  137.                             if 0 <= cp.imag < 4:
  138.                                 ns = complex(15, 11 - cp.imag)
  139.                                 nf = 2
  140.                             elif 4 <= cp.imag < 8:
  141.                                 ns = complex(15 - (cp.imag % 4), 8)
  142.                                 nf = 1
  143.                             elif 8 <= cp.imag < 12:
  144.                                 ns = complex(11, 3 - (cp.imag % 8))
  145.                                 nf = 2
  146.                         elif f == 1:
  147.                             if 0 <= cp.real < 4:
  148.                                 ns = complex(11 - cp.real, 8)
  149.                                 nf = 3
  150.                             elif 4 <= cp.real < 8:
  151.                                 ns = complex(8, 11 - (cp.real % 4))
  152.                                 nf = 0
  153.                             elif 8 <= cp.real < 12:
  154.                                 ns = complex(3 - (cp.real % 8), 7)
  155.                                 nf = 3
  156.                             elif 12 <= cp.real < 16:
  157.                                 ns = complex(0, 7 - (cp.real % 12))
  158.                                 nf = 0
  159.                         elif f == 2:
  160.                             if 0 <= cp.imag < 4:
  161.                                 ns = complex(4 + cp.imag, 4)
  162.                                 nf = 1
  163.                             elif 4 <= cp.imag < 8:
  164.                                 ns = complex(12 + (cp.imag % 4), 11)
  165.                                 nf = 3
  166.                             elif 8 <= cp.imag < 12:
  167.                                 ns = complex(7 - (cp.imag % 8), 7)
  168.                                 nf = 3
  169.                         elif f == 3:
  170.                             if 0 <= cp.real < 4:
  171.                                 ns = complex(11 - cp.real, 0)
  172.                                 nf = 1
  173.                             elif 4 <= cp.real < 8:
  174.                                 ns = complex(8, cp.real % 4)
  175.                                 nf = 0
  176.                             elif 8 <= cp.real < 12:
  177.                                 ns = complex(3 - (cp.real % 8), 4)
  178.                                 nf = 1
  179.                             elif 12 <= cp.real < 16:
  180.                                 ns = complex(11, 7 - (cp.real % 12))
  181.                                 nf = 2
  182.                         if b_map[ns] == '.':
  183.                             cp = ns
  184.                             f = nf
  185.                         elif b_map[ns] == '#':
  186.                             f = (f + T[turn]) % 4
  187.                             break
  188.                 else:
  189.                     f = (f + T[turn]) % 4
  190.  
  191.         else:
  192.             cp = 50  # current point
  193.             for steps, turn in path:
  194.                 for _ in range(int(steps)):
  195.                     ns = cp + D[f]  # next step
  196.                     if ns in b_map:
  197.                         if b_map[ns] == '.':
  198.                             cp = ns
  199.                         elif b_map[ns] == '#':
  200.                             f = (f + T[turn]) % 4
  201.                             break
  202.                     else:
  203.                         # TODO fix wrapping
  204.                         if f == 0:
  205.                             if 0 <= cp.imag < 50:
  206.                                 ns = complex(99, 149 - cp.imag)
  207.                                 nf = 2
  208.                             elif 50 <= cp.imag < 100:
  209.                                 ns = complex(100 + (cp.imag % 50), 49)
  210.                                 nf = 3
  211.                             elif 100 <= cp.imag < 150:
  212.                                 ns = complex(149, 49 - (cp.imag % 100))
  213.                                 nf = 2
  214.                             elif 150 <= cp.imag < 200:
  215.                                 ns = complex(50 + (cp.imag % 150), 149)
  216.                                 nf = 3
  217.                         elif f == 1:
  218.                             if 0 <= cp.real < 50:
  219.                                 ns = complex(100 + cp.real, 0)
  220.                                 nf = 1
  221.                             elif 50 <= cp.real < 100:
  222.                                 ns = complex(49, 150 + (cp.real % 50))
  223.                                 nf = 2
  224.                             elif 100 <= cp.real < 150:
  225.                                 ns = complex(99, 50 + (cp.real % 100))
  226.                                 nf = 2
  227.                         elif f == 2:
  228.                             if 0 <= cp.imag < 50:
  229.                                 ns = complex(0, 149 - cp.imag)
  230.                                 nf = 0
  231.                             elif 50 <= cp.imag < 100:
  232.                                 ns = complex(cp.imag % 50, 100)
  233.                                 nf = 1
  234.                             elif 100 <= cp.imag < 150:
  235.                                 ns = complex(50, 49 - (cp.imag % 100))
  236.                                 nf = 0
  237.                             elif 150 <= cp.imag < 200:
  238.                                 ns = complex(50 + (cp.imag % 150), 0)
  239.                                 nf = 1
  240.                         elif f == 3:
  241.                             if 0 <= cp.real < 50:
  242.                                 ns = complex(50, 50 + cp.real)
  243.                                 nf = 0
  244.                             elif 50 <= cp.real < 100:
  245.                                 ns = complex(0, 150 + (cp.real % 50))
  246.                                 nf = 0
  247.                             elif 100 <= cp.real < 149:
  248.                                 ns = complex(cp.real % 100, 199)
  249.                                 nf = 3
  250.                         if b_map[ns] == '.':
  251.                             cp = ns
  252.                             f = nf
  253.                         elif b_map[ns] == '#':
  254.                             f = (f + T[turn]) % 4
  255.                             break
  256.                 else:
  257.                     f = (f + T[turn]) % 4
  258.     password = int(1000 * (cp.imag + 1) + 4 * (cp.real + 1) + f)
  259.     return password
  260.  
  261.  
  262. def main():
  263.     assert day22('test22', test=True) == 6032
  264.     print(f"Part 1: {day22('input22', test=False)}")
  265.  
  266.     assert day22('test22', test=True, part2=True) == 5031
  267.     print(f"Part 2: {day22('input22', test=False, part2=True)}")
  268.  
  269.  
  270. if __name__ == '__main__':
  271.     main()
  272.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement