10_pipes.py 1.1 KB

123456789101112131415161718192021222324252627282930313233343536
  1. #!/usr/bin/env python3
  2. import sys
  3. UP, DOWN, LEFT, RIGHT = DIRECTIONS = (0, -1), (0, 1), (-1, 0), (1, 0)
  4. CONN = {'|': (UP, DOWN), '-': (LEFT, RIGHT), '7': (LEFT, DOWN),
  5. 'J': (LEFT, UP), 'L': (UP, RIGHT), 'F': (RIGHT, DOWN)}
  6. def parse(inp):
  7. graph = {}
  8. for y, line in enumerate(inp):
  9. for x, char in enumerate(line.rstrip()):
  10. graph[(x, y)] = [(x + dx, y + dy) for dx, dy in CONN.get(char, ())]
  11. if char == 'S':
  12. sx, sy = start = x, y
  13. graph[start] = [(sx + dx, sy + dy) for dx, dy in DIRECTIONS
  14. if start in graph.get((sx + dx, sy + dy), [])]
  15. return graph, start
  16. def loop(graph, start):
  17. path = [start]
  18. nex = graph[start][0]
  19. while nex != start:
  20. path.append(nex)
  21. nex = next(nb for nb in graph[nex] if nb != path[-2])
  22. return path
  23. def inner(border):
  24. b = len(border)
  25. x, y = zip(*border)
  26. area = abs(sum(x[i] * y[(i + 1) % b] - y[i] * x[(i + 1) % b]
  27. for i in range(b))) // 2 # Shoelace formula
  28. return area - b // 2 + 1 # Pick's theorem
  29. border = loop(*parse(sys.stdin))
  30. print(len(border) // 2)
  31. print(inner(border))