Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- from enum import Enum
- class Borya(object):
- def __init__(self):
- self.num_cards = raw_input()
- cards = raw_input()
- self.actual_hand = self.get_cards(cards)
- self.hand = self.get_possibilities()
- self.counts = self.construct_counts()
- self.clues = self.construct_clues()
- self.duplicate_check()
- while not self.not_done():
- self.give_clue()
- self.narrow_possibilities()
- self.duplicate_check()
- print 10 - len(self.clues)
- def get_cards(self, cards):
- cards = cards.split(' ')
- cards = [HanabiCard(card[0], int(card[1])) for card in cards]
- return cards
- def get_possibilities(self):
- hand = list()
- for card in self.actual_hand:
- cards = list()
- for card in self.actual_hand:
- cards.append(card)
- hand.append(cards)
- return hand
- def construct_counts(self):
- counts = dict()
- counts['colors'] = dict()
- counts['numbers'] = dict()
- for card in self.actual_hand:
- if card.color.name not in counts['colors']:
- counts['colors'][card.color.name] = 0
- if card.number not in counts['numbers']:
- counts['numbers'][card.number] = 0
- for card in self.actual_hand:
- counts['colors'][card.color.name] += 1
- counts['numbers'][card.number] += 1
- counts = self.delete_small_counts('colors', counts)
- counts = self.delete_small_counts('numbers', counts)
- return counts
- def delete_small_counts(self, category, counts):
- counts_dict = counts[category]
- min = counts_dict.values()[0]
- min_key = counts_dict.keys()[0]
- for key, value in counts_dict.iteritems():
- if value<=min:
- min = value
- min_key = key
- #print min_key
- counts[category] = {key: value for key, value in \
- counts[category].iteritems() if key != min_key}
- return counts
- def construct_clues(self):
- clues = Color.__members__.keys()
- for i in range(1,6):
- clues.append(i)
- #print clues
- return clues
- def duplicate_check(self):
- for card_num in range(len(self.hand)):
- possibilities = self.hand[card_num]
- if all(card == possibilities[0] for card in possibilities):
- possibilities = [possibilities[0]]
- self.purge(possibilities[0], card_num)
- def purge(self, card, card_num):
- for card_number in range(len(self.hand)):
- if not card_number == card_num:
- possibilities = self.hand[card_number]
- for possibility in possibilities:
- if card == possibility:
- possibilities.remove(possibility)
- break
- def not_done(self):
- for possibilities in self.hand:
- if len(possibilities)>1:
- return False
- return True
- def give_clue(self):
- #print 'clue!'
- clue = self.find_max_count()
- #print clue
- #if clue is None:
- #raise Exception("clue is none! wtf")
- if clue in self.clues:
- self.clues.remove(clue)
- self.update_hand_using_clue(clue)
- #else:
- #raise Exception("same clue twice? wtf")
- def find_max_count(self):
- maximum = 0
- clue = None
- for color, value in self.counts['colors'].items():
- if color in self.clues:
- if value>=maximum:
- maximum = value
- clue = color
- for number, value in self.counts['numbers'].items():
- if number in self.clues:
- if value>=maximum:
- maximum = value
- clue = number
- return clue
- def update_hand_using_clue(self, clue):
- for card_num in range(len(self.actual_hand)):
- card = self.actual_hand[card_num]
- characteristics = list()
- if type(clue) is int:
- if card.number == clue:
- characteristics = range(1,6)
- characteristics.remove(clue)
- # "doesn't match number"
- else:
- #print "matched number"
- characteristics.append(clue)
- else:
- if card.color == Color[clue]:
- characteristics = Color.__members__.keys()
- characteristics.remove(clue)
- #print 'doesnt match color'
- else:
- characteristics.append(Color[clue])
- #print 'matches color'
- self.purge_characteristic(card_num, characteristics)
- def purge_characteristic(self, card_num, characteristics):
- #print 'purge character!'
- #print characteristics
- if type(characteristics[0]) is int:
- for characteristic in characteristics:
- possibility_num = 0
- while possibility_num<len(self.hand[card_num]):
- possibility = self.hand[card_num][possibility_num]
- if possibility.number == characteristic:
- self.hand[card_num].remove(possibility)
- else:
- possibility_num+=1
- else:
- for characteristic in characteristics:
- possibility_num = 0
- while possibility_num<len(self.hand[card_num]):
- possibility = self.hand[card_num][possibility_num]
- if possibility.color.name == characteristic:
- self.hand[card_num].remove(possibility)
- else:
- possibility_num+=1
- def narrow_possibilities(self):
- for card_num in range(len(self.hand)):
- possibilities = self.hand[card_num]
- if len(possibilities) == 1:
- self.purge(possibilities[0], card_num)
- class HanabiCard(object):
- """
- card class for hanabi cards
- """
- def __init__(self, c, number):
- if c in Color.__members__:
- self.color = Color[c]
- #else:
- #raise Exception("color is out of bounds")
- if number in range(1,6):
- self.number = number
- #else:
- #raise Exception("number is out of bounds")
- def __repr__(self):
- return "[%s, %d]"%(self.color, self.number)
- def __eq__(self, other):
- return self.number == other.number and self.color == other.color
- class Color(Enum):
- R = 1
- G = 2
- B = 3
- Y = 4
- W = 5
- if __name__ == "__main__":
- solve = Borya()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement