Advertisement
Guest User

Untitled

a guest
Dec 14th, 2023
88
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 6.12 KB | Source Code | 0 0
  1. import time
  2.  
  3. filename = "data"
  4.  
  5. try:
  6.     with open(filename, "r") as file:
  7.         lines = file.read().splitlines()
  8.         print("File opened successfully.\n")
  9. except:
  10.     input("File '{filename}' not found. Program will now exit.\n")
  11.     exit()
  12.    
  13. for i, line in enumerate(lines):
  14.     lines[i] = [char for char in line]
  15.  
  16. y_range = range(len(lines))
  17. x_range = range(len(lines[0]))
  18. x_max = max(x_range)
  19. y_max = max(y_range)
  20. def tilt_old(_dir):
  21.  
  22.     if -1 in _dir:
  23.         y = 0
  24.        
  25.         for line in lines:
  26.             x = 0
  27.             for char in line:
  28.                 if char not in "#.":
  29.                     _y = y
  30.                     _x = x
  31.                     while ((_y + _dir[0]) in y_range) and ((_x + _dir[1]) in x_range) and lines[_y + _dir[0]][_x + _dir[1]] == '.':
  32.                         lines[_y][_x] = '.'
  33.                         lines[_y + _dir[0]][_x + _dir[1]] = 'O'
  34.                         _y += _dir[0]
  35.                         _x += _dir[1]
  36.                 x += 1
  37.             y += 1
  38.     else:
  39.         y = y_max
  40.         for line in reversed(lines):
  41.             x = x_max
  42.             for char in reversed(line):
  43.                 if char not in "#.":
  44.                     _y = y
  45.                     _x = x
  46.                     while ((_y + _dir[0]) in y_range) and ((_x + _dir[1]) in x_range) and lines[_y + _dir[0]][_x + _dir[1]] == '.':
  47.                         lines[_y][_x] = '.'
  48.                         lines[_y + _dir[0]][_x + _dir[1]] = 'O'
  49.                         _y += _dir[0]
  50.                         _x += _dir[1]
  51.                 x -= 1
  52.             y -= 1
  53.  
  54. def tilt(_dir):
  55.  
  56.     if _dir == [-1, 0]:
  57.         for x in x_range:
  58.             y = 0
  59.             while y < y_max:
  60.  
  61.                 #amount of rocks
  62.                 rocks = 0
  63.                 start = y
  64.                 while y <= y_max and lines[y][x] != '#':
  65.                     if lines[y][x] == 'O':
  66.                         rocks += 1
  67.                     y += 1
  68.  
  69.                 #print the stuff
  70.                 end = y
  71.                 for _y in range(start, end):
  72.                     if _y < rocks+start:
  73.                         lines[_y][x] = 'O'
  74.                     else:
  75.                         lines[_y][x] = '.'
  76.                 y += 1
  77.                
  78.     elif _dir == [1, 0]:
  79.         for x in x_range:
  80.             y = y_max
  81.             #print(f"\nx: {x}")
  82.             while y >= 0:
  83.  
  84.                 #amount of rocks
  85.                 rocks = 0
  86.                 start = y
  87.                 while y >= 0 and lines[y][x] != '#':
  88.                     if lines[y][x] == 'O':
  89.                         rocks += 1
  90.                     y -= 1
  91.  
  92.                 #print the stuff
  93.                 end = y
  94.                 #print(f"{rocks} rocks from {start} to {end}")
  95.                 _y = start
  96.                 while _y > end:
  97.                     if _y > start-rocks:
  98.                         lines[_y][x] = 'O'
  99.                     else:
  100.                         lines[_y][x] = '.'
  101.                     _y -= 1
  102.                 y -= 1
  103.     elif _dir == [0, -1]:
  104.         for y in y_range:
  105.             x = 0
  106.             while x < x_max:
  107.  
  108.                 #amount of rocks
  109.                 rocks = 0
  110.                 start = x
  111.                 while x <= x_max and lines[y][x] != '#':
  112.                     if lines[y][x] == 'O':
  113.                         rocks += 1
  114.                     x += 1
  115.  
  116.                 #print the stuff
  117.                 end = x
  118.                 for _x in range(start, end):
  119.                     if _x < rocks+start:
  120.                         lines[y][_x] = 'O'
  121.                     else:
  122.                         lines[y][_x] = '.'
  123.                 x += 1
  124.                
  125.     elif _dir == [0, 1]:
  126.         for y in y_range:
  127.             x = x_max
  128.             #print(f"\nx: {x}")
  129.             while x >= 0:
  130.  
  131.                 #amount of rocks
  132.                 rocks = 0
  133.                 start = x
  134.                 while x >= 0 and lines[y][x] != '#':
  135.                     if lines[y][x] == 'O':
  136.                         rocks += 1
  137.                     x -= 1
  138.  
  139.                 #print the stuff
  140.                 end = x
  141.                 #print(f"{rocks} rocks from {start} to {end}")
  142.                 _x = start
  143.                 while _x > end:
  144.                     if _x > start-rocks:
  145.                         lines[y][_x] = 'O'
  146.                     else:
  147.                         lines[y][_x] = '.'
  148.                     _x -= 1
  149.                 x -= 1
  150.                
  151.            
  152.                
  153. def cycle():
  154.     tilt([-1, 0])
  155.     tilt([0, -1])
  156.     tilt([1, 0])
  157.     tilt([0, 1])
  158.  
  159. def print_map():
  160.     for line in lines:
  161.         string = ""
  162.         for char in line:
  163.             string += char
  164.         print(string)
  165.     print("\n")
  166.  
  167. def print_index(i):
  168.     for line in states[i]:
  169.         string = ""
  170.         for char in line:
  171.             string += char
  172.         print(string)
  173.     print("\n")
  174.  
  175. def copy_2d_list(_list):
  176.     new = []
  177.     for sub_list in _list:
  178.         new.append(sub_list.copy())
  179.     return new
  180.  
  181. #save the current data for use in part 2
  182. lines2 = copy_2d_list(lines)
  183.  
  184. start = time.time()
  185. tilt([-1, 0])
  186. result = 0
  187. distance = len(lines)
  188. for line in lines:
  189.     for char in line:
  190.         if char == "O": result += distance
  191.     distance -= 1
  192. end = time.time()
  193. time_needed = end-start
  194. print(f"Part 1:\n Time needed: {round(time_needed, 3)}s\n Load: {result}\n")
  195.  
  196. #load the saved data
  197. lines = copy_2d_list(lines2)
  198.  
  199. start = time.time()
  200.  
  201. cycles_max = 1000000000
  202. states = []
  203. cycles = 0
  204.  
  205. while True:
  206.     cycle()
  207.     if lines in states:
  208.         cycle_start = states.index(lines)
  209.         cycle_end = cycles
  210.         cycle_length = cycle_end - cycle_start
  211.         break
  212.     states.append(copy_2d_list(lines))
  213.     cycles += 1
  214.  
  215. left_over = (cycles_max - cycle_start) % cycle_length
  216. lines = states[cycle_start + left_over-1]
  217.  
  218. result = 0
  219. distance = len(lines)
  220. for line in lines:
  221.     for char in line:
  222.         if char == "O": result += distance
  223.     distance -= 1
  224.  
  225. end = time.time()
  226. time_needed = end-start
  227. print(f"Part 2:\n Time needed: {round(time_needed, 3)}s\n Load: {result}\n")
  228.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement