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 (3729B)


      1import sys
      2sys.path.append("../common")
      3import aoc
      4
      5tmap = [list(l) for l in aoc.data.split("\n") if len(l) != 0]
      6xlen, ylen = len(tmap[0]), len(tmap)
      7
      8arrows = dict()
      9arrows["<"] = (-1, 0)
     10arrows[">"] = (1, 0)
     11arrows["^"] = (0, -1)
     12arrows["v"] = (0, 1)
     13
     14directions = [(-1,0), (0,-1), (1, 0), (0, 1)] # l - u - r - d
     15
     16def check_pos(x, y):
     17    if x < xlen and x >= 0 and y < ylen and y >= 0:
     18        return tmap[y][x]
     19    return " "
     20
     21def correct(x, y):
     22    cr = check_pos(x+1, y)
     23    cl = check_pos(x-1, y)
     24    cu = check_pos(x, y-1)
     25    cd = check_pos(x, y+1)
     26
     27    if cr == "|": cr = " "
     28    if cl == "|": cl = " "
     29    if cu == "-": cu = " "
     30    if cd == "-": cd = " "
     31
     32    r = cr != " "
     33    l = cl != " "
     34    u = cu != " "
     35    d = cd != " "
     36
     37    vsum = r + l + u + d
     38    if vsum > 2:
     39        return "+"
     40
     41    # 2 around
     42    if r:
     43        if l:
     44            return "-"
     45        elif u:
     46            return "/"
     47        else:
     48            return "\\"
     49    else:
     50        if not l:
     51            return "|"
     52        elif u:
     53            return "/"
     54        else:
     55            return "\\"
     56
     57carts = list()
     58for y in range(ylen):
     59    for x in range(xlen):
     60        if tmap[y][x] in arrows:
     61            carts.append([x, y, arrows[tmap[y][x]], 0, 0])
     62            tmap[y][x] = correct(x,y)
     63
     64def cart_at(x, y):
     65    global carts
     66    for i in range(len(carts)):
     67        c = carts[i]
     68        if c[0] == x and c[1] == y and not c[4]:
     69            return i
     70    return None
     71
     72def draw_map():
     73    for y in range(ylen):
     74        f = lambda x : "".join(["#" if cart_at(x,y) != None else tmap[y][x]])
     75        aoc.debug([f(x) for x in range(len(tmap[y]))])
     76
     77def advance(cart):
     78    ncart = [0 for x in range(5)]
     79    ncart[0] = cart[0]+cart[2][0]
     80    ncart[1] = cart[1]+cart[2][1]
     81    col = cart_at(ncart[0], ncart[1])
     82    if col != None:
     83        return ncart[0], ncart[1], col
     84
     85    c = tmap[ncart[1]][ncart[0]]
     86    d = directions.index(cart[2])
     87
     88    if c == "+":
     89        d = (d + len(directions)-1 + cart[3]) % len(directions)
     90        ncart[2] = directions[d]
     91        ncart[3] = (cart[3] + 1) % 3
     92    else: # dont need to change direction for '-' and '|'
     93        if c == "/":
     94            ncart[2] = directions[3-d]
     95        elif c == "\\":
     96            if d == 0: #l
     97                ncart[2] = directions[1]
     98            elif d == 1: #u
     99                ncart[2] = directions[0]
    100            elif d == 2: #r
    101                ncart[2] = directions[3]
    102            elif d == 3: #d
    103                ncart[2] = directions[2]
    104        else:
    105            ncart[2] = cart[2]
    106        ncart[3] = cart[3]
    107    return ncart
    108
    109
    110def solve1(args):
    111    global carts
    112
    113    crash = None
    114    while not crash:
    115        carts = sorted(carts, key=lambda x:(x[0], x[1]))
    116        for c in range(len(carts)):
    117            nc = advance(carts[c])
    118            if len(nc) == 3:
    119                crash = nc
    120                break
    121            else:
    122                carts[c] = nc
    123
    124    return f"{crash[0]},{crash[1]}"
    125
    126def solve2(args):
    127    global carts
    128
    129    while len(carts) > 1:
    130        carts = sorted(carts, key=lambda x:(x[0], x[1]))
    131        rcarts = list()
    132        for c in range(len(carts)):
    133            if carts[c][4]: continue;
    134            nc = advance(carts[c])
    135            if len(nc) == 3:
    136                carts[c][4] = 1
    137                carts[nc[2]][4] = 1
    138                rcarts.append(carts[c])
    139                rcarts.append(carts[nc[2]])
    140            else:
    141                carts[c] = nc
    142        for c in rcarts:
    143            if c in carts: # prevent doubles
    144                carts.remove(c)
    145
    146    return f"{carts[0][0]},{carts[0][1]}"
    147
    148aoc.run(solve1, solve2)