Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- class BoryaSolved(object):
- def __init__(self):
- self.num_cards = raw_input()
- cards = raw_input()
- #start = time.clock()
- self.actual_hand = cards.split(' ')
- self.ladder = Ladder(self.actual_hand)
- self.construct_clues()
- #timeit = time.clock() - start
- #print timeit
- #print self.clues
- self.num_clues_needed = list()
- self.set_up_recursion()
- self.pick_lowest()
- #timit = time.clock() - start
- #print timeit
- def construct_clues(self):
- self.clues = list()
- edges = self.ladder.edges
- #print self.ladder.edges
- for edge in edges:
- ind = edges.index(edge)
- edges.remove(edge)
- self.construct_clues_recursively([edge.value], edges)
- edges.insert(ind, edge)
- def construct_clues_recursively(self, clue_seq, edges):
- if sorted(clue_seq) not in self.clues:
- self.clues.append(sorted(clue_seq))
- if len(edges) >= 1:
- for edge in edges:
- ind = edges.index(edge)
- edges.remove(edge)
- clues = [clue for clue in clue_seq]
- clues.append(edge.value)
- self.construct_clues_recursively(clues, edges)
- edges.insert(ind, edge)
- def set_up_recursion(self):
- self.ladder.check_all_but_one()
- if not self.ladder.complete:
- for clue_seq in self.clues:
- if self.num_clues_needed:
- if len(clue_seq)<min(self.num_clues_needed):
- self.ladder = Ladder(self.actual_hand)
- for clue in clue_seq:
- self.ladder.give_clue(clue)
- if self.ladder.complete:
- #print clue_seq
- self.num_clues_needed.append(len(clue_seq))
- else:
- self.ladder = Ladder(self.actual_hand)
- for clue in clue_seq:
- self.ladder.give_clue(clue)
- if self.ladder.complete:
- self.num_clues_needed.append(len(clue_seq))
- self.ladder.clean_up()
- """
- clues = self.possible_clues
- self.ladder.check_all_but_one()
- #print self.ladder.complete
- if not self.ladder.complete:
- for clue in clues:
- #it still thinks that it is the same object
- #so make a new method that creates a new object
- lad = duplicate(self.actual_hand, self.ladder)
- lad.give_clue(clue)
- ind = clues.index(clue)
- clues.remove(clue)
- self.recurse(1, clues, lad)
- clues.insert(ind, clue)
- def recurse(self, steps, clues, ladder):
- #print ladder.clues
- if ladder.complete:
- #print ladder.clues
- self.num_clues_needed.append(steps)
- else:
- steps+=1
- for clue in clues:
- lad = duplicate(self.actual_hand, ladder)
- lad.give_clue(clue)
- ind = clues.index(clue)
- clues.remove(clue)
- self.recurse(steps, clues, lad)
- clues.insert(ind, clue)
- """
- def pick_lowest(self):
- #print self.num_clues_needed
- if self.num_clues_needed:
- print min(self.num_clues_needed)
- else:
- print 0
- class Ladder(object):
- def __init__(self, cards):
- self.rungs = list()
- self.edges = list()
- self.create_ladder(cards)
- self.complete = False
- def create_ladder(self, cards):
- edges = dict()
- for card in cards:
- if card[0] not in edges.keys():
- edges[card[0]] = Edge(card[0])
- if card[1] not in edges.keys():
- edges[card[1]] = Edge(card[1])
- rung = Rung(edges[card[0]], edges[card[1]])
- if rung not in self.rungs:
- edges[card[0]].rungs.append(rung)
- edges[card[1]].rungs.append(rung)
- self.rungs.append(rung)
- #for edge in edges.values():
- # self.edges.append(edge)
- self.edges = [edge for edge in edges.values()]
- #print self.rungs
- def give_clue(self, clue):
- for edge in self.edges:
- if edge.value == clue:
- edge.expose()
- self.check_all_but_one()
- #self.check_all_certain()
- def check_all_but_one(self):
- uncertain = [rung for rung in self.rungs if not rung.certain]
- #for rung in self.rungs:
- # if not rung.certain:
- # uncertain.append(rung)
- if len(uncertain) == 1:
- uncertain[0].certain = True
- self.complete = True
- elif len(uncertain) == 0:
- self.complete = True
- def check_all_certain(self):
- for rung in self.rungs:
- if not rung.certain:
- #print rung.edges[0].value
- return
- #print 'swag'
- self.complete = True
- def clean_up(self):
- for rung in self.rungs:
- rung.certain = False
- for edge in self.edges:
- edge.is_exposed = False
- def duplicate(cards, ladder):
- lad = Ladder(cards)
- for clue in ladder.clues:
- lad.give_clue(clue)
- #print lad.clues
- return lad
- class Edge(object):
- #rungs attribte with list of other edges that it connects to
- #is_exposed
- # value
- def __init__(self, value):
- self.rungs = list()
- self.value = value
- self.is_exposed = False
- def expose(self):
- self.is_exposed = True
- for rung in self.rungs:
- if rung.update_certainty() and rung.other_edge(self).is_exposed:
- #when every rung from an exposed edge is certain, then you make last one certain too.
- rung.other_edge(self).check_all_but_one()
- self.check_all_but_one()
- def check_all_but_one(self):
- """
- checks if the
- """
- uncertain = [rung for rung in self.rungs if not rung.certain]
- #for rung in self.rungs:
- # if not rung.certain:
- # uncertain.append(rung)
- #if len(uncertain)>1:
- # return
- if len(uncertain) == 1:
- uncertain[0].certain = True
- def __repr__(self):
- return self.value
- def __eq__(self, other):
- return self.value == other.value
- # rung has 2 edges
- # is either unknown. one-sided. two-sided (4 possibilities)
- # a side becomes known when: it's exposed, it's
- class Rung(object):
- def __init__(self, color_edge, value_edge):
- self.edges = [color_edge, value_edge]
- self.certain = False
- def update_certainty(self):
- if not self.certain:
- self.certain = self.edges[0].is_exposed and self.edges[1].is_exposed
- return self.certain
- def other_edge(self, edge):
- if edge == self.edges[0]:
- return self.edges[1]
- return self.edges[0]
- def __eq__(self, other):
- # when comparing objects, always override this eq method to get
- # results that YOU need
- return self.edges == other.edges
- def __repr__(self):
- return str([edge.value for edge in self.edges])
- if __name__ == "__main__":
- solve = BoryaSolved()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement