Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.

p23.py 1.5KB

1 år sedan
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. def move(old, seen, parents, special_rules):
  2. steps = [1, -1, 1j, -1j]
  3. for step in special_rules.get(graph[old], steps):
  4. new = old + step
  5. parents.setdefault(new, set()).add(old)
  6. if new in graph and new not in seen:
  7. yield new
  8. def bfs(start, special_rules):
  9. parents = {}
  10. state = {start}
  11. seen = state.copy()
  12. while state:
  13. state = {new for old in state for new in move(old, seen, parents, special_rules)}
  14. seen |= state
  15. return parents
  16. def segmentize(dense):
  17. sparse = {}
  18. for i, js in dense.items():
  19. for j in js:
  20. n = 1
  21. k = i
  22. while len(dense[j] - {k}) == 1:
  23. n += 1
  24. k, [j] = j, dense[j] - {k}
  25. sparse.setdefault(i, set()).add((j, n))
  26. return sparse
  27. def recurse(pos, parents, path=set(), n=0):
  28. if pos == start:
  29. yield n
  30. else:
  31. for parent, cost in parents[pos]:
  32. if parent not in path:
  33. yield from recurse(parent, parents, path | {pos}, n + cost)
  34. def solve(special_rules={}):
  35. dense = bfs(start, special_rules)
  36. sparse = segmentize(dense)
  37. return len(list(recurse(end, sparse)))
  38. text = open(0).read()
  39. graph = {
  40. complex(x, y): val
  41. for y, row in enumerate(text.splitlines())
  42. for x, val in enumerate(row)
  43. if val != '#'
  44. }
  45. start = min(graph, key=lambda p: (p.imag, p.real))
  46. end = max(graph, key=lambda p: (p.imag, p.real))
  47. print(solve({'<': [-1], '^': [-1j], 'v': [1j], '>': [1]}))
  48. print(solve())