Finish 2016.
This commit is contained in:
89
2016/d22.py
Normal file
89
2016/d22.py
Normal file
@@ -0,0 +1,89 @@
|
|||||||
|
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()
|
||||||
87
2016/d23.py
Normal file
87
2016/d23.py
Normal file
@@ -0,0 +1,87 @@
|
|||||||
|
from math import factorial
|
||||||
|
|
||||||
|
|
||||||
|
def solve(data, part_2=False):
|
||||||
|
REGS = "abcd"
|
||||||
|
regs = {c: 0 for c in REGS}
|
||||||
|
|
||||||
|
if part_2:
|
||||||
|
print(factorial(12) + (91 * 85))
|
||||||
|
return
|
||||||
|
else:
|
||||||
|
regs["a"] = 7
|
||||||
|
|
||||||
|
insts = data.splitlines()
|
||||||
|
i = 0
|
||||||
|
inst_count = 0
|
||||||
|
while i < len(insts):
|
||||||
|
inst_count += 1
|
||||||
|
# print(i, regs)
|
||||||
|
parts = insts[i].split()
|
||||||
|
cmd = parts[0]
|
||||||
|
if cmd == "cpy":
|
||||||
|
if parts[1] in REGS:
|
||||||
|
regs[parts[2]] = regs[parts[1]]
|
||||||
|
else:
|
||||||
|
regs[parts[2]] = int(parts[1])
|
||||||
|
elif cmd == "jnz":
|
||||||
|
val = 0
|
||||||
|
if parts[1] in REGS:
|
||||||
|
val = regs[parts[1]]
|
||||||
|
else:
|
||||||
|
val = int(parts[1])
|
||||||
|
if val != 0:
|
||||||
|
if parts[2] in REGS:
|
||||||
|
i += regs[parts[2]]
|
||||||
|
else:
|
||||||
|
i += int(parts[2])
|
||||||
|
continue
|
||||||
|
elif cmd == "inc":
|
||||||
|
if insts[i + 1] == "dec d" and insts[i + 2] == "jnz d -2":
|
||||||
|
regs[parts[1]] += regs["d"]
|
||||||
|
regs["d"] = 0
|
||||||
|
i += 3
|
||||||
|
continue
|
||||||
|
regs[parts[1]] += 1
|
||||||
|
elif cmd == "dec":
|
||||||
|
regs[parts[1]] -= 1
|
||||||
|
elif cmd == "tgl":
|
||||||
|
off = 0
|
||||||
|
if parts[1] in REGS:
|
||||||
|
off = regs[parts[1]]
|
||||||
|
else:
|
||||||
|
off = int(parts[1])
|
||||||
|
addr = i + off
|
||||||
|
|
||||||
|
if addr < len(insts):
|
||||||
|
parts = insts[addr].split()
|
||||||
|
if len(parts) == 2:
|
||||||
|
if parts[0] == "inc":
|
||||||
|
parts[0] = "dec"
|
||||||
|
else:
|
||||||
|
parts[0] = "inc"
|
||||||
|
insts[addr] = " ".join(parts)
|
||||||
|
elif len(parts) == 3:
|
||||||
|
if parts[0] == "jnz":
|
||||||
|
parts[0] = "cpy"
|
||||||
|
else:
|
||||||
|
parts[0] = "jnz"
|
||||||
|
insts[addr] = " ".join(parts)
|
||||||
|
else:
|
||||||
|
assert False
|
||||||
|
else:
|
||||||
|
assert False
|
||||||
|
i += 1
|
||||||
|
|
||||||
|
|
||||||
|
print(regs["a"])
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
data = open(0).read().strip()
|
||||||
|
solve(data)
|
||||||
|
solve(data, True)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
61
2016/d24.py
Normal file
61
2016/d24.py
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
from collections import deque, defaultdict
|
||||||
|
from itertools import permutations
|
||||||
|
from lib import Grid2D, INF
|
||||||
|
|
||||||
|
|
||||||
|
def shortest_path(grid, start, end):
|
||||||
|
seen = set()
|
||||||
|
open = deque([(start, 0)])
|
||||||
|
|
||||||
|
while open:
|
||||||
|
current, steps = open.popleft()
|
||||||
|
if current in seen:
|
||||||
|
continue
|
||||||
|
seen.add(current)
|
||||||
|
if current == end:
|
||||||
|
return steps
|
||||||
|
for nb in grid.neighbors_ort(current):
|
||||||
|
if grid[nb] == "#":
|
||||||
|
continue
|
||||||
|
open.append((nb, steps + 1))
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def solve(data, part_2=False):
|
||||||
|
g = Grid2D(data)
|
||||||
|
# g.print()
|
||||||
|
start = g.find("0")[0]
|
||||||
|
points = g.find_not("#.")
|
||||||
|
|
||||||
|
shortest = defaultdict(defaultdict)
|
||||||
|
for i in range(len(points)):
|
||||||
|
for j in range(i + 1, len(points)):
|
||||||
|
a, b = points[i], points[j]
|
||||||
|
s = shortest_path(g, a, b)
|
||||||
|
assert s is not None
|
||||||
|
shortest[a][b] = s
|
||||||
|
shortest[b][a] = s
|
||||||
|
|
||||||
|
# Brute force all combinations.
|
||||||
|
points.remove(start)
|
||||||
|
dmin = INF
|
||||||
|
for p in permutations(points):
|
||||||
|
d = 0
|
||||||
|
d += shortest[start][p[0]]
|
||||||
|
for i in range(len(p) - 1):
|
||||||
|
d += shortest[p[i]][p[i + 1]]
|
||||||
|
if part_2:
|
||||||
|
d += shortest[p[-1]][start]
|
||||||
|
dmin = min(d, dmin)
|
||||||
|
print(dmin)
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
data = open(0).read().strip()
|
||||||
|
solve(data)
|
||||||
|
solve(data, True)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
60
2016/d25.py
Normal file
60
2016/d25.py
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
def solve(data):
|
||||||
|
REGS = "abcd"
|
||||||
|
goal = [0, 1, 0, 1, 0, 1, 0, 1]
|
||||||
|
|
||||||
|
for a in range(0, 1000):
|
||||||
|
insts = data.splitlines()
|
||||||
|
regs = {c: 0 for c in REGS}
|
||||||
|
regs["a"] = a
|
||||||
|
outs = []
|
||||||
|
i = 0
|
||||||
|
inst_count = 0
|
||||||
|
while i < len(insts):
|
||||||
|
inst_count += 1
|
||||||
|
if inst_count > 100_000:
|
||||||
|
break
|
||||||
|
parts = insts[i].split()
|
||||||
|
cmd = parts[0]
|
||||||
|
if cmd == "cpy":
|
||||||
|
if parts[1] in "abcd":
|
||||||
|
regs[parts[2]] = regs[parts[1]]
|
||||||
|
else:
|
||||||
|
regs[parts[2]] = int(parts[1])
|
||||||
|
elif cmd == "out":
|
||||||
|
if parts[1] in "abcd":
|
||||||
|
v = regs[parts[1]]
|
||||||
|
else:
|
||||||
|
v = int(parts[1])
|
||||||
|
outs.append(v)
|
||||||
|
if len(outs) == len(goal):
|
||||||
|
if outs == goal:
|
||||||
|
print(a)
|
||||||
|
return
|
||||||
|
else:
|
||||||
|
# print(outs)
|
||||||
|
pass
|
||||||
|
elif cmd == "jnz":
|
||||||
|
val = 0
|
||||||
|
if parts[1] in "abcd":
|
||||||
|
val = regs[parts[1]]
|
||||||
|
else:
|
||||||
|
val = int(parts[1])
|
||||||
|
if val != 0:
|
||||||
|
i += int(parts[2])
|
||||||
|
continue
|
||||||
|
elif cmd == "inc":
|
||||||
|
regs[parts[1]] += 1
|
||||||
|
elif cmd == "dec":
|
||||||
|
regs[parts[1]] -= 1
|
||||||
|
else:
|
||||||
|
assert False
|
||||||
|
i += 1
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
data = open(0).read().strip()
|
||||||
|
solve(data)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
Reference in New Issue
Block a user