BLOG | Comparing attributes for a set of cards

Question: SET is a card game where each card has 3 attributes, each of which can take on 3 different values(0,1,2). A “valid SET” is 3 cards such that each attribute is either (a) all the same or (b) all different.
Example:
card1 = {0,1,2}
card2 = {0,0,1}
card3 = {0,2,0}
is a valid set.
Write a function is_set(cards) to determine if a collection of 3 cards is a valid SET.

Follow up 1: card has 4 attributes. You have N cards right now, find the valid set.
Follow up 2: card now has N attribute instead of 4 attributes, how will you write “valid set” function?

Solution:

class Card:
    
    def __init__(self,*attrs):
        # a card is a simple 4-tuple of attributes
        # each attr is supposed to be either 0, 1 or 2
        self.attrs = attrs
    
    # most readable way to express what a SET is
    def isset(self,card1,card2):
        def allsame(v0,v1,v2):       # checks one attribute
            return v0==v1 and v1==v2
        def alldifferent(v0,v1,v2):  # checks one attribute
            return len({v0,v1,v2})==3
        return all(allsame(v0,v1,v2) or alldifferent(v0,v1,v2)
                   for (v0,v1,v2)
                   in zip(self.attrs,card1.attrs,card2.attrs))

    # all 81 possible cards
    @staticmethod
    def allcards():
        return [ Card(att0,att1,att2,att3)
                   for att0 in (0,1,2)
                   for att1 in (0,1,2) 
                   for att2 in (0,1,2)
                   for att3 in (0,1,2)
               ]

Resources:

Leave a comment