Dag: 10
Språk: Python
NORTH = 0
EAST = 1
SOUTH = 2
WEST = 3
indir2outdir = {
('|', NORTH): NORTH,
('|', SOUTH): SOUTH,
('-', EAST): EAST,
('-', WEST): WEST,
('L', WEST): NORTH,
('L', SOUTH): EAST,
('J', EAST): NORTH,
('J', SOUTH): WEST,
('7', NORTH): WEST,
('7', EAST): SOUTH,
('F', NORTH): EAST,
('F', WEST): SOUTH
}
fitting_tile = {} # Used to replace 'S' with a fitting tile
for (tile, dir1), dir2 in indir2outdir.items():
fitting_tile[(dir2, dir1)] = tile
def read_lines(filename):
lines = open(f'day10/{filename}.txt').read().splitlines()
lines.insert(0, '.' * len(lines[0]))
lines.append('.' * len(lines[0]))
lines = [f'.{line}.' for line in lines]
m = {}
for i, line in enumerate(lines):
for j, c in enumerate(line):
if c == 'S':
start = (i, j)
m[(i, j)] = c
return lines, m, start
def next_dir(tile, dir):
return indir2outdir.get((tile, dir), -1)
def next_pos(pos, dir):
if dir == NORTH:
return (pos[0]-1, pos[1])
elif dir == EAST:
return (pos[0], pos[1]+1)
elif dir == SOUTH:
return (pos[0]+1, pos[1])
elif dir == WEST:
return (pos[0], pos[1]-1)
# Part 1
def walk(m, start):
for dir in [NORTH, EAST, SOUTH, WEST]:
start_dir = dir
pos = start
if next_dir(m[next_pos(pos, dir)], dir) != -1:
on_loop = set()
steps = 0
while steps == 0 or m[pos] != 'S':
on_loop.add(pos)
end_dir = dir
pos = next_pos(pos, dir)
dir = next_dir(m[pos], dir)
steps += 1
# Replace 'S' with a fitting tile (used in part 2)
m[start] = fitting_tile[(start_dir, end_dir)]
return (steps//2, on_loop)
# Part 2. Count number of collisions (odd => inside)
def count_inside(lines, m, on_loop):
inside = 0
for i in range(len(lines)):
count = 0
for j in range(len(lines[0])):
if (i, j) in on_loop:
if m[(i, j)] in '|LJ': # ignore other tiles ("collinear")
count += 1
elif count % 2 == 1:
inside += 1
return inside
def solve(filename):
lines, m, start = read_lines(filename)
distance, on_loop = walk(m, start)
inside = count_inside(lines, m, on_loop)
return (distance, inside)
assert solve('input') == (4, 1)
assert solve('input2') == (8, 1)
assert solve('input3') == (23, 4)
assert solve('input4') == (22, 4)
assert solve('input5') == (70, 8)
assert solve('input6') == (80, 10)
#assert solve('input_real') == ...
print('OK')