Just another update
This commit is contained in:
parent
a25938f123
commit
00a190b0a6
6591 changed files with 94363 additions and 23227 deletions
|
|
@ -1,4 +1,8 @@
|
|||
Set Puzzles are created with a deck of cards from the [[wp:Set (game)|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''.
|
||||
{{omit from|GUISS}}
|
||||
|
||||
Set Puzzles are created with a deck of cards from the [[wp:Set (game)|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. <br>
|
||||
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''', or '''purple'''
|
||||
|
||||
|
|
@ -8,9 +12,18 @@ Set Puzzles are created with a deck of cards from the [[wp:Set (game)|Set Game
|
|||
|
||||
; there are three shadings: '''solid''', '''open''', or '''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.
|
||||
Three cards form a ''set'' if each feature is either the same on each card, or is different on each card. <br>
|
||||
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: [http://www.setgame.com/set/rules_basic.htm ''basic''] and [http://www.setgame.com/set/rules_advanced.htm ''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. The task is to 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:
|
||||
There are two degrees of difficulty: [http://www.setgame.com/set/rules_basic.htm ''basic''] and [http://www.setgame.com/set/rules_advanced.htm ''advanced'']. <br>
|
||||
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.
|
||||
|
||||
;The task:
|
||||
Is to 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:'''
|
||||
|
||||
|
|
|
|||
4
Task/Set-puzzle/00META.yaml
Normal file
4
Task/Set-puzzle/00META.yaml
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
---
|
||||
category:
|
||||
- Puzzles
|
||||
note: Cards
|
||||
18
Task/Set-puzzle/Ada/set-puzzle-1.ada
Normal file
18
Task/Set-puzzle/Ada/set-puzzle-1.ada
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
package Set_Puzzle is
|
||||
|
||||
type Three is range 1..3;
|
||||
type Card is array(1 .. 4) of Three;
|
||||
type Cards is array(Positive range <>) of Card;
|
||||
type Set is array(Three) of Positive;
|
||||
|
||||
procedure Deal_Cards(Dealt: out Cards);
|
||||
-- ouputs an array with disjoint cards
|
||||
|
||||
function To_String(C: Card) return String;
|
||||
|
||||
generic
|
||||
with procedure Do_something(C: Cards; S: Set);
|
||||
procedure Find_Sets(Given: Cards);
|
||||
-- calls Do_Something once for each set it finds.
|
||||
|
||||
end Set_Puzzle;
|
||||
78
Task/Set-puzzle/Ada/set-puzzle-2.ada
Normal file
78
Task/Set-puzzle/Ada/set-puzzle-2.ada
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
with Ada.Numerics.Discrete_Random;
|
||||
|
||||
package body Set_Puzzle is
|
||||
|
||||
package Rand is new Ada.Numerics.Discrete_Random(Three);
|
||||
R: Rand.Generator;
|
||||
|
||||
function Locate(Some: Cards; C: Card) return Natural is
|
||||
-- returns index of card C in Some, or 0 if not found
|
||||
begin
|
||||
for I in Some'Range loop
|
||||
if C = Some(I) then
|
||||
return I;
|
||||
end if;
|
||||
end loop;
|
||||
return 0;
|
||||
end Locate;
|
||||
|
||||
procedure Deal_Cards(Dealt: out Cards) is
|
||||
function Random_Card return Card is
|
||||
(Rand.Random(R), Rand.Random(R), Rand.Random(R), Rand.Random(R));
|
||||
begin
|
||||
for I in Dealt'Range loop
|
||||
-- draw a random card until different from all card previously drawn
|
||||
Dealt(I) := Random_Card; -- draw random card
|
||||
while Locate(Dealt(Dealt'First .. I-1), Dealt(I)) /= 0 loop
|
||||
-- Dealt(I) has been drawn before
|
||||
Dealt(I) := Random_Card; -- draw another random card
|
||||
end loop;
|
||||
end loop;
|
||||
end Deal_Cards;
|
||||
|
||||
procedure Find_Sets(Given: Cards) is
|
||||
function To_Set(A, B: Card) return Card is
|
||||
-- returns the unique card C, which would make a set with A and B
|
||||
C: Card;
|
||||
begin
|
||||
for I in 1 .. 4 loop
|
||||
if A(I) = B(I) then
|
||||
C(I) := A(I); -- all three the same
|
||||
else
|
||||
C(I) := 6 - A(I) - B(I); -- all three different;
|
||||
end if;
|
||||
end loop;
|
||||
return C;
|
||||
end To_Set;
|
||||
|
||||
X: Natural;
|
||||
|
||||
begin
|
||||
for I in Given'Range loop
|
||||
for J in Given'First .. I-1 loop
|
||||
X := Locate(Given, To_Set(Given(I), Given(J)));
|
||||
if I < X then -- X=0 is no set, 0 < X < I is a duplicate
|
||||
Do_Something(Given, (J, I, X));
|
||||
end if;
|
||||
end loop;
|
||||
end loop;
|
||||
end Find_Sets;
|
||||
|
||||
function To_String(C: Card) return String is
|
||||
|
||||
Col: constant array(Three) of String(1..6)
|
||||
:= ("Red ", "Green ", "Purple");
|
||||
Sym: constant array(Three) of String(1..8)
|
||||
:= ("Oval ", "Squiggle", "Diamond ");
|
||||
Num: constant array(Three) of String(1..5)
|
||||
:= ("One ", "Two ", "Three");
|
||||
Sha: constant array(Three) of String(1..7)
|
||||
:= ("Solid ", "Open ", "Striped");
|
||||
|
||||
begin
|
||||
return (Col(C(1)) & " " & Sym(C(2)) & " " & Num(C(3)) & " " & Sha(C(4)));
|
||||
end To_String;
|
||||
|
||||
begin
|
||||
Rand.Reset(R);
|
||||
end Set_Puzzle;
|
||||
50
Task/Set-puzzle/Ada/set-puzzle-3.ada
Normal file
50
Task/Set-puzzle/Ada/set-puzzle-3.ada
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
with Ada.Text_IO, Set_Puzzle, Ada.Command_Line;
|
||||
|
||||
procedure Puzzle is
|
||||
|
||||
package TIO renames Ada.Text_IO;
|
||||
|
||||
Card_Count: Positive := Positive'Value(Ada.Command_Line.Argument(1));
|
||||
Required_Sets: Positive := Positive'Value(Ada.Command_Line.Argument(2));
|
||||
|
||||
Cards: Set_Puzzle.Cards(1 .. Card_Count);
|
||||
|
||||
function Cnt_Sets(C: Set_Puzzle.Cards) return Natural is
|
||||
Cnt: Natural := 0;
|
||||
procedure Count_Sets(C: Set_Puzzle.Cards; S: Set_Puzzle.Set) is
|
||||
begin
|
||||
Cnt := Cnt + 1;
|
||||
end Count_Sets;
|
||||
procedure CS is new Set_Puzzle.Find_Sets(Count_Sets);
|
||||
begin
|
||||
CS(C);
|
||||
return Cnt;
|
||||
end Cnt_Sets;
|
||||
|
||||
procedure Print_Sets(C: Set_Puzzle.Cards) is
|
||||
procedure Print_A_Set(C: Set_Puzzle.Cards; S: Set_Puzzle.Set) is
|
||||
begin
|
||||
TIO.Put("(" & Integer'Image(S(1)) & "," & Integer'Image(S(2))
|
||||
& "," & Integer'Image(S(3)) & " ) ");
|
||||
end Print_A_Set;
|
||||
procedure PS is new Set_Puzzle.Find_Sets(Print_A_Set);
|
||||
begin
|
||||
PS(C);
|
||||
TIO.New_Line;
|
||||
end Print_Sets;
|
||||
|
||||
begin
|
||||
loop -- deal random cards
|
||||
Set_Puzzle.Deal_Cards(Cards);
|
||||
exit when Cnt_Sets(Cards) = Required_Sets;
|
||||
end loop; -- until number of sets is as required
|
||||
|
||||
for I in Cards'Range loop -- print the cards
|
||||
if I < 10 then
|
||||
TIO.Put(" ");
|
||||
end if;
|
||||
TIO.Put_Line(Integer'Image(I) & " " & Set_Puzzle.To_String(Cards(I)));
|
||||
end loop;
|
||||
|
||||
Print_Sets(Cards); -- print the sets
|
||||
end Puzzle;
|
||||
|
|
@ -1,12 +1,12 @@
|
|||
import std.stdio, std.random, std.array, std.conv, std.traits,
|
||||
std.exception;
|
||||
std.exception, std.range, std.algorithm;
|
||||
|
||||
const class SetDealer {
|
||||
protected {
|
||||
enum Color : ubyte {green, purple, red}
|
||||
enum Number : ubyte {one, two, three}
|
||||
enum Symbol : ubyte {oval, diamond, squiggle}
|
||||
enum Fill : ubyte {open, striped, solid}
|
||||
enum Color: ubyte {green, purple, red}
|
||||
enum Number: ubyte {one, two, three}
|
||||
enum Symbol: ubyte {oval, diamond, squiggle}
|
||||
enum Fill: ubyte {open, striped, solid}
|
||||
|
||||
static struct Card {
|
||||
Color c;
|
||||
|
|
@ -15,40 +15,33 @@ const class SetDealer {
|
|||
Fill f;
|
||||
}
|
||||
|
||||
immutable Card[81] deck;
|
||||
static immutable Card[81] deck;
|
||||
}
|
||||
|
||||
this() pure nothrow {
|
||||
Card[] tmpdeck;
|
||||
|
||||
static this() pure nothrow @safe {
|
||||
immutable colors = [EnumMembers!Color];
|
||||
immutable numbers = [EnumMembers!Number];
|
||||
immutable symbols = [EnumMembers!Symbol];
|
||||
immutable fill = [EnumMembers!Fill];
|
||||
|
||||
foreach (immutable i; 0 .. deck.length)
|
||||
tmpdeck ~= Card(colors[i / 27],
|
||||
numbers[(i / 9) % 3],
|
||||
symbols[(i / 3) % 3],
|
||||
fill[i % 3]);
|
||||
|
||||
// randomShuffle(tmpdeck); /* not pure nothrow */
|
||||
|
||||
deck = assumeUnique(tmpdeck);
|
||||
deck = deck.length.iota.map!(i => Card(colors[i / 27],
|
||||
numbers[(i / 9) % 3],
|
||||
symbols[(i / 3) % 3],
|
||||
fill[i % 3])).array;
|
||||
}
|
||||
|
||||
// randomSample produces a sorted output that's convenient in our
|
||||
// case because we're printing to stout. Normally you would want
|
||||
// to shuffle.
|
||||
immutable(Card)[] deal(in uint numCards) const {
|
||||
enforce(numCards < deck.length, "number of cards too large");
|
||||
return deck[].randomSample(numCards).array();
|
||||
enforce(numCards < deck.length, "Number of cards too large");
|
||||
return deck[].randomSample(numCards).array;
|
||||
}
|
||||
|
||||
// The summed enums of valid sets are always zero or a multiple
|
||||
// of 3.
|
||||
bool validSet(in ref Card c1, in ref Card c2, in ref Card c3)
|
||||
const pure nothrow {
|
||||
const pure nothrow @safe @nogc {
|
||||
return !((c1.c + c2.c + c3.c) % 3 ||
|
||||
(c1.n + c2.n + c3.n) % 3 ||
|
||||
(c1.s + c2.s + c3.s) % 3 ||
|
||||
|
|
@ -56,7 +49,7 @@ const class SetDealer {
|
|||
}
|
||||
|
||||
immutable(Card)[3][] findSets(in Card[] cards, in uint target = 0)
|
||||
const pure nothrow {
|
||||
const pure nothrow @safe {
|
||||
immutable len = cards.length;
|
||||
if (len < 3)
|
||||
return null;
|
||||
|
|
@ -90,19 +83,14 @@ const final class SetPuzzleDealer : SetDealer {
|
|||
}
|
||||
|
||||
void main() {
|
||||
const dealer = new SetPuzzleDealer();
|
||||
const cards = dealer.deal();
|
||||
const dealer = new SetPuzzleDealer;
|
||||
const cards = dealer.deal;
|
||||
|
||||
writefln("\nDEALT %d CARDS:\n", cards.length);
|
||||
foreach (c; cards)
|
||||
writeln(cast()c);
|
||||
writefln("DEALT %d CARDS:", cards.length);
|
||||
writefln("%(%s\n%)", cards);
|
||||
|
||||
immutable sets = dealer.findSets(cards);
|
||||
immutable len = sets.length;
|
||||
writefln("\nFOUND %d %s:\n", len, len == 1 ? "SET" : "SETS");
|
||||
foreach (set; sets) {
|
||||
foreach (c; set)
|
||||
writeln(cast()c);
|
||||
writeln();
|
||||
}
|
||||
writefln("\nFOUND %d SET%s:", len, len == 1 ? "" : "S");
|
||||
writefln("%(%(%s\n%)\n\n%)", sets);
|
||||
}
|
||||
19
Task/Set-puzzle/D/set-puzzle-2.d
Normal file
19
Task/Set-puzzle/D/set-puzzle-2.d
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
void main() {
|
||||
import std.stdio, std.algorithm, std.range, std.random, combinations3;
|
||||
|
||||
enum nDraw = 9, nGoal = nDraw / 2;
|
||||
auto deck = cartesianProduct("red green purple".split,
|
||||
"one two three".split,
|
||||
"oval squiggle diamond".split,
|
||||
"solid open striped".split).array;
|
||||
|
||||
retry:
|
||||
auto draw = deck.randomSample(nDraw).map!(t => [t[]]).array;
|
||||
const sets = draw.combinations(3).filter!(cs => cs.dup
|
||||
.transposed.all!(t => t.array.sort().uniq.count % 2)).array;
|
||||
if (sets.length != nGoal)
|
||||
goto retry;
|
||||
|
||||
writefln("Dealt %d cards:\n%(%-(%8s %)\n%)\n", draw.length, draw);
|
||||
writefln("Containing:\n%(%(%-(%8s %)\n%)\n\n%)", sets);
|
||||
}
|
||||
|
|
@ -6,11 +6,11 @@ import (
|
|||
"time"
|
||||
)
|
||||
|
||||
var (
|
||||
number = []string{"1", "2", "3"}
|
||||
color = []string{"red", "green", "purple"}
|
||||
shade = []string{"solid", "open", "striped"}
|
||||
shape = []string{"oval", "squiggle", "diamond"}
|
||||
const (
|
||||
number = [3]string{"1", "2", "3"}
|
||||
color = [3]string{"red", "green", "purple"}
|
||||
shade = [3]string{"solid", "open", "striped"}
|
||||
shape = [3]string{"oval", "squiggle", "diamond"}
|
||||
)
|
||||
|
||||
type card int
|
||||
|
|
@ -25,15 +25,7 @@ func (c card) String() string {
|
|||
|
||||
func main() {
|
||||
rand.Seed(time.Now().Unix())
|
||||
basic()
|
||||
advanced()
|
||||
}
|
||||
|
||||
func basic() {
|
||||
game("Basic", 9, 4)
|
||||
}
|
||||
|
||||
func advanced() {
|
||||
game("Advanced", 12, 6)
|
||||
}
|
||||
|
||||
|
|
@ -59,7 +51,7 @@ func game(level string, cards, sets int) {
|
|||
l3:
|
||||
for _, c3 := range d[:j] {
|
||||
for f := card(1); f < 81; f *= 3 {
|
||||
if (c1/f%3+c2/f%3+c3/f%3)%3 != 0 {
|
||||
if (c1/f%3 + c2/f%3 + c3/f%3) % 3 != 0 {
|
||||
continue l3 // not a set
|
||||
}
|
||||
}
|
||||
|
|
@ -77,9 +69,6 @@ func game(level string, cards, sets int) {
|
|||
}
|
||||
fmt.Println("Sets:")
|
||||
for _, s := range found {
|
||||
fmt.Println(" ", s[0])
|
||||
fmt.Println(" ", s[1])
|
||||
fmt.Println(" ", s[2])
|
||||
fmt.Println()
|
||||
fmt.Printf(" %s\n %s\n %s\n",s[0],s[1],s[2])
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
import java.util.*;
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
|
||||
public class SetPuzzle {
|
||||
|
||||
enum Color {
|
||||
|
||||
GREEN(0), PURPLE(1), RED(2);
|
||||
|
||||
private Color(int v) {
|
||||
|
|
@ -13,6 +13,7 @@ public class SetPuzzle {
|
|||
}
|
||||
|
||||
enum Number {
|
||||
|
||||
ONE(0), TWO(1), THREE(2);
|
||||
|
||||
private Number(int v) {
|
||||
|
|
@ -22,6 +23,7 @@ public class SetPuzzle {
|
|||
}
|
||||
|
||||
enum Symbol {
|
||||
|
||||
OVAL(0), DIAMOND(1), SQUIGGLE(2);
|
||||
|
||||
private Symbol(int v) {
|
||||
|
|
@ -31,6 +33,7 @@ public class SetPuzzle {
|
|||
}
|
||||
|
||||
enum Fill {
|
||||
|
||||
OPEN(0), STRIPED(1), SOLID(2);
|
||||
|
||||
private Fill(int v) {
|
||||
|
|
@ -40,20 +43,22 @@ public class SetPuzzle {
|
|||
}
|
||||
|
||||
private static class Card implements Comparable<Card> {
|
||||
|
||||
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) {
|
||||
|
|
@ -79,7 +84,7 @@ public class SetPuzzle {
|
|||
int cnt;
|
||||
do {
|
||||
Collections.shuffle(Arrays.asList(deck));
|
||||
cards = ArrayUtils.subarray(deck, 0, numCards);
|
||||
cards = Arrays.copyOfRange(deck, 0, numCards);
|
||||
cnt = 0;
|
||||
|
||||
outer:
|
||||
|
|
|
|||
18
Task/Set-puzzle/Mathematica/set-puzzle.math
Normal file
18
Task/Set-puzzle/Mathematica/set-puzzle.math
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
colors = {Red, Green, Purple};
|
||||
symbols = {"0", "\[TildeTilde]", "\[Diamond]"};
|
||||
numbers = {1, 2, 3};
|
||||
shadings = {"\[FilledSquare]", "\[Square]", "\[DoublePrime]"};
|
||||
|
||||
validTripleQ[l_List] := Entropy[l] != Entropy[{1, 1, 2}];
|
||||
validSetQ[cards_List] := And @@ (validTripleQ /@ Transpose[cards]);
|
||||
|
||||
allCards = Tuples[{colors, symbols, numbers, shadings}];
|
||||
|
||||
deal[{numDeal_, setNum_}] := Module[{cards, count = 0},
|
||||
While[count != setNum,
|
||||
cards = RandomSample[allCards, numDeal];
|
||||
count = Count[Subsets[cards, {3}], _?validSetQ]];
|
||||
|
||||
cards];
|
||||
|
||||
Row[{Style[#2, #1], #3, #4}] & @@@ deal[{9, 4}]
|
||||
21
Task/Set-puzzle/Python/set-puzzle-2.py
Normal file
21
Task/Set-puzzle/Python/set-puzzle-2.py
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
import random, pprint
|
||||
from itertools import product, combinations
|
||||
|
||||
N_DRAW = 9
|
||||
N_GOAL = N_DRAW // 2
|
||||
|
||||
deck = list(product("red green purple".split(),
|
||||
"one two three".split(),
|
||||
"oval squiggle diamond".split(),
|
||||
"solid open striped".split()))
|
||||
|
||||
sets = []
|
||||
while len(sets) != N_GOAL:
|
||||
draw = random.sample(deck, N_DRAW)
|
||||
sets = [cs for cs in combinations(draw, 3)
|
||||
if all(len(set(t)) in [1, 3] for t in zip(*cs))]
|
||||
|
||||
print "Dealt %d cards:" % len(draw)
|
||||
pprint.pprint(draw)
|
||||
print "\nContaining %d sets:" % len(sets)
|
||||
pprint.pprint(sets)
|
||||
99
Task/Set-puzzle/REXX/set-puzzle.rexx
Normal file
99
Task/Set-puzzle/REXX/set-puzzle.rexx
Normal file
|
|
@ -0,0 +1,99 @@
|
|||
/*REXX program finds "sets" (solutions) for the SET puzzle (game). */
|
||||
parse arg game seed . /*get optional # cards to deal. */
|
||||
if game ==',' | game=='' then game=9 /*Not specified? Then use default*/
|
||||
if seed==',' | seed=='' then seed=77 /* " " " " " */
|
||||
call aGame 0 /*with tell=0, suppress output. */
|
||||
call aGame 1 /*with tell=1, allow output. */
|
||||
exit sets /*stick a fork in it, we're done.*/
|
||||
/*──────────────────────────────────AGAME subroutine────────────────────*/
|
||||
aGame: tell=arg(1); good=game%2 /*enable or disable the output. */
|
||||
/* [↑] GOOD is the right # sets.*/
|
||||
do seed=seed until good==sets /*generate deals until good# sets*/
|
||||
call random ,,seed /*repeatability for last invoke. */
|
||||
call genFeatures /*generate various card features.*/
|
||||
call genDeck /*generate a deck (with 81 cards)*/
|
||||
call dealer game /*deal a number of cards (game). */
|
||||
call findSets game%2 /*find sets from the dealt cards.*/
|
||||
end /*until*/ /*when leaving, SETS is right num*/
|
||||
return /*return to invoker of this sub. */
|
||||
/*──────────────────────────────────DEALER subroutine───────────────────*/
|
||||
dealer: call sey 'dealing' game "cards:",,. /*shuffle and deal cards*/
|
||||
do cards=1 until cards==game /*keep dealing 'til done*/
|
||||
_=random(1,words(##)); ##=delword(##,_,1) /*pick card; delete it. */
|
||||
@.cards=deck._ /*add it to the tableau.*/
|
||||
call sey right('card' cards,30) " " @.cards /*display card to screen*/
|
||||
do j=1 for words(@.cards) /*define cells for card.*/
|
||||
@.cards.j=word(@.cards,j) /*define a cell for card*/
|
||||
end /*j*/
|
||||
end /*cards*/
|
||||
return
|
||||
/*──────────────────────────────────DEFFEATURES subroutine──────────────*/
|
||||
defFeatures: parse arg what,v; _=words(v) /*obtain what to define.*/
|
||||
if _\==values then do; call sey 'error,' what "features ¬=" values,.,.
|
||||
exit -1
|
||||
end /* [↑] check for typos.*/
|
||||
do k=1 for words(values) /*define all possibles. */
|
||||
call value what'.'k, word(values,k) /*define a card feature.*/
|
||||
end /*k*/
|
||||
return
|
||||
/*──────────────────────────────────GENDECK subroutine──────────────────*/
|
||||
genDeck: #=0; ##= /*#cards in deck; ##=shuffle aid.*/
|
||||
do num=1 for values; xnum=word(numbers, num)
|
||||
do col=1 for values; xcol=word(colors, col)
|
||||
do sym=1 for values; xsym=word(symbols, sym)
|
||||
do sha=1 for values; xsha=word(shadings, sha)
|
||||
#=#+1; ##=## #; deck.#=xnum xcol xsym xsha /*create a card.*/
|
||||
end /*sha*/
|
||||
end /*num*/
|
||||
end /*sym*/
|
||||
end /*col*/
|
||||
return /*#: the number of cards in deck.*/
|
||||
/*──────────────────────────────────GENFEATURES subroutine──────────────*/
|
||||
genFeatures: features=3; groups=4; values=3 /*define # feats,grps,vals*/
|
||||
numbers = 'one two three' ; call defFeatures 'number', numbers
|
||||
colors = 'red green purple' ; call defFeatures 'color', colors
|
||||
symbols = 'oval squiggle diamond' ; call defFeatures 'symbol', symbols
|
||||
shadings= 'solid open striped' ; call defFeatures 'shading', shadings
|
||||
return
|
||||
/*──────────────────────────────────GENPOSS subroutine──────────────────*/
|
||||
genPoss: p=0; sets=0; sep=' ───── '; !.= /*define some REXX variables.*/
|
||||
do i=1 for game /* [↓] the IFs eliminate dups.*/
|
||||
do j=i+1 to game; if j==i then iterate
|
||||
do k=j+1 to game; if k==j | k==i then iterate
|
||||
p=p+1; !.p.1=@.i; !.p.2=@.j; !.p.3=@.k
|
||||
end /*k*/
|
||||
end /*j*/
|
||||
end /*i*/ /* [↑] build permutation list. */
|
||||
return
|
||||
/*──────────────────────────────────FINDSETS subroutine─────────────────*/
|
||||
findSets: parse arg n; call genPoss /*N: the number of sets to find.*/
|
||||
call sey /*find any sets generated above. */
|
||||
do j=1 for p /*P is the # of possible sets. */
|
||||
do f=1 for features
|
||||
do g=1 for groups; !!.j.f.g=word(!.j.f, g)
|
||||
end /*g*/
|
||||
end /*f*/
|
||||
ok=1 /*everything is OK so far. */
|
||||
do g=1 for groups; _=!!.j.1.g /*generate strings to hole poss. */
|
||||
equ=1 /* [↓] handles all equal feats. */
|
||||
do f=2 to features while equ; equ=equ & _==!!.j.f.g
|
||||
end /*f*/
|
||||
dif=1
|
||||
__=!!.j.1.g /* [↓] handles all unequal feats*/
|
||||
do f=2 to features while \equ
|
||||
dif=dif & wordpos(!!.j.f.g,__)==0
|
||||
__=__ !!.j.f.g /*append to string for next test.*/
|
||||
end /*f*/
|
||||
ok=ok&(equ|dif) /*now, see if all equal | unequal*/
|
||||
end /*g*/
|
||||
|
||||
if \ok then iterate /*Is this set OK? Nope, skip it.*/
|
||||
sets=sets+1 /*bump the number of sets found. */
|
||||
call sey right('set' sets": ",15) !.j.1 sep !.j.2 sep !.j.3
|
||||
end /*j*/
|
||||
|
||||
call sey sets 'sets found.',.
|
||||
return
|
||||
/*──────────────────────────────────SEY subroutine──────────────────────*/
|
||||
sey: if \tell then return /*should output be suppressed? */
|
||||
if arg(2)==. then say; say arg(1); if arg(3)==. then say; return
|
||||
Loading…
Add table
Add a link
Reference in a new issue