Advertisement
Guest User

Untitled

a guest
Dec 15th, 2024
664
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 7.26 KB | Source Code | 0 0
  1. from collections import Counter
  2. from itertools import cycle
  3. from typing import Set
  4. from copy import deepcopy
  5. from time import sleep
  6.  
  7. # path = "day_15.txt"
  8. path = "test.txt"
  9.  
  10. directions = {">": (0, 1), "v": (1, 0), "<": (0, -1), "^": (-1, 0)}
  11.  
  12.  
  13. def print_grid(rows, cols, robot, walls, boxes, char):
  14.     print("move: ", char)
  15.     for r in range(rows):
  16.         print()
  17.         for c in range(cols):
  18.             if (r, c) == robot:
  19.                 print("@", end="")
  20.             elif (r, c) in walls:
  21.                 print("#", end="")
  22.             elif (r, c) in boxes:
  23.                 print("O", end="")
  24.             else:
  25.                 print(".", end="")
  26.  
  27.     print()
  28.     print('='*cols)
  29.     print()
  30.  
  31.  
  32. with open(path) as f:
  33.     input1, input2 = f.read().split("\n\n")
  34.  
  35.     grid = input1.splitlines()
  36.     commands = ''.join([i.strip() for i in input2.splitlines()])
  37.  
  38. ROWS = len(grid)
  39. COLS = len(grid[0])
  40.  
  41. # print_grid(ROWS, COLS, grid)
  42.  
  43. walls = set()
  44. boxes = set()
  45.  
  46. for row in range(ROWS):
  47.     for col in range(COLS):
  48.  
  49.         if grid[row][col] == "@":
  50.             robot = (row, col)
  51.         elif grid[row][col] == "#":
  52.             walls.add((row, col))
  53.         elif grid[row][col] == "O":
  54.             boxes.add((row, col))
  55.  
  56.  
  57. # print_grid(ROWS, COLS, robot, walls, boxes)
  58.  
  59.  
  60. def move_box(box, direction, walls, boxes: Set):
  61.     d = directions[direction]
  62.     next_tile = (box[0] + d[0], box[1] + d[1])
  63.  
  64.     if next_tile in walls:
  65.         return False, boxes
  66.  
  67.     if next_tile in boxes:
  68.         success, new_boxes = move_box(next_tile, direction, walls, boxes)
  69.         # if success:
  70.         #     return move_box(box, direction, walls, new_boxes)
  71.         if success:
  72.             return move_box(box, direction, walls, new_boxes)
  73.         else:
  74.             return False, boxes
  75.  
  76.     new_boxes = boxes
  77.     new_boxes.remove(box)
  78.     new_boxes.add(next_tile)
  79.  
  80.     return True, new_boxes
  81.  
  82.  
  83. def move(obj, direction, walls, boxes):
  84.     d = directions[direction]
  85.     next_tile = (obj[0] + d[0], obj[1] + d[1])
  86.  
  87.     if next_tile in walls:
  88.         return obj, boxes
  89.  
  90.     if next_tile in boxes:
  91.         success, new_boxes = move_box(next_tile, direction, walls, boxes)
  92.         if success:
  93.             return next_tile, new_boxes
  94.         else:
  95.             return obj, boxes
  96.  
  97.     return next_tile, boxes
  98.  
  99. boxes_1 = deepcopy(boxes)
  100. robot_1 = robot
  101. for char in commands:
  102.     robot_1, boxes_1 = move(robot_1, char, walls, boxes_1)
  103.     # print_grid(ROWS, COLS, robot, walls, boxes, char)
  104.  
  105. p1 = sum([100*i[0] + i[1] for i in boxes_1])
  106.  
  107. print(p1)
  108.  
  109. print_grid(ROWS, COLS, robot_1, walls, boxes_1, char)
  110.  
  111. def convert_p2(obj, is_robot):
  112.     r,c = obj
  113.    
  114.     new_c = 2*c
  115.    
  116.     if is_robot:
  117.         return (r, new_c), None
  118.    
  119.     return (r, new_c), (r, new_c+1)
  120.  
  121. walls_2 = set()
  122. ## https://stackoverflow.com/questions/3204245/how-do-i-convert-a-tuple-of-tuples-to-a-one-dimensional-list-using-list-comprehe
  123. walls_2.update(sum((convert_p2(i, False) for i in walls), ()))
  124. boxes_2 =set([convert_p2(i, False) for i in boxes])
  125. # print(boxes_2)
  126. robot_2, _ = convert_p2(robot, True)
  127. ROWS_2 = ROWS
  128. COLS_2 = COLS * 2
  129.  
  130. def print_grid2(rows, cols, robot, walls, boxes, char):
  131.     b = cycle('[]')
  132.     plain_boxes = set()
  133.     plain_boxes.update([tile for box in boxes for tile in box])
  134.     print("move: ", char)
  135.     for r in range(rows):
  136.         print()
  137.         for c in range(cols):
  138.             if (r, c) == robot:
  139.                 print("@", end="")
  140.             elif (r, c) in walls:
  141.                 print("#", end="")
  142.             elif (r, c) in plain_boxes:
  143.                 print(next(b), end="")
  144.             else:
  145.                 print(".", end="")
  146.  
  147.     print()
  148.     print('='*cols)
  149.     print()
  150.  
  151. # print_grid2(ROWS_2, COLS_2, robot_2, walls_2, boxes_2, '')
  152.  
  153. def possible_vertical(next_tiles):
  154.    
  155.     left = next_tiles[0]
  156.     right = next_tiles[1]
  157.    
  158.     return ((left[0], left[1] - 1), left), (left, right), (right, (right[0], right[1]+1))
  159.    
  160.  
  161. def move_box_2(box, direction, walls, boxes: Set):
  162.     d = directions[direction]
  163.    
  164.     next_tile_left = (box[0][0] + d[0], box[0][1] + d[1])
  165.     next_tile_right = (box[1][0] + d[0], box[1][1] + d[1])
  166.    
  167.     next_box = (next_tile_left, next_tile_right)
  168.     new_boxes = deepcopy(boxes)
  169.    
  170.     if next_tile_left in walls or next_tile_right in walls:
  171.         return False, boxes
  172.    
  173.     if direction == '>' and (next_tile_right, (next_tile_right[0] + d[0], next_tile_right[1] + d[1])) in boxes:
  174.         success, new_boxes = move_box_2((next_tile_right, (next_tile_right[0] + d[0], next_tile_right[1] + d[1])), direction, walls, boxes)
  175.        
  176.         if not success:
  177.             return False, boxes
  178.        
  179.     if direction == '<' and ((next_tile_left[0] + d[0], next_tile_left[1] + d[1]), next_tile_left) in boxes:
  180.         success, new_boxes = move_box_2(((next_tile_left[0] + d[0], next_tile_left[1] + d[1]), next_tile_left), direction, walls, boxes)
  181.        
  182.         if not success:
  183.             return False, boxes
  184.        
  185.     if direction in '^v' and any([i in boxes for i in possible_vertical(next_box)]):
  186.         next_boxes = [i for i in possible_vertical(next_box) if i in boxes]
  187.        
  188.         new_boxes = deepcopy(boxes)
  189.         for b in next_boxes:
  190.             success, new_boxes = move_box_2(b, direction, walls, new_boxes)
  191.             if not success:
  192.                 return False, boxes
  193.        
  194.     new_boxes.remove(box)
  195.     new_boxes.add(next_box)
  196.  
  197.     return True, new_boxes
  198.  
  199. def move_2(robot, direction, walls, boxes):
  200.     d = directions[direction]
  201.     next_tile = (robot[0] + d[0], robot[1] + d[1])
  202.  
  203.     new_boxes = deepcopy(boxes)
  204.     robot_possible_vertical = [((next_tile[0], next_tile[1] - 1), next_tile), (next_tile, (next_tile[0], next_tile[1] + 1))]
  205.  
  206.     if next_tile in walls:
  207.         return robot, boxes
  208.    
  209.     if direction in '>' and (next_tile, (next_tile[0] + d[0], next_tile[1] + d[1])) in boxes:
  210.         success, new_boxes = move_box_2((next_tile, (next_tile[0] + d[0], next_tile[1] + d[1])), direction, walls, boxes)
  211.        
  212.         if not success:
  213.             return robot, boxes
  214.     elif direction in '<' and ((next_tile[0] + d[0], next_tile[1] + d[1]), next_tile) in boxes:
  215.         success, new_boxes = move_box_2(((next_tile[0] + d[0], next_tile[1] + d[1]), next_tile), direction, walls, boxes)
  216.        
  217.         if not success:
  218.             return robot, boxes
  219.     elif direction in '^v' and any(i in boxes for i in robot_possible_vertical):
  220.         next_box = [i for i in robot_possible_vertical if i in boxes][0]
  221.        
  222.         new_boxes = deepcopy(boxes)
  223.         success, new_boxes = move_box_2(next_box, direction, walls, new_boxes)
  224.         if not success:
  225.             return robot, boxes
  226.    
  227.     return next_tile, new_boxes
  228.  
  229. print_grid2(ROWS_2, COLS_2, robot_2, walls_2, boxes_2, 'no move')
  230.  
  231. speed = 0.5/float(input('Choose a speed between 1 and 10: '))
  232. i = 0
  233. for char in commands:
  234.     robot_2, boxes_2 = move_2(robot_2, char, walls_2, boxes_2)
  235.     percentage = i/len(commands) * 100
  236.     print(f'{percentage:.2f}%')
  237.     i+=1
  238.     print_grid2(ROWS_2, COLS_2, robot_2, walls_2, boxes_2, char)
  239.     sleep(speed)
  240.  
  241. print('100.00%')
  242.  
  243. p2 = sum([100*i[0][0] + i[0][1] for i in boxes_2])
  244.  
  245. print("Part 2: ", p2)
  246.  
  247. input('END')
  248.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement