fork download
  1.  
  2. NO = ( 0, 0, 0, 2, 0)
  3. Pi = (+1, 0, 0, 0, 0)
  4. PI = (+1, 0, 0, 0, 1)
  5. Pj = ( 0,+1, 0, 0, 0)
  6. PJ = ( 0,+1, 0, 0, 1)
  7. PK = ( 0, 0,+1, 0, 2)
  8. Mi = (-1, 0, 0, 1, 0)
  9. MI = (-1, 0, 0, 1, 1)
  10. Mj = ( 0,-1, 0, 1, 0)
  11. MJ = ( 0,-1, 0, 1, 1)
  12. MK = ( 0, 0,-1, 1, 2)
  13. # i j k ^ ^
  14. # | Id for comparison
  15. # Lifetime index
  16.  
  17. PRODUCE = {
  18. PI: [ Mj ], # +I -> -j
  19. MJ: [ Mi ], # -J -> -i
  20. MI: [ Pj ], # -I -> +j
  21. PJ: [ Pi ], # +J -> +i
  22. NO: [ NO ],
  23. Pi: [ NO ],
  24. Pj: [ NO ],
  25. Mi: [ NO ],
  26. Mj: [ NO ],
  27. PK: [ PI, MI, PJ, MJ ], # +K -> +I, -J, -I, +J
  28. MK: [ PI, MI, PJ, MJ ], # -K -> +I, -J, -I, +J
  29. }
  30.  
  31.  
  32. class Index:
  33. LastDistance = 0
  34. NumberOfVisits = 0
  35. MinIndex = 0
  36. MaxIndex = 0
  37. def __init__(self, i, j, k, lifetime, direction):
  38. self.globalLifetime = lifetime
  39. self.direction = direction
  40.  
  41. # Assign parent's position
  42. self.i = i
  43. self.j = j
  44. self.k = k
  45.  
  46. # Step away from parent
  47. self.lifetime = lifetime[direction[3]]
  48. self.step()
  49.  
  50. def isLive(self):
  51. return self.lifetime > 0
  52.  
  53. def visit(self):
  54. Index.NumberOfVisits += 1
  55. distance = self.distance()
  56. if distance < Index.LastDistance:
  57. raise NameError("Order is not preserved")
  58. Index.LastDistance = distance
  59. Index.MinIndex = min(self.i, Index.MinIndex)
  60. Index.MinIndex = min(self.j, Index.MinIndex)
  61. Index.MinIndex = min(self.k, Index.MinIndex)
  62. Index.MaxIndex = max(self.i, Index.MaxIndex)
  63. Index.MaxIndex = max(self.j, Index.MaxIndex)
  64. Index.MaxIndex = max(self.k, Index.MaxIndex)
  65. print("[{}, {}, {}]".format(self.i, self.j, self.k))
  66.  
  67. def step(self):
  68. # Move in your direction
  69. self.i += self.direction[0]
  70. self.j += self.direction[1]
  71. self.k += self.direction[2]
  72.  
  73. def iterate(self):
  74. self.lifetime -= 1
  75.  
  76. def produce(self, result):
  77. for direction in PRODUCE[self.direction]:
  78. self.create(direction, result)
  79.  
  80. def create(self, direction, result):
  81. index = Index(self.i, self.j, self.k, self.globalLifetime, direction)
  82. if index.isLive():
  83. result.append(index)
  84.  
  85. def distance(self):
  86. # Manhattan Distance
  87. return abs(self.i) + abs(self.j) + abs(self.k)
  88.  
  89. def Traverse(N):
  90. TotalNumber = N*N*N
  91. halfA = halfB = (N-1)/2
  92. if N % 2 == 0:
  93. halfA = N/2
  94. halfB = N/2-1
  95.  
  96. MinIndex = -min(halfB, halfA)
  97. MaxIndex = max(halfB, halfA)
  98.  
  99. lifetime = (halfA, halfB, 0)
  100.  
  101. SecondaryNodes = []
  102. MainNodes = []
  103. KNodes = []
  104.  
  105. # visit center
  106. center = Index(0, 0, 0, lifetime, NO)
  107. center.visit()
  108.  
  109. center.create(PI, MainNodes)
  110. center.create(MI, MainNodes)
  111. center.create(PJ, MainNodes)
  112. center.create(MJ, MainNodes)
  113. center.create(PK, KNodes)
  114. center.create(MK, KNodes)
  115.  
  116. while len(SecondaryNodes) + len(MainNodes) + len(KNodes) > 0:
  117.  
  118. # First - visit all side nodes
  119. temp = []
  120. for m in SecondaryNodes:
  121. m.visit()
  122. m.step()
  123. m.iterate()
  124. # Save node only if it is alive
  125. if m.isLive():
  126. temp.append(m)
  127.  
  128. SecondaryNodes = temp
  129.  
  130. # Second - visit all main nodes as they may produce secondary nodes
  131. temp = []
  132. for m in MainNodes:
  133. m.visit() # 1 - Visit
  134. m.produce(SecondaryNodes) # 2 - Produce second
  135. m.step() # 3 - Step
  136. m.iterate() # 4 - Lose a life
  137. if m.isLive():
  138. temp.append(m)
  139.  
  140. MainNodes = temp
  141.  
  142. # Third - visit all K nodes as they may produce main nodes
  143. temp = []
  144. for m in KNodes:
  145. m.visit()
  146. m.produce(MainNodes)
  147. m.step()
  148. m.iterate()
  149. if m.isLive():
  150. temp.append(m)
  151.  
  152. KNodes = temp
  153. if TotalNumber != Index.NumberOfVisits:
  154. raise NameError("Number of visited elements does not match {}/{}".format(Index.NumberOfVisits, TotalNumber))
  155. if MinIndex != Index.MinIndex:
  156. raise NameError("Minimal index is out of bounds {}/{}".format(Index.MinIndex, MinIndex))
  157. if MaxIndex != Index.MaxIndex:
  158. raise NameError("Maximal index is out of bounds {}/{}".format(Index.MaxIndex, MaxIndex))
  159.  
  160. Traverse(6)
Success #stdin #stdout 0.01s 9016KB
stdin
Standard input is empty
stdout
[0, 0, 0]
[1, 0, 0]
[-1, 0, 0]
[0, 1, 0]
[0, -1, 0]
[0, 0, 1]
[0, 0, -1]
[1, -1, 0]
[-1, 1, 0]
[1, 1, 0]
[-1, -1, 0]
[2, 0, 0]
[-2, 0, 0]
[0, 2, 0]
[0, -2, 0]
[1, 0, 1]
[-1, 0, 1]
[0, 1, 1]
[0, -1, 1]
[1, 0, -1]
[-1, 0, -1]
[0, 1, -1]
[0, -1, -1]
[0, 0, 2]
[0, 0, -2]
[1, -2, 0]
[-1, 2, 0]
[2, 1, 0]
[-2, -1, 0]
[2, -1, 0]
[-2, 1, 0]
[1, 2, 0]
[-1, -2, 0]
[1, -1, 1]
[-1, 1, 1]
[1, 1, 1]
[-1, -1, 1]
[1, -1, -1]
[-1, 1, -1]
[1, 1, -1]
[-1, -1, -1]
[3, 0, 0]
[0, 3, 0]
[2, 0, 1]
[-2, 0, 1]
[0, 2, 1]
[0, -2, 1]
[2, 0, -1]
[-2, 0, -1]
[0, 2, -1]
[0, -2, -1]
[1, 0, 2]
[-1, 0, 2]
[0, 1, 2]
[0, -1, 2]
[1, 0, -2]
[-1, 0, -2]
[0, 1, -2]
[0, -1, -2]
[0, 0, 3]
[-1, 3, 0]
[3, 1, 0]
[2, -2, 0]
[-2, 2, 0]
[2, 2, 0]
[-2, -2, 0]
[1, -2, 1]
[-1, 2, 1]
[2, 1, 1]
[-2, -1, 1]
[1, -2, -1]
[-1, 2, -1]
[2, 1, -1]
[-2, -1, -1]
[3, -1, 0]
[1, 3, 0]
[2, -1, 1]
[-2, 1, 1]
[1, 2, 1]
[-1, -2, 1]
[2, -1, -1]
[-2, 1, -1]
[1, 2, -1]
[-1, -2, -1]
[1, -1, 2]
[-1, 1, 2]
[1, 1, 2]
[-1, -1, 2]
[1, -1, -2]
[-1, 1, -2]
[1, 1, -2]
[-1, -1, -2]
[3, 0, 1]
[0, 3, 1]
[3, 0, -1]
[0, 3, -1]
[2, 0, 2]
[-2, 0, 2]
[0, 2, 2]
[0, -2, 2]
[2, 0, -2]
[-2, 0, -2]
[0, 2, -2]
[0, -2, -2]
[1, 0, 3]
[-1, 0, 3]
[0, 1, 3]
[0, -1, 3]
[-2, 3, 0]
[3, 2, 0]
[-1, 3, 1]
[3, 1, 1]
[-1, 3, -1]
[3, 1, -1]
[3, -2, 0]
[2, 3, 0]
[2, -2, 1]
[-2, 2, 1]
[2, 2, 1]
[-2, -2, 1]
[2, -2, -1]
[-2, 2, -1]
[2, 2, -1]
[-2, -2, -1]
[1, -2, 2]
[-1, 2, 2]
[2, 1, 2]
[-2, -1, 2]
[1, -2, -2]
[-1, 2, -2]
[2, 1, -2]
[-2, -1, -2]
[3, -1, 1]
[1, 3, 1]
[3, -1, -1]
[1, 3, -1]
[2, -1, 2]
[-2, 1, 2]
[1, 2, 2]
[-1, -2, 2]
[2, -1, -2]
[-2, 1, -2]
[1, 2, -2]
[-1, -2, -2]
[1, -1, 3]
[-1, 1, 3]
[1, 1, 3]
[-1, -1, 3]
[3, 0, 2]
[0, 3, 2]
[3, 0, -2]
[0, 3, -2]
[2, 0, 3]
[-2, 0, 3]
[0, 2, 3]
[0, -2, 3]
[3, 3, 0]
[-2, 3, 1]
[3, 2, 1]
[-2, 3, -1]
[3, 2, -1]
[-1, 3, 2]
[3, 1, 2]
[-1, 3, -2]
[3, 1, -2]
[3, -2, 1]
[2, 3, 1]
[3, -2, -1]
[2, 3, -1]
[2, -2, 2]
[-2, 2, 2]
[2, 2, 2]
[-2, -2, 2]
[2, -2, -2]
[-2, 2, -2]
[2, 2, -2]
[-2, -2, -2]
[1, -2, 3]
[-1, 2, 3]
[2, 1, 3]
[-2, -1, 3]
[3, -1, 2]
[1, 3, 2]
[3, -1, -2]
[1, 3, -2]
[2, -1, 3]
[-2, 1, 3]
[1, 2, 3]
[-1, -2, 3]
[3, 0, 3]
[0, 3, 3]
[3, 3, 1]
[3, 3, -1]
[-2, 3, 2]
[3, 2, 2]
[-2, 3, -2]
[3, 2, -2]
[-1, 3, 3]
[3, 1, 3]
[3, -2, 2]
[2, 3, 2]
[3, -2, -2]
[2, 3, -2]
[2, -2, 3]
[-2, 2, 3]
[2, 2, 3]
[-2, -2, 3]
[3, -1, 3]
[1, 3, 3]
[3, 3, 2]
[3, 3, -2]
[-2, 3, 3]
[3, 2, 3]
[3, -2, 3]
[2, 3, 3]
[3, 3, 3]