g | x | w | all
Bytes Lang Time Link
013Japt v2.0a0250129T161000ZShaggy
099Python 2191030T011936ZChas Bro
012Brachylog191029T055747ZUnrelate
073Mathematica131016T200206ZDavidC
071Sage131017T183226Zboothby
080Ruby131016T130808ZDoorknob
053GolfScript131016T220338ZHoward
076APLIBM131017T101748ZTwiN
073Mathematica131017T101210Zalephalp
313javascript131016T142304ZMath chi

Japt v2.0a0, 13 bytes

¸à3 fÈÕeÈâ ÊÍ

Try it

¸à3 fÈÕeÈâ ÊÍ     :Implicit input of string
¸                 :Split on spaces
 à3               :Combinations of length 3
    f             :Filter by
     È            :Passing each through the following function
      Õ           :  Transpose
       e          :  All truthy when
        È         :  Passed through the following function
         â        :    Deduplicate
           Ê      :    Length
            Í     :    Subtract from 2

Python 2, 99 bytes

lambda A:[a for a in combinations(A,3)if all(len(set(t))-2for t in zip(*a))]
from itertools import*

Try it online!

Brachylog, 12 bytes

ṇ₁⊇Ṫz{=|≠}ᵐz

Try it online!

Takes input through the input variable and generates the output through the output variable.

Second test case taken from a recently closed duplicate in its encoding, since this solution doesn't really care what anything actually means.

                The output variable is
  ⊇             a subsequence
   Ṫ            of length 3
ṇ₁              of the input split on spaces,
    z      z    the columns of which
     {   }ᵐ     are all
       |        either
      =         the same element repeated,
        ≠       or entirely free of duplicates.

Mathematica 93 92 93 82 76 73

f={}⋃Select[StringSplit@#~Subsets~{3}, FreeQ[Tally/@(Characters@#^T),2]&]&

The Logic

StringSplit@#~Subsets~{3} produces a list of 3-card subsets. Each triple such as:

{{"D", "G", "3", "N"}, {"W", "G", "3", "S"}, {"O", "G", "3", "O"}}

or

array 1

is then transposed,

array 2

and Tally/@(Characters@#^T) tallies the number of distinct items in each row.

{3,1,1,3}

3 corresponds to "all different"; 1 corresponds to "all same".

FreeQ[...,2] determines whether 2 cards of the same type or in the triple. If 2 is not among the tallies, then the three cards are a "set", according to Game of Set rules.


Usage

f["OR1N WP2N DG3N DR1D WG3S WG1N WR2D WP3N DR2O DR1D OG3O OR2D"]

{{"DG3N", "WG3S", "OG3O"}, {"OR1N", "WP2N", "DG3N"}, {"WP2N", "DR1D", "OG3O"}}

Sage, 71

If C is a string, say "OR1N WP2N DG3N DR1D WG3S WG1N WR2D WP3N DR2O DR1D OG3O OR2D", execute

[c for c in Subsets(C.split(),3)if{1,3}>={len(set(x))for x in zip(*c)}]

to get [{'DR1D', 'OG3O', 'WP2N'}, {'DR2D', 'WR2D', 'OR2D'}, {'WG3S', 'OG3O', 'DG3N'}, {'DG3N', 'WP2N', 'OR1N'}]

And here's a very different approach using the interpretation that a Set is a projective line in GF(3)^4:

[c for c in Subsets(C.split(),3)if sum(matrix(3,map('WODRPG123N'.find,''.join(c))))%3==0]

I was a little annoyed that D was used twice... until I figured how to abuse that. But even better, I abuse the find method, too. str.find returns -1 if a letter isn't found. Since -1 = 2 mod 3, the letter S is handled appropriately because it doesn't occur in 'WODRPG123N'.

Ruby, 104 98 81 80 characters

$*.combination(3).map{|c|puts c*?,if(0..3).all?{|i|c.map{|x|x[i]}.uniq.size!=2}}

Sample run (using your example data):

c:\a\ruby>set.rb OR1N WP2N DG3N DR1D WG3S WG1N WR2D WP3N DR2O DR1D OG3O OR2D
OR1N,WP2N,DG3N
WP2N,DR1D,OG3O
WP2N,DR1D,OG3O
DG3N,WG3S,OG3O

It outputs WP2N,DR1D,OG3O twice because you have two DR1Ds in your sample data.

Explanation:

$*.combination(3).map{|c| - each combination of 3 cards
puts c*?,if - output the set, if...
(0..3).all?{|i| - if all of the numbers from 0 to 3 (the indeces of the properties in the string) evaluate to true when passed into this block
c.map{|x|x[i]} - take the ith index of each string
.uniq.size!=2} - if the amount of unique properties (form, color, etc.) is not 2 (so, 1 or 3)

GolfScript, 53 characters

" "/:w,,{:a,{:^,{a^]{w=}%.0\zip{.&,2=|}/!{.p}*;}/}/}/

Input must be provided on STDIN, example online:

> OR1N WP2N DG3N DR1D WG3S WG1N WR2D WP3N DR2O DR2D OG3O OR2D
["OR1N" "DG3N" "WP2N"]
["WP2N" "OG3O" "DR1D"]
["DG3N" "OG3O" "WG3S"]
["WR2D" "OR2D" "DR2D"]

Commented code:

" "/:w          # split the input at spaces and assign it to variable w
,,              # create the array [0..n-1] (n being the length of w)
{:a,{:^,{       # three nested loops: a=0..n-1, ^=0..a-1, _=0..b-1 
                # (third loop has no variable assigned but just pushes on stack)
    a^]         # make an array [a,^,_] of the three loop variables
    {w=}%       # take the corresponding list items, i.e. [w[a],w[^],w[_]]
    .0\         # push zero, add duplicate of the the array
    zip         # zip transposes the array, thus [OR1N WP2N DG3N] -> [OWD RPG 123 NNN]
    {           # loop over those entries
      .&        # unique
      ,2=       # length equals 2?
      |         # "or" with top of stack (two zero pushed before)
    }/          # end of loop, on stack remains the results of the "or"s
    !{.p}*      # if no length of 2 is there, make a copy of the set and print it
    ;           # discard stack item
}/}/}/          # closing the three nested loops

APL(IBM), 76

⍉¨x/⍨{{⍵≡1⌽⍵}⍵=1⌽⍵}¨x←⊃¨(∘.,/3⍴⊂⍪¨(' '≠y)⊂y←⍞)⌷⍨¨z/⍨∧/¨2</¨z←,⍳3⍴12

I don't have IBM APL, but I believe this will work.

Sample run (Emulating IBM APL in Dyalog APL)

OR1N WP2N DG3N DR1D WG3S WG1N WR2D WP3N DR2O DR1D OG3O OR2D
 OR1N  WP2N  WP2N  DG3N 
 WP2N  DR1D  DR1D  WG3S 
 DG3N  OG3O  OG3O  OG3O 

Mathematica 73

f = Select[StringSplit@#~Subsets~{3}, FreeQ[Tally /@ Thread@Characters@#, 2] &] &

Usage

f["OR1N WP2N DG3N DR1D WG3S WG1N WR2D WP3N DR2O DR1D OG3O OR2D"]

{{"OR1N", "WP2N", "DG3N"}, {"WP2N", "DR1D", "OG3O"}, {"WP2N", "DR1D", "OG3O"}, {"DG3N", "WG3S", "OG3O"}}

javascript 323 313

function a(b){d=h=[];c=e=f=0;for(i in b){for(j in b){for(k in b[i]){if(b[i][k]==b[j][k]){if(c+f<4)c++;else if(c==4){h+=b[j];if(h.length=3)return h}}else{for(l in d){for(m in d[l]){g=f;if(d[l][2]==i){if(d[l][3]==k)if(b[j][k]!=d[l][0]&&b[j][k]!=d[l][1])f++;}else{continue}}if(g==f)d[e++]=[b[i][k],b[j][k],j,k]}}}}}}

its a function that takes a array of objects, and returns a array of objects.

DEMO fiddle (with tidy-up).