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


      1import sys
      2sys.path.append("../common")
      3import aoc
      4
      5def parse_line(l):
      6    s = l.split(">")
      7    vals = list()
      8    for ss in s:
      9        if len(ss) == 0:
     10            continue
     11        ss = ss.split("<",1)[1]
     12        vals.append([int(x) for x in ss.split(",")])
     13    return vals
     14
     15data = [parse_line(l) for l in aoc.data.split("\n") if len(l) != 0]
     16posdata = [x[0] for x in data]
     17veldata = [x[1] for x in data]
     18
     19def check_adj(pi):
     20    for p in posdata:
     21        if abs(p[0] - pi[0]) + abs(p[1] - pi[1]) == 1:
     22            return True
     23    return False
     24
     25def check_data():
     26    for p in posdata:
     27        if not check_adj(p):
     28            return False
     29    return True
     30
     31def bounds():
     32    minx = None
     33    maxx = None
     34    miny = None
     35    maxy = None
     36    for p in posdata:
     37        if minx is None or p[0] < minx:
     38            minx = p[0]
     39        if maxx is None or p[0] > maxx:
     40            maxx = p[0]
     41        if miny is None or p[1] < miny:
     42            miny = p[1]
     43        if maxy is None or p[1] > maxy:
     44            maxy = p[1]
     45    return minx, maxx, miny, maxy
     46
     47def solve(part, args):
     48    count = 0
     49    distx = None
     50    disty = None
     51    while True:
     52        for i in range(len(data)):
     53            posdata[i][0] += veldata[i][0]
     54            posdata[i][1] += veldata[i][1]
     55        count += 1
     56
     57        minx, maxx, miny, maxy = bounds()
     58        if distx == None:
     59            distx = maxx - minx
     60            disty = maxy - miny
     61        else:
     62            cdistx = maxx - minx
     63            cdisty = maxy - miny
     64            if cdistx > distx or cdisty > disty:
     65                for i in range(len(data)):
     66                    posdata[i][0] -= veldata[i][0]
     67                    posdata[i][1] -= veldata[i][1]
     68                count -= 1
     69                break
     70            else:
     71                distx = cdistx
     72                disty = cdisty
     73
     74        if count % 100 == 0:
     75            aoc.debug("\r" + " " * 50, end="")
     76            aoc.debug(f"\rcluster size: {distx}, {disty}", end="")
     77
     78    if part == 1:
     79        return count
     80    elif part == 2:
     81        answer = ""
     82        minx, maxx, miny, maxy = bounds()
     83        for y in range(maxy - miny + 1):
     84            f = lambda x:  "#" if list([x + minx, y + miny]) in posdata else " "
     85            answer += "".join([f(x) for x in range(maxx - minx + 1)]) + "\n"
     86        print(repr(answer))
     87        print(repr(sol2))
     88        return answer
     89    else:
     90        assert(False)
     91
     92sol2 = """\
     93#    #  ######  #       #####   #    #  #    #   ####   #    #
     94#   #   #       #       #    #  #    #  #    #  #    #  #   # 
     95#  #    #       #       #    #  #    #   #  #   #       #  #  
     96# #     #       #       #    #  #    #   #  #   #       # #   
     97##      #####   #       #####   ######    ##    #       ##    
     98##      #       #       #    #  #    #    ##    #  ###  ##    
     99# #     #       #       #    #  #    #   #  #   #    #  # #   
    100#  #    #       #       #    #  #    #   #  #   #    #  #  #  
    101#   #   #       #       #    #  #    #  #    #  #   ##  #   # 
    102#    #  #       ######  #####   #    #  #    #   ### #  #    #
    103"""
    104
    105aoc.run(lambda args: solve(1, args), lambda args: solve(2, args), sols=[10659, sol2])