fork(2) download
  1. m = {1: 2, 7: 3, 2: 1, 4: 4, 5: 3, 6: 9}
  2. n = {1:2, 2:3, 3:4, 4:5, 5:1, 6:1, 7:1, 8:8}
  3.  
  4. cycles = set()
  5. for k, v in m.items():
  6. if m.get(v) == k:
  7. cycles.add(tuple(sorted((k, v))))
  8.  
  9. output = [[k] if k == v else (k, v) for k, v in cycles]
  10. print(output)
  11.  
  12. cycles = set(tuple(sorted(item)) for item in m.items() if m.get(item[1]) == item[0])
  13.  
  14.  
  15. output = [[k] if k == v else (k, v) for k, v in cycles]
  16. print(output)
  17.  
  18. def find_cycles(m):
  19. n = m.copy() # don't mutilate the original
  20. cycles = []
  21. while n:
  22. visited = {}
  23. count = 0
  24. k, v = n.popitem()
  25. while v is not None:
  26. visited[k] = (count, v)
  27. count += 1
  28. k = v
  29. v = n.pop(k, None)
  30.  
  31. if k in visited:
  32. cycle_start = visited[k][0]
  33. item = min((k, v) for k, (c, v) in visited.items() if c >= cycle_start)
  34. cycles.append(item)
  35.  
  36. return [[k] if k == v else (k, v) for k, v in cycles]
  37.  
  38. print(find_cycles(m))
  39. print(find_cycles(n))
  40.  
  41. def find_cycles(m):
  42. n = m.copy() # don't mutilate the original
  43. cycles = []
  44. while n:
  45. visited = {}
  46. count = 0
  47. k, v = n.popitem()
  48. while v is not None:
  49. visited[k] = count
  50. count += 1
  51. k = v
  52. v = n.pop(k, None)
  53.  
  54. if k in visited:
  55. if len(visited) == 1:
  56. cycle = list(visited.keys())
  57. else:
  58. cycle_start = visited[k]
  59. cycle = sorted((c, k) for k, c in visited.items() if c >= cycle_start)
  60. cycle = tuple(k for c, k in cycle)
  61. k = min(range(len(cycle)), key=lambda x: cycle[x])
  62. cycle = cycle[k:] + cycle[:k]
  63. cycles.append(cycle)
  64.  
  65. return cycles
  66.  
  67. print(find_cycles(m))
  68. print(find_cycles(n))
Success #stdin #stdout 0.02s 27712KB
stdin
Standard input is empty
stdout
[(1, 2), [4]]
[(1, 2), [4]]
[(1, 2), [4]]
[(1, 2), [8]]
[(1, 2), [4]]
[(1, 2, 3, 4, 5), [8]]