For the uninitiated, SET is a card game now enjoyed mostly be numberphiles and probability geeks. The rules are simple: each card has between 1 to 3 of a shape, with 3 possible shapes. Each shape has three ways to be filled - solid, striped, empty. Each card is one of 3 colors.
Twelve cards are laid out in a grid, and players compete to be the first to find a SET - three cards whose properties are such:
For each property (shape, fill, color, number), all three cards must either share the same value (all the same color, all the same fill, all the same shape, all the same number) or each must have a unique value (each is one of the three colors, each is filled one of the three ways, etc.).
This brings to mind a couple interesting questions: to begin, how many possible SETs are there?
Counting SETs

Math

The number theory is elegantly trivial: each set must either have one, two, three, or four traits unique among cards.
Then, for some
i
, there’s

4
i

possible ways to choose which traits are unique,
3
P
3
ways to permute each trait among the cards, and so
3
i-1
P
3
ways to permute all i traits among the cards. The remaining (4 - i) traits can be any of 3 options, so we multiply by
4-i
3
for a final form of

4
i


3
i-1
P
3

4-i
3
.

Implementation

The implementation is simple, but we can add a bit of complexity by allowing the number of traits, the number of options, and the set size to be arbitrary:
In[]:=
nPr[n_,r_]:=n!/(n-r)!;
In[]:=
setCounts[numTraits_,numOptions_,setSize_]:=Module[{permutations},​​Table[​​Binomial[numTraits,i]*nPr[numOptions,setSize]^(i-1)*numOptions^(numTraits-i)​​,{i,numTraits}]​​]​​sets=setCounts[4,3,3]
Out[]=
{108,324,432,216}
This result indicates there are 108 SETs with one element unique, 324 with two, 432 with three, and 216 with four.
In[]:=
Total[sets]
Out[]=
1080

Brute Force Confirmation

We can confirm our math by doing a brute force check - generating all 81 possible cards, finding every set of three and checking how many are valid SETs.
In[]:=
multiPerm[numCards_,numChoices_]:=ToExpression/@​​PadLeft[StringSplit[StringSplit[ToString[BaseForm[#,numChoices]],"\n"][[1]],""],numCards]&/@Range[0,numChoices^numCards-1];
In[]:=
checkIfSet[els_]:=Module[{numSlots=Length[els[[1]]],numDiff},​​numDiff=0;​​Table[​​Module[{dist=CountDistinct[#[[slot]]&/@els]},​​numDiff=numDiff+Which[dist==1,0,dist==Length[els],1,True,-Infinity];​​]​​,{slot,numSlots}];​​numDiff​​]
In[]:=
deck=Subsets[multiPerm[4,3],{3}];
In[]:=
counts=checkIfSet/@deck;
In[]:=
Table[Count[counts,i],{i,4}]
Out[]=
{108,324,432,216}