Advertisement
illuminati229

AoC 2023 Day 14 String Method

Dec 14th, 2023
1,126
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 2.26 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 tilt_east(rock_map: tuple):
  18.     # rock map is a tuple of strings
  19.     return tuple('#'.join([''.join(sorted(p)) for p in row.split('#')]) for row in rock_map)
  20.  
  21.  
  22. def tilt_north(m: tuple):
  23.     return rotate_counterclockwise(tilt_east(rotate_clockwise(m)))
  24.  
  25.  
  26. def transpose(m: tuple):
  27.     # transposes a tuple of strings
  28.     return tuple(''.join(i) for i in list(zip(*m)))
  29.  
  30.  
  31. def flip(m: tuple):
  32.     # flip a tuple north-south
  33.     return m[::-1]
  34.  
  35.  
  36. def rotate_clockwise(m: tuple):
  37.     # rotate clockwise a tuple of string
  38.     return transpose(flip(m))
  39.  
  40.  
  41. def rotate_counterclockwise(m: tuple):
  42.     # rotate counterclockwise a tuple of strings
  43.     return flip(transpose(m))
  44.  
  45.  
  46. def spin_platform(rock_map):
  47.     for _ in range(4):
  48.         rock_map = rotate_clockwise(rock_map)
  49.         rock_map = tilt_east(rock_map)
  50.     return rock_map
  51.  
  52.  
  53. def north_load(m):
  54.     return sum([row.count('O') * i for i, row in enumerate(m[::-1], 1)])
  55.  
  56.  
  57. @timer_func
  58. def day14(filepath, part2=False):
  59.     with open(filepath) as fin:
  60.         rock_map = tuple(line.strip() for line in fin.readlines())
  61.  
  62.     if not part2:
  63.         return north_load(tilt_north(rock_map))
  64.     else:
  65.         rm_dict = {}
  66.         for i in range(1, 1000000000):
  67.             rock_map = spin_platform(rock_map)
  68.             if rock_map in rm_dict:
  69.                 loop_start = rm_dict[rock_map]
  70.                 loop_length = i - loop_start
  71.                 i_f = (1000000000 - loop_start) % loop_length + loop_start
  72.                 for rock_map, j in rm_dict.items():
  73.                     if j == i_f:
  74.                         return north_load(rock_map)
  75.             else:
  76.                 rm_dict[rock_map] = i
  77.  
  78.  
  79. def main():
  80.     assert day14('test14') == 136
  81.     print(f"Part 1: {day14('input14')}")
  82.  
  83.     assert day14('test14', True) == 64
  84.     print(f"Part 2: {day14('input14', True)}")
  85.  
  86.  
  87. if __name__ == '__main__':
  88.     main()
  89.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement