aoc-2018-python

Advent of Code 2018 Solutions in Python
git clone https://git.sinitax.com/sinitax/aoc-2018-python
Log | Files | Refs | README | sfeed.txt

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])