#!/usr/bin/env python # -*- encoding: utf-8; py-indent-offset: 4 -*- # Author: Sebastian Mark # CC-BY-SA (https://creativecommons.org/licenses/by-sa/4.0/deed.de) # pylint: disable=missing-module-docstring,missing-function-docstring,consider-using-f-string import re import copy DIRECTION = { "^": (-1, 0), "v": (1, 0), "<": (0, -1), ">": (0, 1), } def readinput(): with open("input", "r", encoding="utf-8") as file: lines = file.readlines() sep = lines.index("\n") warehouse = [] for line in lines[:sep]: warehouse.append(list(line.strip())) directions = "" for line in lines[sep + 1 :]: directions += line.strip() return warehouse, directions def find_robot(warehouse: list) -> tuple: for y, line in enumerate(warehouse): try: x = line.index("@") except ValueError: continue return (y, x) def run_robot_run(warehouse: list, robot: tuple, directions: list) -> list: sorted_warehouse = copy.deepcopy(warehouse) roboty, robotx = robot for d in directions: dy, dx = DIRECTION[d] nxty = roboty + dy nxtx = robotx + dx # check for border in front of robot if sorted_warehouse[nxty][nxtx] == "#": continue # check stack of boxes boxes = [] bxchky, bxchkx = nxty, nxtx while sorted_warehouse[bxchky][bxchkx] == "O": boxes.append((bxchky, bxchkx)) bxchky += dy bxchkx += dx # check for border after last box if sorted_warehouse[bxchky][bxchkx] == "#": continue # move boxes for box in boxes: sorted_warehouse[box[0] + dy][box[1] + dx] = "O" # move robot sorted_warehouse[roboty][robotx] = "." sorted_warehouse[nxty][nxtx] = "@" roboty, robotx = nxty, nxtx return sorted_warehouse def calc_gps_sum(warehouse: list) -> int: gps_sum = 0 for y, line in enumerate(warehouse): boxes = re.finditer("O", "".join(line)) for box in boxes: gps_sum += 100 * y + box.start() return gps_sum def print_area(area: list): for line in area: print("".join(line)) def main(): warehouse, directions = readinput() # part 1 robot = find_robot(warehouse) unclutterd_warehouse = run_robot_run(warehouse, robot, directions) gps_sum = calc_gps_sum(unclutterd_warehouse) print("GPS sum: %d" % gps_sum) if __name__ == "__main__": main()