Advertisement
Guest User

Advent Day 18 Part 2

a guest
Dec 18th, 2023
123
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 2.76 KB | Software | 0 0
  1. import re
  2. import sys
  3.  
  4. def walk(plan):
  5.     x, y = 0, 0
  6.     corners = [(0, 0)]
  7.     directions = ((1, 0), (0, 1), (-1, 0), (0, -1))
  8.     for d, l, c in plan:
  9.         d, l = directions[int(c[-1])], int(c[0:-1], 16)
  10.         x, y = x + l * d[0], y + l * d[1]
  11.         corners.append((x, y))
  12.     return corners
  13.  
  14. def draw(corners):
  15.     # ensure no line or corner directly abuts another to help the flood fill
  16.     def expand(v):
  17.         return sorted(set(v + [w - 1 for w in v] + [w + 1 for w in v]))
  18.     xgrid = expand([p[0] for p in corners])
  19.     ygrid = expand([p[1] for p in corners])
  20.     xindex = dict((v, i) for i, v in enumerate(xgrid))
  21.     yindex = dict((v, i) for i, v in enumerate(ygrid))
  22.     index = [(xindex[x], yindex[y]) for x, y in corners]
  23.     i0, j0 = index[0]
  24.     field = [['.'] * len(xgrid) for y in range(len(ygrid))]
  25.     field[j0][i0] = '#'
  26.     for i1, j1 in index[1:]:
  27.         if i0 != i1:
  28.             for i in range(min(i0, i1), max(i0, i1) + 1):
  29.                 field[j0][i] = '#'
  30.         if j0 != j1:
  31.             for j in range(min(j0, j1), max(j0, j1) + 1):
  32.                 field[j][i0] = '#'
  33.         i0, j0 = i1, j1
  34.     return field, xgrid, ygrid
  35.  
  36. def fill(field, row, col):
  37.     q = [(row, col)]
  38.     while q:
  39.         r, c = q.pop()
  40.         if 0 <= r < len(field) and 0 <= c < len(field[0]):
  41.             if field[r][c] == '.':
  42.                 field[r][c] = 'o'
  43.                 q.append((r - 1, c))
  44.                 q.append((r + 1, c))
  45.                 q.append((r, c - 1))
  46.                 q.append((r, c + 1))
  47.  
  48. def count(field, xgrid, ygrid):
  49.     total = 0
  50.     for y in range(len(field)):
  51.         for x in range(len(field[0])):
  52.             if field[y][x] in ('#', '.'):
  53.                 dy = ygrid[y + 1] - ygrid[y] if field[y + 1][x] != 'o' else 1
  54.                 dx = xgrid[x + 1] - xgrid[x] if field[y][x + 1] != 'o' else 1
  55.                 total += dx * dy
  56.     return total
  57.  
  58. def fieldstr(field):
  59.     return '\n'.join(''.join(f) for f in field)
  60.  
  61. def advent_day18_part1(lines):
  62.     plan = []
  63.     for line in lines:
  64.         m = re.search(r'^(\S+) (\S+) \(#(\S+)\)', line)
  65.         if m:
  66.             d, l, c = m.groups()
  67.             l = int(l)
  68.             plan.append((d,l,c))
  69.  
  70.     corners = walk(plan)
  71.     print()
  72.     print('corners')
  73.     print(corners)
  74.  
  75.     field, xgrid, ygrid = draw(corners)
  76.     fill(field, 0, 0)
  77.     print()
  78.     print(fieldstr(field))
  79.  
  80.     print()
  81.     print(count(field, xgrid, ygrid))
  82.  
  83. def readlines(file_path):
  84.     with open(file_path, 'r') as file:
  85.         lines = [line.strip() for line in file.readlines()]
  86.     return [x for x in lines if x]
  87.  
  88. if __name__ == '__main__':
  89.     if len(sys.argv) >= 2:
  90.         lines = readlines(sys.argv[1])
  91.     else:
  92.         lines = []
  93.     advent_day18_part1(lines)
  94.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement