user
Set Puzzles are created with a deck of cards from the Set Game™. The object of the puzzle is to find sets of 3 cards in a rectangle of cards that have been dealt face up.   
  
There are 81 cards in a deck.
Each card contains a unique variation of the following four features: *color, symbol, number and shading*.

* there are three colors:  
      *red, green, purple*

* there are three symbols:  
      *oval, squiggle, diamond*

* there is a number of symbols on the card:  
      *one, two, three*

* there are three shadings:  
      *solid, open, striped*

Three cards form a *set* if each feature is either the same on each card, or is different on each card. For instance: all 3 cards are red, all 3 cards have a different symbol, all 3 cards have a different number of symbols, all 3 cards are striped.

There are two degrees of difficulty: basic and advanced. The basic mode deals 9 cards, that contain exactly 4 sets; the advanced mode deals 12 cards that contain exactly 6 sets.

When creating sets you may use the same card more than once.

Task

Write code that deals the cards (9 or 12, depending on selected mode) from a shuffled deck in which the total number of sets that could be found is 4 (or 6, respectively); and print the contents of the cards and the sets.

For instance:

**DEALT 9 CARDS:**

:   green, one, oval, striped

:   green, one, diamond, open

:   green, one, diamond, striped

:   green, one, diamond, solid

:   purple, one, diamond, open

:   purple, two, squiggle, open

:   purple, three, oval, open

:   red, three, oval, open

:   red, three, diamond, solid

**CONTAINING 4 SETS:**

:   green, one, oval, striped

:   purple, two, squiggle, open

:   red, three, diamond, solid

:   green, one, diamond, open

:   green, one, diamond, striped

:   green, one, diamond, solid

:   green, one, diamond, open

:   purple, two, squiggle, open

:   red, three, oval, open

:   purple, one, diamond, open

:   purple, two, squiggle, open

:   purple, three, oval, open
assistant
(formerly Perl 6)

The trick here is to allocate three different bits for each enum, with the result that the cards of a matching set OR together to produce a 4-digit octal number that contains only the digits 1, 2, 4, or 7. This OR is done by funny looking [+|], which is the reduction form of +|, which is the numeric bitwise OR. (Because Raku stole the bare | operator for composing junctions instead.)

```
enum Color (red => 0o1000, green =>  0o2000, purple => 0o4000);
enum Count (one =>  0o100, two =>     0o200, three =>   0o400);
enum Shape (oval =>  0o10, squiggle => 0o20, diamond =>  0o40);
enum Style (solid =>  0o1, open =>      0o2, striped =>   0o4);
 
my @deck = Color.enums X Count.enums X Shape.enums X Style.enums;
 
sub MAIN($DRAW = 9, $GOAL = $DRAW div 2) {
    sub show-cards(@c) { { printf "%9s%7s%10s%9s\n", @c[$_;*]».key } for ^@c }

    my @combinations = [^$DRAW].combinations(3);

    my @draw;
    repeat until (my @sets) == $GOAL {
        @draw = @deck.pick($DRAW);
        my @bits = @draw.map: { [+] @^enums».value }
        @sets = gather for @combinations -> @c {
            take @draw[@c].item when /^ <[1247]>+ $/ given ( [+|] @bits[@c] ).base(8);
        }
    }

    say "Drew $DRAW cards:";
    show-cards @draw;
    for @sets.kv -> $i, @cards {
        say "\nSet {$i+1}:";
        show-cards @cards;
    }
}

```

Output:

```
Drew 9 cards:
   purple    two   diamond     open
      red    two  squiggle  striped
   purple  three  squiggle     open
   purple    two  squiggle  striped
      red  three      oval  striped
      red    one   diamond  striped
   purple    two      oval    solid
    green  three   diamond    solid
      red    two  squiggle     open

Set 1:
   purple    two   diamond     open
   purple    two  squiggle  striped
   purple    two      oval    solid

Set 2:
   purple    two   diamond     open
      red    one   diamond  striped
    green  three   diamond    solid

Set 3:
      red    two  squiggle  striped
      red  three      oval  striped
      red    one   diamond  striped

Set 4:
   purple  three  squiggle     open
      red  three      oval  striped
    green  three   diamond    solid
```