| import collections | import collections | ||||
| import re | import re | ||||
| from pathlib import Path | |||||
| import sys | |||||
| def read_in(): | def read_in(): | ||||
| grid = collections.defaultdict(lambda: ' ') | grid = collections.defaultdict(lambda: ' ') | ||||
| for _ in Path('y2018/p17.dat').read_text().splitlines(): | |||||
| for _ in sys.stdin.read().splitlines(): | |||||
| _ = _.replace(',', ';') | _ = _.replace(',', ';') | ||||
| _ = re.sub(r'(\d+)\.\.(\d+)', r'range(\1, \2 + 1)', _) | _ = re.sub(r'(\d+)\.\.(\d+)', r'range(\1, \2 + 1)', _) | ||||
| _ = re.sub(r'=(\d+)', r'=[\1]', _) | _ = re.sub(r'=(\d+)', r'=[\1]', _) | ||||
| def write_out(grid, path): | def write_out(grid, path): | ||||
| xmin, *_, xmax = sorted(x for x, y in grid) | |||||
| ymin, *_, ymax = sorted(y for x, y in grid) | |||||
| text = '\n'.join( | text = '\n'.join( | ||||
| ''.join(grid[x, y] for x in range(xmin - 5, xmax + 5)) | ''.join(grid[x, y] for x in range(xmin - 5, xmax + 5)) | ||||
| for y in range(ymin, ymax + 1) | for y in range(ymin, ymax + 1) | ||||
| ) | ) | ||||
| Path(path).write_text(text) | |||||
| with open('p17out.dat', 'w') as fp: | |||||
| fp.write(text) | |||||
| def flow(start): | |||||
| def flow(grid, start, ymax): | |||||
| stack = [start] | stack = [start] | ||||
| while stack: | while stack: | ||||
| x, y = stack.pop() | x, y = stack.pop() | ||||
| grid[x, y] = '~' | grid[x, y] = '~' | ||||
| if y > ymax: | |||||
| if y >= ymax: | |||||
| break | break | ||||
| for dx, dy in [(1, 0), (-1, 0), (0, 1)]: | for dx, dy in [(1, 0), (-1, 0), (0, 1)]: | ||||
| if grid[new] == ' ': | if grid[new] == ' ': | ||||
| stack.append(new) | stack.append(new) | ||||
| drain((x, y)) | |||||
| drain(grid, (x, y), ymax) | |||||
| def drain(end): | |||||
| def drain(grid, end, ymax): | |||||
| stack = [end] | stack = [end] | ||||
| while stack: | while stack: | ||||
| x, y = stack.pop() | x, y = stack.pop() | ||||
| left, right, below = grid[x - 1, y], grid[x + 1, y], grid[x, y + 1] | left, right, below = grid[x - 1, y], grid[x + 1, y], grid[x, y + 1] | ||||
| if all([right == ' ', left == '|', below != '|']): | if all([right == ' ', left == '|', below != '|']): | ||||
| flow((x + 1, y)) | |||||
| flow(grid, (x + 1, y), ymax) | |||||
| for dx, dy in [(-1, 0), (1, 0), (0, -1)]: | for dx, dy in [(-1, 0), (1, 0), (0, -1)]: | ||||
| new = x + dx, y + dy | new = x + dx, y + dy | ||||
| grid = read_in() | grid = read_in() | ||||
| xmin, *_, xmax = sorted(x for x, y in grid) | |||||
| ymin, *_, ymax = sorted(y for x, y in grid) | |||||
| flow((500, 0)) | |||||
| ymin, *_, ymax = sorted(y for x, y in grid if grid[x, y] == '#') | |||||
| flow(grid, (500, ymin), ymax) | |||||
| counter = collections.Counter(grid.values()) | counter = collections.Counter(grid.values()) | ||||
| print(counter['~'] + counter['|']) | print(counter['~'] + counter['|']) | ||||
| print(counter['~']) | print(counter['~']) |