[Question]
  [
## Background
[**Set**](https://en.wikipedia.org/wiki/Set_(card_game)) is a card game. The deck consists of 81 unique cards that vary in four features: number of shapes (one, two, or three), shape (diamond, squiggle, oval), shading (solid, striped, or open), and color (red, green, or purple).
For convenience, let's write a card as a 4-tuple of numbers from 1 to 3, e.g.
* `1111` = one red solid diamond
* `1122` = one red striped squiggle
* `1223` = one green striped oval
* `2312` = two purple solid squiggle
Given several cards (usually 12), the objective of the game is to find a "set" of three cards such that
* They all have the same number or have three different numbers.
* They all have the same shape or have three different shapes.
* They all have the same shading or have three different shadings.
* They all have the same color or have three different colors.
i.e. the cards are either **all the same or all different in each of the four features**.
Here are some examples of sets:
```
1111, 1112, 1113
1111, 2222, 3333
2312, 3321, 1333
```
Here are some examples of non-sets:
```
1111, 1122, 1123
2131, 3221, 1213
```
A [**cap set**](https://en.wikipedia.org/wiki/Cap_set) is a collection of cards that doesn't contain any Set. It was proven in 1971 that [the maximum number of cards without a Set is 20.](https://www.quantamagazine.org/set-proof-stuns-mathematicians-20160531) Interestingly, finding the largest cap set for the generalized game of Set is still an open problem in mathematics.
The Wikipedia page shows an example of 20-cap set, and here is the 20 cards in the number notation:
```
1111, 1113, 1131, 1133,
1312, 1332, 1321, 1323,
3311, 3313, 3331, 3333,
3112, 3132, 3121, 3123,
1222, 2122, 2322, 3222
```
There are 682344 20-cap sets in total, but under affine transformations on 4-dimensional finite space, they all reduce to essentially one cap set.
## Task
Output any of the 20-cap sets in the game of Set.
## Input and output
Your program/function is not allowed to take input.
The output is a collection (list, set, ...) of 20 cards which is a cap set. Each card should be represented as a 4-tuple (or equivalent ordered collection) whose elements are one of three distinct values (not necessarily 1, 2, 3). Flexible output applies in the following ways:
* Nested or flattened list
* Ordering of cards doesn't matter
* You may choose to output the same set or different set across runs
* For string/text output, it's fine as long as we can clearly identify the structure (20 chunks of four items) of the output
[Verification script example in Python](https://tio.run/##VZFNjoMwDIX3nMKsClVGKvGuUrY9QXcIjVJ@1EiQoCSVgMszdmhnNCw@2X5@jmXmNT6dxX0fvJvAxN5H58YAZpqdj@es6wcYilb7LpTXDAbnQYuHaMFYaN30MFZH42w4WgQgd4EJ36GPoODuXz3lbFvEKja2bWYu0ozUCmaARak1VxtQ16rUlquFw02pJVfr9W/aTY@Bx5HlqF3B9/Hl7Ud5Z/zqnhYiU12fJz0XxkYBIfpiKcvmWIiXqWlcRZ9gIhNTjChYwUpShpgoq8SkILKHiExM8eEhgbpJSGQP8ZgmJdVklYhMgsyaJps9rVd87gzadjD29p0qJS@pdLo/Df2ZABrk5avVM9AJTnyqX8W6@F8t9x8) using the example shown above.
## Scoring and winning criterion
Standard [code-golf](/questions/tagged/code-golf "show questions tagged 'code-golf'") rules apply. The shortest valid code in bytes wins.
  
[Answer]
# [Haskell](https://www.haskell.org/), 62 bytes
```
tail[t|t@[a,b,c,d]<-mapM(:[1,2])[0,0,0,0],mod(a*a+b*b+c*d)3<1]
```
[Try it online!](https://tio.run/##HcJBDkQwFADQq3RhQX3JMDshcQEn6HTx2xoavzR06ey@RN5b8FwnIqb@xwk9qXSlQSEYsOB0VwWMY96qGhpdqA@8NITd5SixNNKUVrri29WaA/pN9CIefksiE8S3/RPOJ1c2xgc "Haskell – Try It Online")
Defines a cap-set as all \$(a,b,c,d)\$ from \$\{0,1,2\}^4\$ where $$a^2+b^2+cd=0\bmod3,$$ except not \$(0,0,0,0)\$.
I found this formula by looking at [Wikipedia's example](https://en.wikipedia.org/wiki/Cap_set#/media/File:Set_isomorphic_cards.svg) and coming up with progressively simpler formulas linking the allowed inner coordinates \$(a,b)\$ to the outer coordinates \$(c,d)\$.
---
# [Haskell](https://www.haskell.org/), 46 bytes
```
[t|t<-mapM(:"12")"0000",sum[1|'0'<-t!!0:t]==2]
```
[Try it online!](https://tio.run/##y0gszk7NyfmfYxvzP7qkpsRGNzexwFfDSsnQSElTyQAIlHSKS3OjDWvUDdRtdEsUFQ2sSmJtbY1i/@cmZuYp2CoUFGXmlSioKOT8/5eclpOYXvxfN7mgAAA "Haskell – Try It Online")
This uses a modified condition giving a different but equivalent cap set:
$$a^2+b^2+c^2 - d^2=0\bmod3,$$ still without \$(0,0,0,0)\$.
This is equivalent to \$a^2+b^2+c^2 + d^2 + d^2 =0\bmod3,\$, so we can duplicate an element and check that the give-element list of squares adds to zero modulo 3. Since squares modulo 3 are 0 or 1, this is further equivalent to this condition:
> 
> There are exactly \$2\$ zeroes among \$[a,b,c,d,d]\$.
> 
> 
> 
This automatically excludes the all-zero point. Of course, duplicating $d$ was arbitrary -- choosing another element gives a different but equivalent cap-set.
[Answer]
# [05AB1E](https://github.com/Adriandmen/05AB1E/wiki/Commands), ~~16~~ ~~13~~ ~~11~~ 9 [bytes](https://github.com/Adriandmen/05AB1E/wiki/Codepage)
```
2Ý4ãʒĆ0¢<
```
Port of the found formula of *@xnor*, as mentioned in [his comment](https://codegolf.stackexchange.com/questions/195685/20-cards-with-no-set#comment465676_195685) as well as his [Haskell answer](https://codegolf.stackexchange.com/a/195689/52210), so make sure to upvote him!  
-2 bytes by using *@xnor*'s updated formula (thanks for letting me know).  
-2 bytes thanks to *@xnor* again by simply counting whether there are exactly 2 zeroes in \$[a,b,c,d,a]\$.
Also outputs a list of lists with values in the range \$[0,3]\$.
[Try it online.](https://tio.run/##yy9OTMpM/f/f6PBck8OLT0060mZwaJHN//8A)
**Explanation:**
Will leave quartets \$[a,b,c,d]\$ for which there are exactly 2 zeroes in the list \$[a,b,c,d,a]\$.
```
2Ý         # Push the list [0,1,2]
  4ã       # Create all possible quartets using the values in this list
           # by taking the cartesian power of 4
    ʒ      # Filter the remaining quartets by:
     Ć     #  Enclose the quartet; appending its own head: [a,b,c,d] → [a,b,c,d,a]
      0¢   #  Count the amount of 0s in this list
        <  #  And decrease it by one
           #  (Since only 1 is truthy in 05AB1E, the filter with count(0)-1 will only
           #   leave quartets where the [a,b,c,d,a].count(0) is exactly 2)
           # (after which the filtered list is output implicitly as result)
```
[Answer]
# JavaScript (ES6), ~~73~~ 67 bytes
```
_=>[...'11138272726454626454'].map(i=>3333-(t-=i).toString(3),t=80)
```
[Try it online!](https://tio.run/##HcTRCoMwDEDRzzEBG@zqnC/xJ3wcMopT6dBGavD3q@weuD9/@mNMYVcT5TvlmfOHuzcRFdZa1z5et6Z@1s3/xUCb3yFw5@4MqOGApNJrCnEBh6VyW2EeJR6yTrTKAjMg5gs "JavaScript (Node.js) – Try It Online")
Outputs the following set, as an array of integers:
```
1112, 1113, 1121, 1131, 1223, 1232, 1323, 1332, 2123, 2132,
2222, 2233, 2322, 2333, 3123, 3132, 3222, 3233, 3322, 3333
```
[Test it online!](https://tio.run/##VZFNjoMwDIX3nMKsClVGKvGuUrY9QXcIjVJ@1EiQoCSVgMszdmhnNFlYz/b3jEnmNT6dxX0fvJvAxN5H58YAZpqdj@es6wcYilb7LpTXDAbnQYuHaMFYaN30MFZH42w4EAHIFJjwHfoICu7@1VPOtkWsYmPbZuYizUgomAEWpdZcbUDUqtSWq4XlptSSq/X6N@2mx8DjyHLUruD7@PL203ln/NU9LUSmuj5Pei6MjQJC9MVSls2xEC9T07iqqqTgiBxlxRE5SskVidzFpJG1rFhLKglySzqUSeQaJo2sMVHIFGBiMDGYGEIwa5ps9rRY8blh0LaDsbfvVCl5SaXT/WnoTQJokJevVs9AP3/iS/rtWBf/d8v9Bw)
[Answer]
# [Perl 6](https://github.com/nxadm/rakudo-pkg), ~~46~~ 36 bytes
```
{grep *[0,^*].Bag{0}==2,[X] ^3 xx 4}
```
[Try it online!](https://tio.run/##K0gtyjH7n1upoJamYKvwvzq9KLVAQSvaQCdOK1bPKTG92qDW1tZIJzoiViHOWKGiQsGk9n9xYqVCmobmfwA "Perl 6 – Try It Online")
Uses [xnor's *updated* formula](https://codegolf.stackexchange.com/a/195689/76162).
### Explanation:
```
{                                  }  # Anonymous code block
 grep                                 # Filter from
                       ,[X]             # The cross product of
                            ^3 xx 4     # 0,1,2 four times
      *[0,^*]                         # Duplicating the first element
             .Bag{0}                  # Where the number of zeroes
                    ==2               # Is equal to 2
```
[Answer]
# [APL (Dyalog Unicode)](https://www.dyalog.com/), ~~21~~ 19 bytes
*-2 bytes thanks to Bubbler*
```
((3=1⊥5⍴×)¨⊆⊢),⍳4/3
```
[Try it online!](https://tio.run/##SyzI0U2pTMzJT///qG@qp/@jtgkGIBaQ1tAwtjV81LXU9FHvlsPTNQ@teNTV9qhrkabOo97NJvrG//8DAA "APL (Dyalog Unicode) – Try It Online")
This uses [xnor's formula](https://codegolf.stackexchange.com/a/195689/76162), finding all cards from the permutation that when the first attribute is duplicated, has exactly 2 zeroes (this code being 0-indexed). The output is slightly weird, since some cards are grouped together, but you can still make out the individual cards.
### Explanation
```
              ,⍳4/3     ⍝ Generate all length 4 permutations of 0,1,2
 (       )¨             ⍝ For each permutation, e.g 0,1,2,1
        ×               ⍝ Get the sign,         e.g 0,1,1,1
      5⍴                ⍝ Reshape to size 5     e.g 0,1,1,1,0
    1⊥                  ⍝ Base 1 (or sum)       e.g 3
  3=                    ⍝ Is equal to 3         e.g 1
           ⊆⊢           ⍝ And partition the ones that return true
```
[Answer]
# [Ruby](https://www.ruby-lang.org/), ~~78..52~~ 49 bytes
```
"U

 

".bytes{|r|p ($.+=r).to_s 4}
```
[Try it online!](https://tio.run/##KypNqvz/XymUiY2Jm4eZiVlGQQZI8nAD@Up6SZUlqcXVNUU1BQoaKnratkWaeiX58cUKJrX//wMA "Ruby – Try It Online")
### How
The sequence can be DPCM-encoded.
If we consider a card as a single base-4 integer (1111 through 3333), we can take any sequence, sort it, and use a single ASCII character to encode the difference between successive elements. The first character represents the first value of the sequence. All values are relatively small, and the decoding is still simple enough to be golfed.
Thanks Value Ink for -3 bytes ("to print the unprintable")
In theory, with a different encoding, every value can be encoded as a single byte, and this would bring the byte count down to 43, but with UTF-8 it's impossible (or at least, I can't figure it out).
[Answer]
# [Charcoal](https://github.com/somebody1234/Charcoal), 24 bytes
```
ＵＢ0Ｅ²⁰⮌⍘Σ…”)″&:igＫ⁶Mψ”ι³
```
[Try it online!](https://tio.run/##HYlBCoMwEADvfUXIaQMpSJKD4E3PQmlesMRFpamRGIW@fhscGBiYsGAOCSOzp9Jj@Mw5ndsEspGqe7zyuhUYcQfTaPGmi/JB0ONBvtQ1gz@/MPxCpGFJO8jWOlt1xhh3l22lFqtSWlhV6Zj5ecU/ "Charcoal – Try It Online") Link is to verbose version of code. Outputs the given set, but with digits decremented and sorted in order of reverse of string. Explanation:
```
ＵＢ0
```
Pad all lines to the same length using `0`.
```
Ｅ²⁰
```
Loop `i` from 0 to 19 and implicitly print each result on its own line.
```
⮌⍘Σ…”)″&:igＫ⁶Mψ”ι³
```
Convert the digital sum of the `i`th prefix of the compressed string `8343834422244383438` to base 3 and print it backwards.
[Answer]
# [Python 2](https://docs.python.org/2/), 85 bytes
```
print eval('[[a,b,c,d]'+'for %s in 0,1,2'*4%tuple('abcd')+'if(a*a+b*b+c*d)%3<1]')[1:]
```
A full program which performs [xnor's algorithm](https://codegolf.stackexchange.com/a/195689/53748).
**[Try it online!](https://tio.run/##BcFLCoAgEADQq7iR8TOLrFbRTcTF@ImEMCkLOr29V7@2n2XsvV65NJZeOgRYS@gxYHSgYTsvxm@WCxvQ4Ahq5u2pRxJAPkSQGvImSJH2yuugouTTahxIaxbX@w8 "Python 2 – Try It Online")**
[Answer]
# [Python 2](https://docs.python.org/2/), 62 bytes
```
for c in"P}nF-Z>a9*)V=.Q":n=ord(c);print n/50,n%3,n%4,n%5
```
[Try it online!](https://tio.run/##K6gsycjPM/r/Py2/SCFZITNPKUCkNk/STTdK0C5RzFJLM8xWL5BNySrPNr8oRSNZ07qgKDOvRCFP39RAJ0/VGIhNgNj0/38A "Python 2 – Try It Online")
Using ideas from Bubbler and Jo King, we can cut a few bytes from the below. The decompression method `n/50,n%3,n%4,n%5` turns an ASCII value into a 4-tuple. While not every set can be obtained this way using `n` from 0 to 127, there's enough wiggle room in the choice of cap-set to find one within the obtainable subset. We also avoid problematic characters that need escaping such as `\0` or `\n`, though unprintables can't be avoided.
---
**[Python 2](https://docs.python.org/2/), 65 bytes**
```
for c in'RSTW_ahjq"(,15;=CGLP':print[ord(c)/B%3for B in 27,9,3,1]
```
[Try it online!](https://tio.run/##K6gsycjPM/r/Py2/SCFZITNPPSg4JDw@MSOrUElDx9DU2tbZ3SdA3aqgKDOvJDq/KEUjWVPfSdUYpNwJqFzByFzHUsdYxzD2/38A "Python 2 – Try It Online")
String compression looks like the way to go for Python. We compress each of the 20 elements as a value from 0 to 80, which we represent as a character. Since we only need the values to be correct modulo 81, we can keep the string within the printable ASCII range. Python 3 could save a few bytes using a bytestring.
An alternative compression method would be 81 bits marking which of the 81 cards are present. Even though the 81 bits needed for this are less than the \$20 \log\_2(81)\approx 127\$ bits for the method used, the latter [wins out easily](https://tio.run/##FcYxCoAwDADAr2SpKAhNUsW49CPi4GC1S5TioK@Puhx3Ptd@KJudJes1Tep5aNWPLnyGXxfmdBRQyApl0W2thZqcAG8iFGFh/tIjC3XYrTFqRbPZCw) for how concisely the string can be written and decoded.
For comparison, here's a solution using [the formula I found](https://codegolf.stackexchange.com/a/195689/20260).
**79 bytes**
```
n=81
while n:
 t=a,b,c,d=n/27,n/9%3,n/3%3,n%3;n-=1
 if(a*a+b*b+c*d)%3<1:print t
```
[Try it online!](https://tio.run/##FcRLCoAgFADAvadwI5Qaoi4qy8P4KRTiJSFEp7eaxZSnphNUa2Anie6Ujw2DQbhaxz0PPFoQauQgZqK/9T/RCwxWIpz3zlHHPPUs0NgTvUpTrgwV19Ze "Python 2 – Try It Online")
[Answer]
# [Jelly](https://github.com/DennisMitchell/jelly), ~~13~~ 11 [bytes](https://github.com/DennisMitchell/jelly/wiki/Code-page)
-2 using more of xnor's ideas
```
3ṗ4ṁ5ỊS⁼ʋƇ2
```
A niladic Link which yields a list of lists of integers.
**[Try it online!](https://tio.run/##AR4A4f9qZWxsef//M@G5lzThuYE14buKU@KBvMqLxocy//8 "Jelly – Try It Online")**
### How?
Cards being `[a, b, c, d]` where \$a,b,c,d \in [1,3]\$ this method picks cards for which there are exactly two `1`s in `[a, b, c, d, a]`.
```
3ṗ4ṁ5ỊS⁼ʋƇ2 - Link: no arguments
3           - literal three
  4         - literal four
 ṗ          - (implicit range(x)) Cartesian power -> [[1,1,1,1],[1,1,1,2],...,[3,3,3,3]]
          2 - set the right argument to two
         Ƈ  - filter keep if:
        ʋ   -   last four links as a dyad:
   ṁ5       -     mould like 5 ([a,b,c,d] -> [a,b,c,d,a])
     Ị      -     insignificant? (abs(x)<=1) (vectorises)
      S     -     sum
       ⁼    -     equals (2)?
```
---
Previous
```
3ṗ4Ṗ2œ?ḋƊ3ḍƊƇ
```
A niladic Link which yields a list of lists of integers.
**[Try it online!](https://tio.run/##ASIA3f9qZWxsef//M@G5lzThuZYyxZM/4biLxooz4biNxorGh/// "Jelly – Try It Online")**
### How?
A method which works in a similar vein as [xnor's](https://codegolf.stackexchange.com/a/195689/53748).  
With cards being `[a, b, c, d]` where \$a,b,c,d \in [1,3]\$ this method picks cards for which \$3 \mid (a^2+b^2+2cd)\$ (except `[3,3,3,3]`)
```
3ṗ4Ṗ2œ?ḋƊ3ḍƊƇ - Link: no arguments
3             - literal three
  4           - literal four
 ṗ            - (implicit range(x)) Cartesian power -> [[1,1,1,1],[1,1,1,2],...,[3,3,3,3]]
   Ṗ          - pop off the rightmost (remove [3,3,3,3])
            Ƈ - filter keep those for which:
           Ɗ  -   last three links as a monad:- i.e. f([a,b,c,d])
        Ɗ     -     last three links as a monad - i.e. g([a,b,c,d]):
    2         -       literal two                 2
     œ?       -       nth permutation             [a,b,d,c]
       ḋ      -       dot product                 a*a+b*b+c*d+d*c
         3    -     literal three               3
          ḍ   -     divides?                    (a*a+b*b+c*d+d*c)%3 == 0?
```
[Answer]
# [Brachylog](https://github.com/JCumin/Brachylog), 32 bytes
Just an inefficient Brachylog answer passing by, both in speed and bytes. But it works in the generalized case and will give every possible set if you let it run several years!
```
l₂₀{l₄ℕᵐ<ᵛ³}ᵐ{cᵐ≠&}¬{⊇l₃\{=|≠}ᵐ}&≜
```
[Try it online!](https://tio.run/##SypKTM6ozMlPN/r/P@dR20zTahBp8qhl6sOtE2webp39qG2acS2QnQzEjzoXqB1aU/2oqz3nUVNzTLVtDVAEJFmr9qhzzv//Uf8B) … or don't; this will just give you a 5 cap set, the maximum for TIO's time limit. The version uses up/down arrows for ease of use. First number is size of cap set, second is number of properties per card, and third is variations of each property. The 6 cap set I found locally: `[[0, 0, 0, 0], [0, 0, 0, 1], [0, 0, 1, 0], [0, 1, 0, 0], [0, 1, 1, 1], [1, 0, 0, 0]]`.
### How it works
```
l₂₀{l₄ℕᵐ<ᵛ³}ᵐcᵐ≠&¬{⊇l₃\{=|≠}ᵐ}&≜ (the implicit input we are looking for)
l₂₀                              is a list of 20 cards,
   {       }ᵐ                    where each card
    l₄                             has 4 elements,
      ℕᵐ                           numbers >= 0 – to be precise
        <ᵛ³                        that are also lower than 3
                                   (so [0,0,0,0] up to [2,2,2,2])
             cᵐ                  if each card is concatenated to a string,
               ≠                   they would be different. (sadly ≠
                                   doesn't work on lists.)
                 &¬{          }  the following doesn't hold for the input:
                    ⊇l₃            take any list of 3 cards,
                       \           transpose it
                                   ([[0,1,2],[3,2,1],[0,0,0],[2,2,2]])
                        {   }ᵐ   each of the row's elements are …
                         =|≠       either equal or different to each other
                              &≜ actually get some numbers for the list
                   
```
[Answer]
# [Python 3](https://docs.python.org/3/), ~~108~~ ~~104~~ 100 bytes
Saved 4 bytes thanks to @JonathanAllan!  
Saved 4 bytes thanks to @xnor!
Blatant rip of @xnor's algorithm:
```
lambda:[(a,b,c,d)for a,b,c,d in product(*[(0,1,2)]*4)if(a*a+b*b+c*d)%3<1][1:]
from itertools import*
```
[Try it online!](https://tio.run/##LcY7DgIhEADQ3lPQmMzMUohrtXFPghR8JJIsDBmx8PTY@KrXv@PFbZ15f8zD15D8ZsHroKNOmFnU/6o01YXTJw4gCxdt9BUd3bBk8OSXQGGJlPC83o2zZnOnLFxVGU8ZzMdbldpZBs0upQ3IgDh/ "Python 3 – Try It Online")
[Answer]
# [Scala](http://www.scala-lang.org/), 68 bytes
```
BigInt("3aglhdjjb0zmp3uvkpxvwio58",36).toString(3).grouped(4).toList
```
[Try it online!](https://tio.run/##LcvRCsIgFIDhVxGvFIYErui27oK66gncFNO542GerbHo2a2g2//jL71JpuYuup7YzQRgbiUHtrATInsxnAJQAlHPwV@ABNfGp4eNsdttI@p5GXBdniHvj7zRB6ko3@m7eKGl8lOe0VnR/vI1FKpqHP7MGy7lu34A "Scala – Try It Online")
Just storing the 20-cap set as a 80-digit base-3 number (using 0, 1, 2 for notation - since it's stated in the question that it's not necessary to use exactly 1, 2, 3), constructing it from base-36 to save space, and splitting the string to 4-character slices, finally getting a list of 20 cards (represented as strings like "1111", "0222" etc.). A couple more bytes probably can be golfed, using a smaller number.
]