from lib import str_to_ints from dataclasses import dataclass from collections import defaultdict data = """ Filesystem Size Used Avail Use% /dev/grid/node-x0-y0 10T 8T 2T 80% /dev/grid/node-x0-y1 11T 6T 5T 54% /dev/grid/node-x0-y2 32T 28T 4T 87% /dev/grid/node-x1-y0 9T 7T 2T 77% /dev/grid/node-x1-y1 8T 0T 8T 0% /dev/grid/node-x1-y2 11T 7T 4T 63% /dev/grid/node-x2-y0 10T 6T 4T 60% /dev/grid/node-x2-y1 9T 8T 1T 88% /dev/grid/node-x2-y2 9T 6T 3T 66% """ @dataclass class Node: id: int x: int y: int size: int used: int avail: int usep: int def get_nodes(data): return [Node(i, *str_to_ints(line)) for i, line in enumerate(data.splitlines()[2:])] def part_1(data): c = 0 nodes = get_nodes(data) for a in nodes: for b in nodes: if a is not b and a.used != 0 and a.used <= b.avail: c += 1 print(c) def part_2(data): nodes = get_nodes(data) empty = None for n in nodes: if n.usep < 50: assert empty is None empty = (n.x, n.y) assert empty is not None grid = defaultdict(dict) for n in nodes: grid[n.x][n.y] = n cols = len(grid) steps = 0 steps += empty[1] # move space to y=0 steps += ((cols - 2) - empty[0]) # move space to x=cols-1 # shuffle target cell to (0, 0) via empty space steps += ((cols - 2) * 5) steps += 1 # Account for the fact that there is a "barrier" through which we cannot # move the space. This can be seen by uncommenting the grid print code # below. Might have been better to code a proper search from the beginning. # Clearly he enjoyed setting a bit of a trap there. steps += 15 - 3 # for y in range(rows): # for x in range(cols): # print(f"{grid[x][y].used:2} ", end='') # print() print(steps) def main(): data = open(0).read().strip() part_1(data) part_2(data) if __name__ == "__main__": main()