September 2017 Update

This commit is contained in:
Ingy döt Net 2017-09-23 10:01:46 +02:00
parent bba7bfd280
commit ba8067c3b7
14570 changed files with 153136 additions and 63871 deletions

View file

@ -0,0 +1,140 @@
import ceylon.random {
Random,
DefaultRandom
}
abstract class Feature() of Color | Symbol | NumberOfSymbols | Shading {}
abstract class Color()
of red | green | purple
extends Feature() {}
object red extends Color() {
string => "red";
}
object green extends Color() {
string => "green";
}
object purple extends Color() {
string => "purple";
}
abstract class Symbol()
of oval | squiggle | diamond
extends Feature() {}
object oval extends Symbol() {
string => "oval";
}
object squiggle extends Symbol() {
string => "squiggle";
}
object diamond extends Symbol() {
string => "diamond";
}
abstract class NumberOfSymbols()
of one | two | three
extends Feature() {}
object one extends NumberOfSymbols() {
string => "one";
}
object two extends NumberOfSymbols() {
string => "two";
}
object three extends NumberOfSymbols() {
string => "three";
}
abstract class Shading()
of solid | open | striped
extends Feature() {}
object solid extends Shading() {
string => "solid";
}
object open extends Shading() {
string => "open";
}
object striped extends Shading() {
string => "striped";
}
class Card(color, symbol, number, shading) {
shared Color color;
shared Symbol symbol;
shared NumberOfSymbols number;
shared Shading shading;
value plural => number == one then "" else "s";
string => "``number`` ``shading`` ``color`` ``symbol````plural``";
}
{Card*} deck = {
for(color in `Color`.caseValues)
for(symbol in `Symbol`.caseValues)
for(number in `NumberOfSymbols`.caseValues)
for(shading in `Shading`.caseValues)
Card(color, symbol, number, shading)
};
alias CardSet => [Card+];
Boolean validSet(CardSet cards) {
function allOrOne({Feature*} features) =>
let(uniques = features.distinct.size)
uniques == 3 || uniques == 1;
return allOrOne(cards*.color) &&
allOrOne(cards*.number) &&
allOrOne(cards*.shading) &&
allOrOne(cards*.symbol);
}
{CardSet*} findSets(Card* cards) =>
cards
.sequence()
.combinations(3)
.filter(validSet);
Random random = DefaultRandom();
class Mode of basic | advanced {
shared Integer numberOfCards;
shared Integer numberOfSets;
shared new basic {
numberOfCards = 9;
numberOfSets = 4;
}
shared new advanced {
numberOfCards = 12;
numberOfSets = 6;
}
}
[{Card*}, {CardSet*}] deal(Mode mode) {
value randomStream = random.elements(deck);
while(true) {
value cards = randomStream.distinct.take(mode.numberOfCards).sequence();
value sets = findSets(*cards);
if(sets.size == mode.numberOfSets) {
return [cards, sets];
}
}
}
shared void run() {
value [cards, sets] = deal(Mode.basic);
print("The cards dealt are:
");
cards.each(print);
print("
Containing the sets:
");
for(cardSet in sets) {
cardSet.each(print);
print("");
}
}

View file

@ -0,0 +1,89 @@
// version 1.1.3
import java.util.Collections.shuffle
enum class Color { RED, GREEN, PURPLE }
enum class Symbol { OVAL, SQUIGGLE, DIAMOND }
enum class Number { ONE, TWO, THREE }
enum class Shading { SOLID, OPEN, STRIPED }
enum class Degree { BASIC, ADVANCED }
class Card(
val color: Color,
val symbol: Symbol,
val number: Number,
val shading: Shading
) : Comparable<Card> {
private val value =
color.ordinal * 27 + symbol.ordinal * 9 + number.ordinal * 3 + shading.ordinal
override fun compareTo(other: Card) = value.compareTo(other.value)
override fun toString() = (
color.name.padEnd(8) +
symbol.name.padEnd(10) +
number.name.padEnd(7) +
shading.name.padEnd(7)
).toLowerCase()
companion object {
val zero = Card(Color.RED, Symbol.OVAL, Number.ONE, Shading.SOLID)
}
}
fun createDeck() =
List<Card>(81) {
val col = Color.values() [it / 27]
val sym = Symbol.values() [it / 9 % 3]
val num = Number.values() [it / 3 % 3]
val shd = Shading.values()[it % 3]
Card(col, sym, num, shd)
}
fun playGame(degree: Degree) {
val deck = createDeck()
val nCards = if (degree == Degree.BASIC) 9 else 12
val nSets = nCards / 2
val sets = Array(nSets) { Array(3) { Card.zero } }
var hand: Array<Card>
outer@ while (true) {
shuffle(deck)
hand = deck.take(nCards).toTypedArray()
var count = 0
for (i in 0 until hand.size - 2) {
for (j in i + 1 until hand.size - 1) {
for (k in j + 1 until hand.size) {
val trio = arrayOf(hand[i], hand[j], hand[k])
if (isSet(trio)) {
sets[count++] = trio
if (count == nSets) break@outer
}
}
}
}
}
hand.sort()
println("DEALT $nCards CARDS:\n")
println(hand.joinToString("\n"))
println("\nCONTAINING $nSets SETS:\n")
for (s in sets) {
s.sort()
println(s.joinToString("\n"))
println()
}
}
fun isSet(trio: Array<Card>): Boolean {
val r1 = trio.sumBy { it.color.ordinal } % 3
val r2 = trio.sumBy { it.symbol.ordinal } % 3
val r3 = trio.sumBy { it.number.ordinal } % 3
val r4 = trio.sumBy { it.shading.ordinal } % 3
return (r1 + r2 + r3 + r4) == 0
}
fun main(args: Array<String>) {
playGame(Degree.BASIC)
println()
playGame(Degree.ADVANCED)
}

View file

@ -3,10 +3,10 @@ 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).tree;
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 " %-6s %-5s %-8s %s\n", $_».key for @c }
sub show-cards(@c) { { printf "%9s%7s%10s%9s\n", @c[$_;*]».key } for ^@c }
my @combinations = [^$DRAW].combinations(3);

View file

@ -0,0 +1,66 @@
function comb(sequence pool, integer needed, sequence res={}, integer done=0, sequence chosen={})
if needed=0 then -- got a full set
sequence {a,b,c} = chosen
if not find_any({3,5,6},flatten(sq_or_bits(sq_or_bits(a,b),c))) then
res = append(res,chosen)
end if
elsif done+needed<=length(pool) then
-- get all combinations with and without the next item:
done += 1
res = comb(pool,needed-1,res,done,append(chosen,pool[done]))
res = comb(pool,needed,res,done,chosen)
end if
return res
end function
constant m124 = {1,2,4}
function card(integer n)
--returns the nth card (n is 1..81, res is length 4 of 1/2/4)
n -= 1
sequence res = repeat(0,4)
for i=1 to 4 do
res[i] = m124[remainder(n,3)+1]
n = floor(n/3)
end for
return res
end function
constant colours = {"red", "green", 0, "purple"},
symbols = {"oval", "squiggle", 0, "diamond"},
numbers = {"one", "two", 0, "three"},
shades = {"solid", "open", 0, "striped"}
procedure print_cards(sequence hand, sequence cards)
for i=1 to length(cards) do
integer {c,m,n,g} = cards[i],
id = find(cards[i],hand)
printf(1,"%3d: %-7s %-9s %-6s %s\n",{id,colours[c],symbols[m],numbers[n],shades[g]})
end for
printf(1,"\n")
end procedure
procedure play(integer cards=9, integer sets=4)
integer deals = 1
while 1 do
sequence deck = shuffle(tagset(81))
sequence hand = deck[1..cards]
for i=1 to length(hand) do
hand[i] = card(hand[i])
end for
sequence res = comb(hand,3)
if length(res)=sets then
printf(1,"dealt %d cards (%d deals)\n",{cards,deals})
print_cards(hand,hand)
printf(1,"with %d sets\n",{sets})
for i=1 to sets do
print_cards(hand,res[i])
end for
exit
end if
deals += 1
end while
end procedure
play()
--play(12,6)
--play(9,6)

View file

@ -0,0 +1,22 @@
const nDraw=9, nGoal=(nDraw/2); // Basic
var [const] UH=Utils.Helpers; // baked in stash of goodies
deck:=Walker.cproduct("red green purple".split(), // Cartesian product of 4 lists of lists
"one two three".split(), // T(1,2,3) (ie numbers) also works
"oval squiggle diamond".split(),
"solid open striped".split()).walk();
reg draw,sets,N=0;
do{ N+=1;
draw=deck.shuffle()[0,nDraw]; // one draw per shuffle
sets=UH.pickNFrom(3,draw) // 84 sets of 3 cards (each with 4 features)
.filter(fcn(set){ // list of 12 items (== 3 cards)
set[0,4].zip(set[4,4],set[8,4]) // -->4 tuples of 3 features
.pump(List,UH.listUnique,"len", // 1,3 (good) or 2 (bad)
'==(2)) // (F,F,F,F)==good
.sum(0) == 0 // all 4 feature sets good
});
}while(sets.len()!=nGoal);
println("Dealt %d cards %d times:".fmt(draw.len(),N));
draw.pump(Void,fcn(card){ println(("%8s "*4).fmt(card.xplode())) });
println("\nContaining:");
sets.pump(Void,fcn(card){ println((("%8s "*4 + "\n")*3).fmt(card.xplode())) });