Advertisement
raultres

Hanabi_Borya_2

Aug 19th, 2014
236
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.99 KB | None | 0 0
  1. class BoryaSolved(object):
  2. def __init__(self):
  3. self.num_cards = raw_input()
  4. cards = raw_input()
  5. #start = time.clock()
  6. self.actual_hand = cards.split(' ')
  7. self.ladder = Ladder(self.actual_hand)
  8. self.construct_clues()
  9. #timeit = time.clock() - start
  10. #print timeit
  11. #print self.clues
  12. self.num_clues_needed = list()
  13. self.set_up_recursion()
  14. self.pick_lowest()
  15. #timit = time.clock() - start
  16. #print timeit
  17.  
  18. def construct_clues(self):
  19. self.clues = list()
  20. edges = self.ladder.edges
  21. #print self.ladder.edges
  22. for edge in edges:
  23. ind = edges.index(edge)
  24. edges.remove(edge)
  25. self.construct_clues_recursively([edge.value], edges)
  26. edges.insert(ind, edge)
  27.  
  28. def construct_clues_recursively(self, clue_seq, edges):
  29. if sorted(clue_seq) not in self.clues:
  30. self.clues.append(sorted(clue_seq))
  31. if len(edges) >= 1:
  32. for edge in edges:
  33. ind = edges.index(edge)
  34. edges.remove(edge)
  35. clues = [clue for clue in clue_seq]
  36. clues.append(edge.value)
  37. self.construct_clues_recursively(clues, edges)
  38. edges.insert(ind, edge)
  39.  
  40. def set_up_recursion(self):
  41. self.ladder.check_all_but_one()
  42. if not self.ladder.complete:
  43. for clue_seq in self.clues:
  44. if self.num_clues_needed:
  45. if len(clue_seq)<min(self.num_clues_needed):
  46. self.ladder = Ladder(self.actual_hand)
  47. for clue in clue_seq:
  48. self.ladder.give_clue(clue)
  49. if self.ladder.complete:
  50. #print clue_seq
  51. self.num_clues_needed.append(len(clue_seq))
  52. else:
  53. self.ladder = Ladder(self.actual_hand)
  54. for clue in clue_seq:
  55. self.ladder.give_clue(clue)
  56. if self.ladder.complete:
  57. self.num_clues_needed.append(len(clue_seq))
  58. self.ladder.clean_up()
  59.  
  60.  
  61.  
  62. """
  63. clues = self.possible_clues
  64. self.ladder.check_all_but_one()
  65. #print self.ladder.complete
  66. if not self.ladder.complete:
  67. for clue in clues:
  68. #it still thinks that it is the same object
  69. #so make a new method that creates a new object
  70. lad = duplicate(self.actual_hand, self.ladder)
  71. lad.give_clue(clue)
  72. ind = clues.index(clue)
  73. clues.remove(clue)
  74. self.recurse(1, clues, lad)
  75. clues.insert(ind, clue)
  76.  
  77. def recurse(self, steps, clues, ladder):
  78. #print ladder.clues
  79. if ladder.complete:
  80. #print ladder.clues
  81. self.num_clues_needed.append(steps)
  82. else:
  83. steps+=1
  84. for clue in clues:
  85. lad = duplicate(self.actual_hand, ladder)
  86. lad.give_clue(clue)
  87. ind = clues.index(clue)
  88. clues.remove(clue)
  89. self.recurse(steps, clues, lad)
  90. clues.insert(ind, clue)
  91. """
  92. def pick_lowest(self):
  93. #print self.num_clues_needed
  94. if self.num_clues_needed:
  95. print min(self.num_clues_needed)
  96. else:
  97. print 0
  98.  
  99. class Ladder(object):
  100. def __init__(self, cards):
  101. self.rungs = list()
  102. self.edges = list()
  103. self.create_ladder(cards)
  104. self.complete = False
  105.  
  106. def create_ladder(self, cards):
  107. edges = dict()
  108. for card in cards:
  109. if card[0] not in edges.keys():
  110. edges[card[0]] = Edge(card[0])
  111. if card[1] not in edges.keys():
  112. edges[card[1]] = Edge(card[1])
  113. rung = Rung(edges[card[0]], edges[card[1]])
  114. if rung not in self.rungs:
  115. edges[card[0]].rungs.append(rung)
  116. edges[card[1]].rungs.append(rung)
  117. self.rungs.append(rung)
  118. #for edge in edges.values():
  119. # self.edges.append(edge)
  120. self.edges = [edge for edge in edges.values()]
  121. #print self.rungs
  122.  
  123. def give_clue(self, clue):
  124. for edge in self.edges:
  125. if edge.value == clue:
  126. edge.expose()
  127. self.check_all_but_one()
  128. #self.check_all_certain()
  129.  
  130. def check_all_but_one(self):
  131. uncertain = [rung for rung in self.rungs if not rung.certain]
  132. #for rung in self.rungs:
  133. # if not rung.certain:
  134. # uncertain.append(rung)
  135. if len(uncertain) == 1:
  136. uncertain[0].certain = True
  137. self.complete = True
  138. elif len(uncertain) == 0:
  139. self.complete = True
  140.  
  141. def check_all_certain(self):
  142. for rung in self.rungs:
  143. if not rung.certain:
  144. #print rung.edges[0].value
  145. return
  146. #print 'swag'
  147. self.complete = True
  148.  
  149. def clean_up(self):
  150. for rung in self.rungs:
  151. rung.certain = False
  152. for edge in self.edges:
  153. edge.is_exposed = False
  154.  
  155. def duplicate(cards, ladder):
  156. lad = Ladder(cards)
  157. for clue in ladder.clues:
  158. lad.give_clue(clue)
  159. #print lad.clues
  160. return lad
  161.  
  162. class Edge(object):
  163. #rungs attribte with list of other edges that it connects to
  164. #is_exposed
  165. # value
  166. def __init__(self, value):
  167. self.rungs = list()
  168. self.value = value
  169. self.is_exposed = False
  170.  
  171. def expose(self):
  172. self.is_exposed = True
  173. for rung in self.rungs:
  174. if rung.update_certainty() and rung.other_edge(self).is_exposed:
  175. #when every rung from an exposed edge is certain, then you make last one certain too.
  176. rung.other_edge(self).check_all_but_one()
  177. self.check_all_but_one()
  178.  
  179. def check_all_but_one(self):
  180. """
  181. checks if the
  182. """
  183. uncertain = [rung for rung in self.rungs if not rung.certain]
  184. #for rung in self.rungs:
  185. # if not rung.certain:
  186. # uncertain.append(rung)
  187. #if len(uncertain)>1:
  188. # return
  189. if len(uncertain) == 1:
  190. uncertain[0].certain = True
  191.  
  192. def __repr__(self):
  193. return self.value
  194.  
  195. def __eq__(self, other):
  196. return self.value == other.value
  197.  
  198.  
  199. # rung has 2 edges
  200. # is either unknown. one-sided. two-sided (4 possibilities)
  201. # a side becomes known when: it's exposed, it's
  202. class Rung(object):
  203. def __init__(self, color_edge, value_edge):
  204. self.edges = [color_edge, value_edge]
  205. self.certain = False
  206.  
  207. def update_certainty(self):
  208. if not self.certain:
  209. self.certain = self.edges[0].is_exposed and self.edges[1].is_exposed
  210. return self.certain
  211.  
  212. def other_edge(self, edge):
  213. if edge == self.edges[0]:
  214. return self.edges[1]
  215. return self.edges[0]
  216.  
  217. def __eq__(self, other):
  218. # when comparing objects, always override this eq method to get
  219. # results that YOU need
  220. return self.edges == other.edges
  221.  
  222. def __repr__(self):
  223. return str([edge.value for edge in self.edges])
  224.  
  225. if __name__ == "__main__":
  226. solve = BoryaSolved()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement