90 lines
2.1 KiB
Python
90 lines
2.1 KiB
Python
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()
|