Guest User

Untitled

a guest
May 27th, 2018
77
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.50 KB | None | 0 0
  1. import sys
  2. __all__ = ['Road']
  3.  
  4. class Road(object):
  5. def __add__(self, lengths):
  6. return self.insert(*lengths)
  7.  
  8. def clear(self):
  9. self.start = None
  10. self.end = None
  11. return self
  12.  
  13. def find(self, *lengths):
  14. return lengths in self
  15.  
  16. def __init__(self):
  17. self.start = None
  18. self.end = None
  19.  
  20. def insert(self, a_len, b_len, c_len=0):
  21. if self.start is None and self.end is None:
  22. self.start = start_left, start_right = Node(), Node()
  23. self.end = end_left, end_right = Node(), Node()
  24. start_left.next = a_len, end_left
  25. start_right.next = b_len, end_right
  26. end_left.sideways = c_len, end_right
  27. end_right.sideways = c_len, end_left
  28. else:
  29. end_left, end_right = self.end
  30. new_end_left, new_end_right = Node(), Node()
  31. end_left.next = a_len, new_end_left
  32. end_right.next = b_len, new_end_right
  33. new_end_left.sideways = c_len, new_end_right
  34. new_end_right.sideways = c_len, new_end_left
  35. self.end = new_end_left, new_end_right
  36. return self
  37.  
  38. def __iter__(self):
  39. if self.start is None:
  40. return
  41. current = start_left, start_right = self.start
  42. while current != self.end:
  43. current_left, current_right = current
  44. a_len, next_left = current_left.next
  45. b_len, next_right = current_right.next
  46. c_len, _ = next_left.sideways
  47. current = next_left, next_right
  48. yield a_len, b_len, c_len
  49.  
  50. def iter_r(self, current_left = None, current_right = None):
  51. if current_left is None and current_right is None:
  52. if self.start is None:
  53. return
  54. else:
  55. current_left, current_right = self.start
  56. if (current_left, current_right) == self.end:
  57. return
  58. else:
  59. a_len, next_left = current_left.next
  60. b_len, next_right = current_right.next
  61. c_len, _ = next_left.sideways
  62. yield a_len, b_len, c_len
  63. for a,b,c, in self.iter_r(next_left, next_right):
  64. yield a,b,c
  65.  
  66. def load(self, filename):
  67. self.clear()
  68. lines = open(filename, 'r')
  69. sections_num = int(lines.next())
  70. for x in xrange(0, sections_num-1):
  71. a = int(lines.next())
  72. b = int(lines.next())
  73. c = int(lines.next())
  74. self.insert(a,b,c)
  75. a = int(lines.next())
  76. b = int(lines.next())
  77. self.insert(a,b)
  78. return self
  79.  
  80. def path(self):
  81. left_price, right_price = 0, 0
  82. left_path, right_path = [], []
  83. current = current_left, current_right = self.start
  84. while (current_left, current_right) != self.end:
  85. a_len, next_left = current_left.next
  86. b_len, next_right = current_right.next
  87. c_len, _ = next_right.sideways
  88. if a_len + left_price <= b_len + c_len + right_price:
  89. new_left_price = left_price + a_len
  90. new_left_path = left_path[:]
  91. new_left_path.append('a')
  92. else:
  93. new_left_price = right_price + b_len + c_len
  94. new_left_path = right_path[:]
  95. new_left_path.append('b')
  96. new_left_path.append('r')
  97. if b_len + right_price <= a_len + c_len + left_price:
  98. new_right_price = right_price + b_len
  99. new_right_path = right_path[:]
  100. new_right_path.append('b')
  101. else:
  102. new_right_price = left_price + a_len + c_len
  103. new_right_path = left_path[:]
  104. new_right_path.append('a')
  105. new_right_path.append('r')
  106. left_price = new_left_price
  107. right_price = new_right_price
  108. left_path = new_left_path
  109. right_path = new_right_path
  110. current_left, current_right = next_left, next_right
  111. for path in left_path, right_path:
  112. if path[-1:] == ['r']: path.pop()
  113. if left_price <= right_price:
  114. return left_price, ''.join(left_path)
  115. else:
  116. return right_price, ''.join(right_path)
  117.  
  118. def path_r(self):
  119. price, path = self._path_r(0, [], 0, [])
  120. if path[-1:] == ['r']:
  121. path.pop()
  122. return price, ''.join(path)
  123.  
  124. def _path_r(self, left_price, left_path, right_price, right_path, current_left = None, current_right = None):
  125. if current_left is None and current_right is None:
  126. current_left, current_right = self.start
  127. if (current_left, current_right) == self.end:
  128. return (left_price, left_path) if left_price <= right_price else (right_price, right_path)
  129. else:
  130. a_len, next_left = current_left.next
  131. b_len, next_right = current_right.next
  132. c_len, _ = next_right.sideways
  133. if a_len + left_price <= b_len + c_len + right_price:
  134. new_left_price = left_price + a_len
  135. new_left_path = left_path[:]
  136. new_left_path.append('a')
  137. else:
  138. new_left_price = right_price + b_len + c_len
  139. new_left_path = right_path[:]
  140. new_left_path.append('b')
  141. new_left_path.append('r')
  142. if b_len + right_price <= a_len + c_len + left_price:
  143. new_right_price = right_price + b_len
  144. new_right_path = right_path[:]
  145. new_right_path.append('b')
  146. else:
  147. new_right_price = left_price + a_len + c_len
  148. new_right_path = left_path[:]
  149. new_right_path.append('a')
  150. new_right_path.append('r')
  151. return self._path_r(new_left_price, new_left_path, new_right_price, new_right_path, next_left, next_right)
  152.  
  153. def __str__(self):
  154. if self.start is None:
  155. return "| empty |"
  156. else:
  157. return ''.join("""
  158. | |
  159. %3d %3d
  160. |_%3d_| """ % (a, b, c) for a,b,c in self)
  161.  
  162.  
  163. class Node(object):
  164. def __init__(self, next=None, sideways=None):
  165. self.next = (0, None) if next is None else next
  166. self.sideways = (0, None) if sideways is None else sideways
  167.  
  168.  
  169. if __name__ == '__main__':
  170. sys.setrecursionlimit(10000000)
  171. road = Road()
  172. road.load('test10000_2.txt')
Add Comment
Please, Sign In to add comment