solve.py (3547B)
1import sys 2sys.path.append("../common") 3import aoc 4from copy import deepcopy 5 6data = list(aoc.data) 7 8def get_map(p): 9 return vmap[p[1] + spos[1]][p[0] + spos[0]] 10 11def set_map(p, c): 12 global vmap, spos 13 vmap[p[1] + spos[1]][p[0] + spos[0]] = c 14 15def new_pos(p, c): 16 p = p[:] 17 if c == "N": 18 p[1] -= 2 19 elif c == "S": 20 p[1] += 2 21 elif c == "W": 22 p[0] -= 2 23 elif c == "E": 24 p[0] += 2 25 return p 26 27def calc_pos(stack): 28 p = [0,0] 29 for c in stack: 30 p = new_pos(p, c) 31 return p 32 33xmin = 0 34xmax = 0 35ymin = 0 36ymax = 0 37 38def check_size(stack): 39 global xmin, xmax, ymin, ymax 40 41 p = calc_pos(stack) 42 if p[0] < xmin: 43 xmin = p[0] 44 if p[0] > xmax: 45 xmax = p[0] 46 if p[1] < ymin: 47 ymin = p[1] 48 if p[1] > ymax: 49 ymax = p[1] 50 51def draw_route(stack): 52 p = calc_pos(stack) 53 set_map(p, ".") 54 np = new_pos(p, stack[-1]) 55 cp = [0,0] 56 cp[0] = p[0] + int((p[0] - np[0])/2) 57 cp[1] = p[1] + int((p[1] - np[1])/2) 58 set_map(cp, "+") 59 60def iter_regex(func): 61 stacklens = [0] 62 stack = [] 63 for i in range(1, len(data)-1): 64 c = data[i] 65 if c == "(": 66 stacklens.append(0) 67 elif c == "|": 68 for i in range(stacklens[-1]): 69 stack.pop() 70 stacklens[-1] = 0 71 elif c == ")": 72 for i in range(stacklens[-1]): 73 stack.pop() 74 stacklens.pop() 75 else: 76 stack.append(c) 77 stacklens[-1] += 1 78 func(stack) 79 80def fwriteMap(): 81 f = open("output", "w+") 82 for y in range(len(vmap)): 83 f.write("".join([str(v) for v in vmap[y]]) + "\n") 84 f.close() 85 86mshape = None 87spos = None 88vmap = None 89 90def genMap(): 91 global vmap, mshape, spos 92 93 iter_regex(check_size) 94 xdif = xmax - xmin + 2 95 ydif = ymax - ymin + 2 96 97 spos = (-xmin+1, -ymin+1) 98 mshape = (xdif, ydif) 99 100 vmap = [["#" for x in range(xdif+1)] for y in range(ydif+1)] 101 vmap[spos[1]][spos[0]] = "X" 102 103 iter_regex(draw_route) 104 105 106adjacent = ((-1, 0), (0, -1), (1, 0), (0, 1)) 107 108def gen_countmap(sp): 109 countmap = dict() 110 next = dict() 111 next[(sp[0], sp[1])] = 0 112 counter = 0 113 steps = list() 114 while len(next) > 0 and len(steps) == 0: # first steps available will be shortest 115 countmap = {**countmap, **next} # merge dictionaries 116 counter += 1 117 temp = dict() 118 for n in next: 119 for dir in adjacent: 120 nx = n[0]+dir[0] 121 ny = n[1]+dir[1] 122 if get_map((nx, ny)) != "#" and (nx, ny) not in countmap and (nx, ny) not in temp: 123 temp[(nx,ny)] = counter 124 next = temp 125 return countmap 126 127def next_step(cmap, p): 128 # adjacent squares 129 npos = [[p[0] + dir[0], p[1] + dir[1]] for dir in adjacent] 130 131 # steps and dist 132 steps = [[np[0], np[1], cmap[np[0], np[1]]] for np in npos if (np[0], np[1]) in cmap] 133 134 if len(steps) == 0: 135 return None 136 else: 137 return sorted(steps, key = lambda x: x[2])[0] #closest 138 139genMap() 140 141def solve1(args): 142 cmap = gen_countmap((0,0)) 143 ipos = sorted(cmap, key = lambda x : cmap[x])[-1] 144 return int(cmap[ipos]/2) 145 146def solve2(args): 147 cmap = gen_countmap((0,0)) 148 count = len([v for v in cmap if int(cmap[v]/2) >= 1000 and get_map(v) == "."]) 149 return count 150 151aoc.run(solve1, solve2, sols=[4121, 8636])