﻿from heapq import heappush

class KNearestDecks(object):
    """ Finds the decks that are most similar to a set of cards. """

    MAX_CARDS_IN_DECK = 30

    def __init__(self):
        self.decks = {}

    def update_deck(self, deck_entry):
        """ Adds a card to its corresponding deck. """
        archetype = deck_entry['class'] + '##' + deck_entry['archetype']
        if archetype not in self.decks:
            self.decks[archetype] = {}

        title = deck_entry['title']
        if title not in self.decks[archetype]:
            self.decks[archetype][title] = set()

        self.decks[archetype][title].add(deck_entry['card-name'])

    def get_nearest_decks(self, k, hero_class, archetype, cards):
        """ Finds the k decks that are closest to the passed set of cards. """
        dist_sorted_decks = []
        archetype_id = hero_class + '##' + archetype

        for deck_title, arch_cards in self.decks[archetype_id].iteritems():
            dist = KNearestDecks.__get_distance(arch_cards, cards)
            heappush(dist_sorted_decks, (dist, deck_title))

        return dist_sorted_decks[:k]

    @classmethod
    def __get_distance(cls, first, second):
        return cls.MAX_CARDS_IN_DECK - len(first - second)

@@ -192,24 +192,53 @@
 f.decks = %7B%7D
+%0A        self.card_count = %7B%7D
 %0A%0A    def up
@@ -604,13 +604,10 @@
 %5D = 
-set()
+%5B%5D
 %0A%0A  
@@ -642,17 +642,20 @@
 title%5D.a
-d
+ppen
 d(deck_e
@@ -662,22 +662,249 @@
 ntry
-%5B'card-name'%5D)
+)%0A%0A        card_name = deck_entry%5B'card-name'%5D%0A        deck_entry_id = archetype + '##' + title + '##' + card_name%0A        self.card_count%5Bdeck_entry_id%5D = int(deck_entry%5B'card-count'%5D)%0A%0A        print self.decks%0A        print self.card_count
 %0A%0A  
@@ -957,16 +957,17 @@
 rchetype
+s
 , cards)
@@ -1078,16 +1078,118 @@
 ks = %5B%5D%0A
+        input_card_count = KNearestDecks.__get_count(cards)%0A%0A        for archetype in archetypes:%0A    
         
@@ -1233,17 +1233,20 @@
 chetype%0A
-%0A
+    
         
@@ -1261,26 +1261,20 @@
 _title, 
-arch_cards
+deck
  in self
@@ -1323,120 +1323,414 @@
     
-dist = KNearestDecks.__get_distance(arch_cards, cards)%0A            heappush(dist_sorted_decks, (dist, deck_title
+    deck_id = archetype_id + '##' + deck_title%0A                dist = self.__get_distance(deck_id, cards)%0A%0A                is_complete_match = KNearestDecks.MAX_CARDS_IN_DECK - dist == input_card_count%0A                heappush(dist_sorted_decks, (dist, %7B%0A                    'deck': deck,%0A                    'archetype': archetype,%0A                    'complete_match': is_complete_match%0A                %7D
 ))%0A%0A
@@ -1771,25 +1771,8 @@
 k%5D%0A%0A
-    @classmethod%0A
     
@@ -1794,84 +1794,594 @@
 nce(
-cls, first, second):%0A        return cls.MAX_CARDS_IN_DECK - len(first - second)
+self, deck_id, cards):%0A        dist = KNearestDecks.MAX_CARDS_IN_DECK%0A%0A        for card in cards:%0A            card_name = card%5B'card-name'%5D%0A            card_count = int(card%5B'card-count'%5D)%0A            deck_entry_id = deck_id + '##' + card_name%0A            if deck_entry_id in self.card_count:%0A                count_in_deck = self.card_count%5Bdeck_entry_id%5D%0A                dist -= min(count_in_deck, card_count)%0A%0A        return dist%0A%0A    @staticmethod%0A    def __get_count(cards):%0A        count = 0%0A        for card in cards:%0A            count += int(card%5B'card-count'%5D)%0A        return count
 %0A

Add data to nearest deck finder output