solve.py (3729B)
1import sys 2sys.path.append("../common") 3import aoc 4 5tmap = [list(l) for l in aoc.data.split("\n") if len(l) != 0] 6xlen, ylen = len(tmap[0]), len(tmap) 7 8arrows = dict() 9arrows["<"] = (-1, 0) 10arrows[">"] = (1, 0) 11arrows["^"] = (0, -1) 12arrows["v"] = (0, 1) 13 14directions = [(-1,0), (0,-1), (1, 0), (0, 1)] # l - u - r - d 15 16def check_pos(x, y): 17 if x < xlen and x >= 0 and y < ylen and y >= 0: 18 return tmap[y][x] 19 return " " 20 21def correct(x, y): 22 cr = check_pos(x+1, y) 23 cl = check_pos(x-1, y) 24 cu = check_pos(x, y-1) 25 cd = check_pos(x, y+1) 26 27 if cr == "|": cr = " " 28 if cl == "|": cl = " " 29 if cu == "-": cu = " " 30 if cd == "-": cd = " " 31 32 r = cr != " " 33 l = cl != " " 34 u = cu != " " 35 d = cd != " " 36 37 vsum = r + l + u + d 38 if vsum > 2: 39 return "+" 40 41 # 2 around 42 if r: 43 if l: 44 return "-" 45 elif u: 46 return "/" 47 else: 48 return "\\" 49 else: 50 if not l: 51 return "|" 52 elif u: 53 return "/" 54 else: 55 return "\\" 56 57carts = list() 58for y in range(ylen): 59 for x in range(xlen): 60 if tmap[y][x] in arrows: 61 carts.append([x, y, arrows[tmap[y][x]], 0, 0]) 62 tmap[y][x] = correct(x,y) 63 64def cart_at(x, y): 65 global carts 66 for i in range(len(carts)): 67 c = carts[i] 68 if c[0] == x and c[1] == y and not c[4]: 69 return i 70 return None 71 72def draw_map(): 73 for y in range(ylen): 74 f = lambda x : "".join(["#" if cart_at(x,y) != None else tmap[y][x]]) 75 aoc.debug([f(x) for x in range(len(tmap[y]))]) 76 77def advance(cart): 78 ncart = [0 for x in range(5)] 79 ncart[0] = cart[0]+cart[2][0] 80 ncart[1] = cart[1]+cart[2][1] 81 col = cart_at(ncart[0], ncart[1]) 82 if col != None: 83 return ncart[0], ncart[1], col 84 85 c = tmap[ncart[1]][ncart[0]] 86 d = directions.index(cart[2]) 87 88 if c == "+": 89 d = (d + len(directions)-1 + cart[3]) % len(directions) 90 ncart[2] = directions[d] 91 ncart[3] = (cart[3] + 1) % 3 92 else: # dont need to change direction for '-' and '|' 93 if c == "/": 94 ncart[2] = directions[3-d] 95 elif c == "\\": 96 if d == 0: #l 97 ncart[2] = directions[1] 98 elif d == 1: #u 99 ncart[2] = directions[0] 100 elif d == 2: #r 101 ncart[2] = directions[3] 102 elif d == 3: #d 103 ncart[2] = directions[2] 104 else: 105 ncart[2] = cart[2] 106 ncart[3] = cart[3] 107 return ncart 108 109 110def solve1(args): 111 global carts 112 113 crash = None 114 while not crash: 115 carts = sorted(carts, key=lambda x:(x[0], x[1])) 116 for c in range(len(carts)): 117 nc = advance(carts[c]) 118 if len(nc) == 3: 119 crash = nc 120 break 121 else: 122 carts[c] = nc 123 124 return f"{crash[0]},{crash[1]}" 125 126def solve2(args): 127 global carts 128 129 while len(carts) > 1: 130 carts = sorted(carts, key=lambda x:(x[0], x[1])) 131 rcarts = list() 132 for c in range(len(carts)): 133 if carts[c][4]: continue; 134 nc = advance(carts[c]) 135 if len(nc) == 3: 136 carts[c][4] = 1 137 carts[nc[2]][4] = 1 138 rcarts.append(carts[c]) 139 rcarts.append(carts[nc[2]]) 140 else: 141 carts[c] = nc 142 for c in rcarts: 143 if c in carts: # prevent doubles 144 carts.remove(c) 145 146 return f"{carts[0][0]},{carts[0][1]}" 147 148aoc.run(solve1, solve2)