예제 #1
0
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))
예제 #2
0
# 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'}
예제 #3
0
# 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, "")
예제 #4
0
    
    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'))
예제 #5
0
        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())
예제 #6
0
# 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)
예제 #7
0
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))
예제 #8
0
      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'))
  
예제 #9
0
# 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()
예제 #10
0
# 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
예제 #11
0
# 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

예제 #12
0
# 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):