def part1(): G = [] for line in open(getFilePath('input18.txt'),'r').readlines(): G.append(list(line.strip())) R = len(G) C = len(G[0]) DR = [-1,0,1,0] DC = [0,1,0,-1] Q = deque() State = namedtuple('State', ['r', 'c', 'keys', 'd']) all_keys = set() for r in range(R): for c in range(C): if G[r][c]=='@': #print(r,c,G[r][c]) Q.append(State(r, c, set(), 0)) if 'a'<=G[r][c]<='z': all_keys.add(G[r][c]) #print(len(all_keys), all_keys) SEEN = set() print('Calculating required steps',end='',flush=True) while Q: S = Q.popleft() key = (S.r, S.c, tuple(sorted(S.keys))) if key in SEEN: continue SEEN.add(key) if len(SEEN)%250000 == 0: print('.',end='',flush=True) if not (0<=S.r<R and 0<=S.c<C and G[S.r][S.c]!='#'): continue if 'A'<=G[S.r][S.c]<='Z' and G[S.r][S.c].lower() not in S.keys: continue newkeys = set(S.keys) if 'a'<=G[S.r][S.c]<='z': newkeys.add(G[S.r][S.c]) if newkeys == all_keys: print('\n%d'%S.d) return for d in range(4): rr,cc = S.r+DR[d], S.c+DC[d] Q.append(State(rr, cc, newkeys, S.d+1))
# adventofcode.com # Day 15 # https://adventofcode.com/2019/day/15 import common, math import intcode as icp from intpoint import IntPoint from typing import Dict, Tuple DroneMap = Dict[int, Dict[int, int]] PROGRAM_PATH = common.getFilePath('input15.txt') f = open(PROGRAM_PATH, 'r') # Droid Status Codes DS_WALL = 0 # Droid hit wall. Did not move. DS_MOVE = 1 # Droid moved successfully. DS_ONO2 = 2 # Droid moved successfully and is on the O2 System. DS_P = {-1:'start', DS_WALL: 'wall', DS_MOVE: 'move', DS_ONO2: 'success'} MAP_P = {DS_WALL: "█", DS_MOVE:".", DS_ONO2:"O"} # Droid Movement Codes DM_N = 1 # Move North DM_S = 2 # Move South DM_W = 3 # Move West DM_E = 4 # Move East DM_P = {DM_N: 'north', DM_E: 'east', DM_S: 'south', DM_W: 'west'}
# adventofcode.com # Day 6 # https://adventofcode.com/2019/day/6 import common f = open(common.getFilePath('input6.txt'), 'r') orbit_data = f.read().splitlines() orbits = dict() planets = set() for orbit in orbit_data: link = orbit.split(')') planets.add(link[1]) orbits.setdefault(link[1], link[0]) obc = 0 for planet in planets: p = planet while p != "COM": obc += 1 p = orbits.get(p, "") def getPathToCOM(planet, orbit_map): path = dict() p = orbit_map.get(planet, "") step = 0 while p != "COM": step += 1 p = orbit_map.get(p, "")
pq = [] distance2 = dict() def isSmaller2(portalTuple, level, distance): if((portalTuple, level) not in distance2): return True else: return distance2[(portalTuple, level)] < distance heapq.heappush(pq, (0, ("AA", 0), 0)) while(len(pq) != 0): (distance, portalTuple, level) = heapq.heappop(pq) if(portalTuple == ("ZZ", 0) and level == 0): print(distance) break else: for nextPortalTuple in dist[portalTuple]: nextPortal, dLevel = nextPortalTuple #End up at opposite portal, so -dLevel instead newLevel = level - dLevel newDist = distance + dist[portalTuple][nextPortalTuple] if(newLevel < 0 or (nextPortal == "ZZ" and newLevel != 0) or (nextPortal == "AA")): #Illegal moves continue if(isSmaller2(nextPortalTuple, newLevel, newDist)): heapq.heappush(pq, (newDist, nextPortalTuple, newLevel)) distance2[(nextPortalTuple, newLevel)] = newDist main(getFilePath('input20.txt'))
buffer = "" for layer in reversed(self.layers): idx = 0 for pixel in layer: if pixel == 0: processed[idx] = ' ' elif pixel == 1: processed[idx] = '█' idx += 1 idx = 0 while len(processed): buffer += processed.pop(0) idx += 1 if idx == self.width: buffer += '\n' idx = 0 return buffer IMG_PATH = common.getFilePath('input8.txt') IMG_WIDTH = 25 IMG_HEIGHT = 6 i = Image(IMG_WIDTH, IMG_HEIGHT) i.loadFile(IMG_PATH) print(i.checksum()) print(i.render())
# https://adventofcode.com/2019/day/20 from common import getFilePath from intpoint import IntPoint import array import time from typing import Dict, Tuple, Set, List import re t_start = time.time() named = re.compile('\w\w') U, D, L, R = IntPoint(0, -1), IntPoint(0, 1), IntPoint(-1, 0), IntPoint(1, 0) FILE_PATH = getFilePath('input20_sample.txt') def idx(inP: IntPoint, inW: int, inH: int) -> int: return inP.x + inP.y * inW a: array = array.array('u') f = open(FILE_PATH, 'r') input = list(f.read()) w, h = 0, 0 x, y = 0, 0 for c in input: #print(c, end='', flush=True) w = max(x, w) h = max(y, h)
def part2(): G = [] for line in open(getFilePath('input18_2.txt')).readlines(): G.append(list(line.strip())) R = len(G) C = len(G[0]) DR = [-1,0,1,0] DC = [0,1,0,-1] Q = deque() State = namedtuple('State', ['pos', 'keys', 'd']) all_doors = {} all_keys = {} starts = [] for r in range(R): for c in range(C): if G[r][c]=='@': starts.append((r,c)) if 'a'<=G[r][c]<='z': all_keys[G[r][c]] = (r,c) if 'A'<=G[r][c]<='Z': all_doors[G[r][c]] = (r,c) print(len(all_keys), all_keys) print(len(all_doors), all_doors) Q.append(State(starts, set(), 0)) N = len(starts) best = 1e9 SEEN = {} while Q: S = Q.popleft() key = (tuple(S.pos), tuple(sorted(S.keys))) if key in SEEN and S.d>=SEEN[key]: continue SEEN[key] = S.d if len(SEEN)%10000 == 0: print(key,S.d) print(len(SEEN)) newkeys = set(S.keys) bad = False for i in range(N): r,c = S.pos[i] if not (0<=r<R and 0<=c<C and G[r][c]!='#'): bad = True break if 'A'<=G[r][c]<='Z' and G[r][c].lower() not in S.keys: bad = True print('B2') break if bad: continue D = {} Q2 = deque() for i in range(N): Q2.append((S.pos[i], i, 0)) while Q2: pos,robot,dd = Q2.popleft() r,c = pos if not (0<=r<R and 0<=c<C and G[r][c]!='#'): continue if 'A'<=G[r][c]<='Z' and G[r][c].lower() not in S.keys: continue if pos in D: continue D[pos] = (dd,robot) for d3 in range(4): newpos = (r+DR[d3], c+DC[d3]) Q2.append((newpos, robot,dd+1)) for k in all_keys: if k not in S.keys and all_keys[k] in D: distance,robot = D[all_keys[k]] newpos = list(S.pos) newpos[robot] = all_keys[k] newkeys = set(S.keys) newkeys.add(k) newdist = S.d+distance if len(newkeys) == len(all_keys): if newdist < best: best = newdist print(best) Q.append(State(newpos, newkeys, newdist))
return True else: return newDist < bfDist[newNodes][intKeyMap] while(len(pq)!=0): curDist, curKeyMap, curNodes = heapq.heappop(pq) if(curKeyMap == fullKeys): print(curDist) break else: for bot in range(4): if(reachableKeys[startNodes[bot]]&curKeyMap == reachableKeys[startNodes[bot]]): continue curNode = curNodes[bot] for newNode in newNodeDist[curNode]: newDist = curDist + newNodeDist[curNode][newNode] newNodesList = list(curNodes) newNodesList[bot] = newNode newNodes = "".join(newNodesList) newKeyMap = curKeyMap if(newNode.isupper()): if(keyIntDict[newNode.lower()]&curKeyMap == 0): continue elif(newNode.islower()): newKeyMap |= keyIntDict[newNode] if(newIsSmaller(newDist, newNodes, newKeyMap)): bfDist[newNodes][newKeyMap] = newDist heapq.heappush(pq, (newDist, newKeyMap, newNodes)) main(getFilePath('input18.txt'))
# adventofcode.com # Day 22 # https://adventofcode.com/2019/day/22 import common, math from collections import deque from typing import Tuple INPUT = common.getFilePath('input22.txt') # Card shuffling # Deal: Reverse list order # Cut: Move start of list # Positive cuts shift start index forward. # Negative cuts shift start index backwards, # wrapping around if required. # Deal w/ Increment: def cut(d: deque, count: int = 0) -> None: if count == 0: return d.rotate(-count) def deal(d: deque, count: int = 0) -> None: if count == 0: d.reverse() return _d: deque = d.copy()
# adventofcode.com # Day 23 # https://adventofcode.com/2019/day/23 from common import getFilePath import intcode as icp from typing import Dict, Tuple, Set, List PROGRAM_PATH = getFilePath('input23.txt') class Network: def __init__(self, program: str, size: int): self.computers: List[icp.Thread] = [] self.program: str = program self.size: int = size self.NAT: Tuple[int, int] = None self.idleCycles = 0 def boot(self) -> None: for i in range(self.size): _thread = icp.Thread(icp.loadProgram(self.program)) # Set IP _thread.addInput(i) _thread.id = i self.computers.append(_thread) #print('Booting %d...' % _thread.id) def tick(self) -> bool: processing = False
# adventofcode.com # Day 3 # https://adventofcode.com/2019/day/3 import common with open(common.getFilePath('input3.txt')) as f: inpt = f.read() path1, path2 = inpt.strip().split('\n') deltas = {'R': (1, 0), 'L': (-1, 0), 'U': (0, 1), 'D': (0, -1)} def find_points(directions): steps, curr_x, curr_y = 0, 0, 0 points = set() step_counts = {} for dir in directions.split(','): d, l = dir[:1], int(dir[1:]) dx, dy = deltas[d] for _ in range(l): curr_x += dx curr_y += dy steps += 1 points.add((curr_x, curr_y)) step_counts.setdefault((curr_x, curr_y), steps) return points, step_counts
# adventofcode.com # Day 19 # https://adventofcode.com/2019/day/19 from common import getFilePath import intcode as icp from typing import Dict, Tuple, Set, List core = icp.Thread(icp.loadProgram(getFilePath('input19.txt'))) def scan(x: int, y: int) -> int: t = core.clone() t.istream.append(x) t.istream.append(y) while not t.didSucceed(): t.process() return t.readOutput() def checkPoint(left:int, bottom:int) -> Tuple[int, int, int]: top = bottom - 99 right = left + 99 return (scan(right,top),left,top) def part1(): strength = 0 for y in range(50): for x in range(50):