Advertisement
illuminati229

AoC 2022 Day 14 Fast

Dec 14th, 2022
845
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 2.05 KB | None | 0 0
  1. from time import time
  2.  
  3.  
  4. def timer_func(func):
  5.     # This function shows the execution time of
  6.     # the function object passed
  7.     def wrap_func(*args, **kwargs):
  8.         t1 = time()
  9.         result = func(*args, **kwargs)
  10.         t2 = time()
  11.         print(f'Function {func.__name__!r} executed in {(t2 - t1):.4f}s')
  12.         return result
  13.  
  14.     return wrap_func
  15.  
  16.  
  17. def tuple_add(a, b):
  18.     return tuple(c + d for c, d in zip(a, b))
  19.  
  20.  
  21. def tuple_sub(a, b):
  22.     return tuple(c - d for c, d in zip(a, b))
  23.  
  24.  
  25. def tuple_direction(a, b):
  26.     return tuple(x // abs(x) if abs(x) > 0 else 0 for x in tuple_sub(b, a))
  27.  
  28.  
  29. @timer_func
  30. def day14(filepath, part2=False):
  31.     with open(filepath) as fin:
  32.         lines = fin.readlines()
  33.  
  34.     rocks = set()
  35.     for line in lines:
  36.         for a, b in zip(line.split(' -> '), line.split(' -> ')[1:]):
  37.             a = tuple([int(x) for x in a.split(',')])
  38.             b = tuple([int(x) for x in b.split(',')])
  39.             direction = tuple_direction(a, b)
  40.             while a != b:
  41.                 rocks.add(a)
  42.                 a = tuple_add(a, direction)
  43.             rocks.add(b)
  44.     sand = set()
  45.     cave_floor = int(max([x[1] for x in rocks])) + 2
  46.     path = [(500, -1)]
  47.     more_sand = True
  48.     while more_sand:
  49.         cur = path[-1]
  50.         for step in [(0, 1), (-1, 1), (1, 1)]:
  51.             next_loc = tuple_add(cur, step)
  52.             if not part2:
  53.                 if next_loc[1] == cave_floor:
  54.                     more_sand = False
  55.                     break
  56.             if next_loc in rocks or next_loc in sand or next_loc[1] == cave_floor:
  57.                 continue
  58.  
  59.             path.append(next_loc)
  60.             break
  61.         else:
  62.             sand.add(cur)
  63.             rocks.add(cur)
  64.             path.pop()
  65.         if (500, 0) in sand:
  66.             break
  67.     return len(sand)
  68.  
  69.  
  70. def main():
  71.     assert day14('test14') == 24
  72.     print(f"Part 1: {day14('input14')}")
  73.  
  74.     assert day14('test14', True) == 93
  75.     print(f"Part 2: {day14('input14', True)}")
  76.  
  77.  
  78. if __name__ == '__main__':
  79.     main()
  80.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement