diff --git a/AoC2021/code/AoC23.py b/AoC2021/code/AoC23.py new file mode 100755 index 0000000..c0ea67a --- /dev/null +++ b/AoC2021/code/AoC23.py @@ -0,0 +1,109 @@ +#!/usr/bin/env python3 + +import sys +from functools import cache + +@cache +def path(f1,f2): + path = [] + y, x = f1 + while y != 0: + y -= 1 + path.append((y,x)) + while x != f2[1]: + x += 1 if f2[1] > x else -1 + path.append((y,x)) + while y != f2[0]: + y += 1 + path.append((y,x)) + assert path[-1] == f2 + return path + +def pathvalid(path,board): + for p in path: + if p in board: return False + return True + +def cost(a,w): + if a == 'A': return len(w) * 1 + if a == 'B': return len(w) * 10 + if a == 'C': return len(w) * 100 + if a == 'D': return len(w) * 1000 + +def endstate(board): + for f,a in board.items(): + if f[1] != target[a]: return False + return True + +def target_position(f,b,lowest): + a = b[f] + if f[1] != target[a]: return False + for y in range(f[0],lowest+1): + if (y,target[a]) not in b: return False + if b[(y,target[a])] != a: return False + return True + +def totarget(board,lowest): + change = False + costs = 0 + nb = {k: v for k,v in board.items()} + for f,a in board.items(): + if target_position(f,nb,lowest): continue + t = (lowest,target[a]) + while t in nb and nb[t] == a: + t = (t[0]-1,target[a]) + if t == (0,target[a]): continue + p = path(f,t) + if pathvalid(p,nb): + change = True + nb.pop(f) + nb[t] = a + costs += cost(a,p) + return nb,costs,change + +def dfs(board,lowest,costs=0,curmin=sys.maxsize): + ch = True + nb = {k: v for k,v in board.items()} + while ch: + nb,co,ch = totarget(nb,lowest) + costs += co + if endstate(nb): + return costs + if costs > curmin: return None + board = {k: v for k,v in nb.items()} + for f,a in board.items(): + if f[0] != 0 and not(target_position(f,board,lowest)): + for f2 in hallway: + p = path(f,f2) + if pathvalid(p, board): + cb = {k: v for k,v in board.items()} + cb.pop(f) + cb[f2] = a + nc = dfs(cb,lowest,costs+cost(a,p),curmin) + if nc is not None and nc < curmin: curmin = nc + if curmin < sys.maxsize: return curmin + +if __name__ == '__main__': + # challenge 1 + lines = open(sys.argv[1]).readlines() + start = {} + for y,l in enumerate(lines[1:]): + for x,f in enumerate(l[1:]): + if f in 'ABCD': start[(y,x)] = f + + hallway = [(0,0), (0,1), (0,3), (0,5), (0,7), (0,9), (0,10)] + target = {'A': 2, 'B': 4, 'C': 6, 'D': 8} + + res1 = str(dfs(start,2)) + print("challenge 1:" + "\n" + res1 + "\n") + + # challenge 2 + lines = open(sys.argv[2]).readlines() + start = {} + for y,l in enumerate(lines[1:]): + for x,f in enumerate(l[1:]): + if f in 'ABCD': start[(y,x)] = f + + res2 = str(dfs(start,4)) + print("challenge 2:" + "\n" + res2 + "\n") + diff --git a/AoC2021/inputs/input23 b/AoC2021/inputs/input23 new file mode 100644 index 0000000..6cda201 --- /dev/null +++ b/AoC2021/inputs/input23 @@ -0,0 +1,5 @@ +############# +#...........# +###A#C#B#A### + #D#D#B#C# + ######### diff --git a/AoC2021/inputs/input23-2 b/AoC2021/inputs/input23-2 new file mode 100644 index 0000000..534f76f --- /dev/null +++ b/AoC2021/inputs/input23-2 @@ -0,0 +1,7 @@ +############# +#...........# +###A#C#B#A### + #D#C#B#A# + #D#B#A#C# + #D#D#B#C# + ######### diff --git a/AoC2021/inputs/test23 b/AoC2021/inputs/test23 new file mode 100644 index 0000000..6a7120d --- /dev/null +++ b/AoC2021/inputs/test23 @@ -0,0 +1,5 @@ +############# +#...........# +###B#C#B#D### + #A#D#C#A# + ######### diff --git a/AoC2021/inputs/test23-2 b/AoC2021/inputs/test23-2 new file mode 100644 index 0000000..1e769e1 --- /dev/null +++ b/AoC2021/inputs/test23-2 @@ -0,0 +1,7 @@ +############# +#...........# +###B#C#B#D### + #D#C#B#A# + #D#B#A#C# + #A#D#C#A# + ######### diff --git a/AoC2021/inputs/test23-3 b/AoC2021/inputs/test23-3 new file mode 100644 index 0000000..647c803 --- /dev/null +++ b/AoC2021/inputs/test23-3 @@ -0,0 +1,5 @@ +############# +#.....D.D.A.# +###.#B#C#.### + #A#B#C#.# + ######### diff --git a/AoC2021/inputs/test23-4 b/AoC2021/inputs/test23-4 new file mode 100644 index 0000000..d8dc3c9 --- /dev/null +++ b/AoC2021/inputs/test23-4 @@ -0,0 +1,7 @@ +############# +#AA.D......D# +###B#.#C#.### + #D#B#C#.# + #D#B#C#.# + #A#B#C#A# + #########