def get_move(loc, d): if d == DIR.UP: return util.vecadd(loc, (0, -1)) if d == DIR.LEFT: return util.vecadd(loc, (-1, 0)) if d == DIR.DOWN: return util.vecadd(loc, (0, 1)) if d == DIR.RIGHT: return util.vecadd(loc, (1, 0)) assert (False)
def trees_on_slope(l, v): loc = (0, 0) trees = 0 while loc[1] < len(l): i = loc[0] % len(l[loc[1]]) if l[loc[1]][i] == "#": trees = trees + 1 loc = util.vecadd(loc, v) return trees
def visible_8_filled(loc, s): vecs = util.adj8((0, 0)) count = 0 for v in vecs: newloc = loc while True: newloc = util.vecadd(newloc, v) if newloc in s: if s[newloc] == "L": break elif s[newloc] == "#": count += 1 break else: break return count
"e": (1, 0), "ne": (0, 1), "w": (-1, 0), "nw": (-1, 1), "se": (1, -1), "sw": (0, -1) } locs = set() for line in l: loc = (0, 0) i = 0 while i < len(line): c = line[i] if c in {"e", "w"}: loc = util.vecadd(loc, str_to_vec[c]) else: loc = util.vecadd(loc, str_to_vec[c + line[i + 1]]) i += 1 i += 1 if loc in locs: locs.remove(loc) else: locs.add(loc) print("Part 1 Solution:") print(len(locs)) for _ in range(100): # adj_count contains a map from every location that matters (locations in locs or locations # adjacent to locs) to how many neighbors it has that are flipped
print("ERROR") raise ValueError('bad char') fn = "./in.txt" l = util.filetowordlistlist(fn, ",") locations = {} for i in range(len(l)): wire = l[i] currloc = (0, 0) dist_to = 0 for inst in wire: d = chartovec(inst[0]) m = int(inst[1:]) for j in range(m): currloc = util.vecadd(currloc, d) dist_to += 1 if not currloc in locations: locations[currloc] = {} locations[currloc][i] = dist_to bestloc = None bestdist = None beststeps = None for key in locations: locdict = locations[key] if 0 in locdict and 1 in locdict: steps = locdict[0] + locdict[1] if beststeps == None or steps < beststeps: beststeps = steps if len(locdict.keys()) == 2 and key != (0,0):
curr_bott = start curr_top = start botts = [] tops = set() for i in range(2000): botts.append(curr_bott) tops.add(curr_top) c_bott = intcode.Computer(get_input(curr_bott[0], curr_bott[1] + 1)) if c_bott.calc() == 1: curr_bott = (curr_bott[0], curr_bott[1] + 1) else: curr_bott = (curr_bott[0] + 1, curr_bott[1]) c_top = intcode.Computer(get_input(curr_top[0] + 1, curr_top[1])) if c_top.calc() == 1: curr_top = (curr_top[0] + 1, curr_top[1]) else: curr_top = (curr_top[0], curr_top[1] + 1) ans = None i = 0 square_size = 100 while ans == None: if util.vecadd((square_size - 1, 1 - square_size), botts[i]) in tops: ans = util.vecadd((0, 1 - square_size), botts[i]) else: i += 1 print("Part 2") print(ans[0] * 10000 + ans[1])
def draw_game(panels, offset, loc): for key in panels: if key == loc: util.print_at_loc(util.vecadd(key, offset), "0") else: util.print_at_loc(util.vecadd(key, offset), n_to_c(panels[key][0]))
def draw_game(panels, offset): for key in panels: util.print_at_loc(util.vecadd(key, offset), n_to_c(panels[key]))
def draw_oxygen(new_oxygen_locs, offset): for l in new_oxygen_locs: util.print_at_loc(util.vecadd(l, offset), 'o')
def draw_maze(panels, offset): for p in panels: util.print_at_loc(util.vecadd(p, offset), n_to_c(panels[p][0]))
def draw_game(new_panel, offset, new_loc, old_loc): util.print_at_loc(util.vecadd(old_loc, offset), ".") if new_panel != None: util.print_at_loc(util.vecadd(new_panel[0], offset), new_panel[1]) util.print_at_loc(util.vecadd(new_loc, offset), "0")
util.print_at_loc((1, 1), "Part 1") util.print_at_loc((1, 2), len(panels)) state = {} for q in range(len(b)): state[q] = b[q] c = (state, 0, 0) panels = {} panels[(0, 0)] = 1 loc = (0, 0) direction = DIR.UP while True: if not loc in panels: panels[loc] = 0 done, outputs, vals = calc_with_input([panels[loc]], c[0], c[1], c[2]) c = vals panels[loc] = outputs[0] if outputs[1] == 0: direction = get_left(direction) else: direction = get_right(direction) loc = get_move(loc, direction) if done: break util.print_at_loc((1, 3), "Part 2") for key in panels: char = "." if panels[key] == 0 else "#" util.print_at_loc(util.vecadd(key, (1, 4)), char) print("")
# Vector math is very precise. Fortunately, I had part 1 set up in such # a way that part 2 was straightforward. fn = f"{os.path.dirname(__file__)}/in.txt" l = util.filetolist(fn) loc = (0, 0) vec = (1, 0) for line in l: action = line[0] val = int(line[1:]) if action == "N": loc = util.vecadd((0, val), loc) elif action == "S": loc = util.vecadd((0, -1 * val), loc) elif action == "E": loc = util.vecadd((val, 0), loc) elif action == "W": loc = util.vecadd((-1 * val, 0), loc) elif action == "L": numturns = int(val / 90) for i in range(numturns): vec = (-1 * vec[1], vec[0]) elif action == "R": numturns = int(val / 90) for i in range(numturns): vec = (vec[1], -1 * vec[0]) elif action == "F":
locs_to_tiles = {(0, 0): corner} tiles_to_locs = {corner: (0, 0)} active_tiles = {corner} done_tiles = set() fixed_tiles = {corner: tiles[corner]} while len(active_tiles) > 0: active_tile = active_tiles.pop() done_tiles.add(active_tile) neighbor_ids = edges[active_tile] for id in neighbor_ids: if not id in done_tiles: active_tiles.add(id) fixed_tiles[id] = orient_tile(fixed_tiles[active_tile], tiles[id]) piece_loc = util.vecadd( tiles_to_locs[active_tile], get_tile_vector(fixed_tiles[active_tile], fixed_tiles[id])) locs_to_tiles[piece_loc] = id tiles_to_locs[id] = piece_loc supertile = [] minx = min(locs_to_tiles, key=lambda x: x[0])[0] for y in range( max(locs_to_tiles, key=lambda x: x[1])[1], min(locs_to_tiles, key=lambda x: x[1])[1] - 1, -1): rowgroup = [] for x in range(minx, max(locs_to_tiles, key=lambda x: x[0])[0] + 1): if x == minx: for r in fixed_tiles[locs_to_tiles[(x, y)]][1:-1]: rowgroup.append(r[1:-1]) else: