Data commit

This commit is contained in:
Ingy döt Net 2023-07-01 11:58:00 -04:00
parent 7387c8f97b
commit cb5bb5e222
199093 changed files with 3378972 additions and 0 deletions

View file

@ -0,0 +1,96 @@
import std.stdio, std.random, std.array, std.conv, std.traits,
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}
static struct Card {
Color c;
Number n;
Symbol s;
Fill f;
}
static immutable Card[81] deck;
}
static this() pure nothrow @safe {
immutable colors = [EnumMembers!Color];
immutable numbers = [EnumMembers!Number];
immutable symbols = [EnumMembers!Symbol];
immutable fill = [EnumMembers!Fill];
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;
}
// 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 @safe @nogc {
return !((c1.c + c2.c + c3.c) % 3 ||
(c1.n + c2.n + c3.n) % 3 ||
(c1.s + c2.s + c3.s) % 3 ||
(c1.f + c2.f + c3.f) % 3);
}
immutable(Card)[3][] findSets(in Card[] cards, in uint target = 0)
const pure nothrow @safe {
immutable len = cards.length;
if (len < 3)
return null;
typeof(return) sets;
foreach (immutable i; 0 .. len - 2)
foreach (immutable j; i + 1 .. len - 1)
foreach (immutable k; j + 1 .. len)
if (validSet(cards[i], cards[j], cards[k])) {
sets ~= [cards[i], cards[j], cards[k]];
if (target != 0 && sets.length > target)
return null;
}
return sets;
}
}
const final class SetPuzzleDealer : SetDealer {
enum {basic = 9, advanced = 12}
override immutable(Card)[] deal(in uint numCards = basic) const {
immutable numSets = numCards / 2;
typeof(return) cards;
do {
cards = super.deal(numCards);
} while (findSets(cards, numSets).length != numSets);
return cards;
}
}
void main() {
const dealer = new SetPuzzleDealer;
const cards = dealer.deal;
writefln("DEALT %d CARDS:", cards.length);
writefln("%(%s\n%)", cards);
immutable sets = dealer.findSets(cards);
immutable len = sets.length;
writefln("\nFOUND %d SET%s:", len, len == 1 ? "" : "S");
writefln("%(%(%s\n%)\n\n%)", sets);
}

View 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);
}