import java.util.*; public class SetPuzzle { enum Color { GREEN(0), PURPLE(1), RED(2); private Color(int v) { val = v; } public final int val; } enum Number { ONE(0), TWO(1), THREE(2); private Number(int v) { val = v; } public final int val; } enum Symbol { OVAL(0), DIAMOND(1), SQUIGGLE(2); private Symbol(int v) { val = v; } public final int val; } enum Fill { OPEN(0), STRIPED(1), SOLID(2); private Fill(int v) { val = v; } public final int val; } private static class Card implements Comparable { Color c; Number n; Symbol s; Fill f; @Override public String toString() { return String.format("[Card: %s, %s, %s, %s]", c, n, s, f); } @Override public int compareTo(Card o) { return (c.val - o.c.val) * 10 + (n.val - o.n.val); } } private static Card[] deck; public static void main(String[] args) { deck = new Card[81]; Color[] colors = Color.values(); Number[] numbers = Number.values(); Symbol[] symbols = Symbol.values(); Fill[] fillmodes = Fill.values(); for (int i = 0; i < deck.length; i++) { deck[i] = new Card(); deck[i].c = colors[i / 27]; deck[i].n = numbers[(i / 9) % 3]; deck[i].s = symbols[(i / 3) % 3]; deck[i].f = fillmodes[i % 3]; } findSets(12); } private static void findSets(int numCards) { int target = numCards / 2; Card[] cards; Card[][] sets = new Card[target][3]; int cnt; do { Collections.shuffle(Arrays.asList(deck)); cards = Arrays.copyOfRange(deck, 0, numCards); cnt = 0; outer: for (int i = 0; i < cards.length - 2; i++) { for (int j = i + 1; j < cards.length - 1; j++) { for (int k = j + 1; k < cards.length; k++) { if (validSet(cards[i], cards[j], cards[k])) { if (cnt < target) sets[cnt] = new Card[]{cards[i], cards[j], cards[k]}; if (++cnt > target) { break outer; } } } } } } while (cnt != target); Arrays.sort(cards); System.out.printf("GIVEN %d CARDS:\n\n", numCards); for (Card c : cards) { System.out.println(c); } System.out.println(); System.out.println("FOUND " + target + " SETS:\n"); for (Card[] set : sets) { for (Card c : set) { System.out.println(c); } System.out.println(); } } private static boolean validSet(Card c1, Card c2, Card c3) { int tot = 0; tot += (c1.c.val + c2.c.val + c3.c.val) % 3; tot += (c1.n.val + c2.n.val + c3.n.val) % 3; tot += (c1.s.val + c2.s.val + c3.s.val) % 3; tot += (c1.f.val + c2.f.val + c3.f.val) % 3; return tot == 0; } }