March 2014 update
This commit is contained in:
parent
09687c4926
commit
a25938f123
1846 changed files with 21876 additions and 5203 deletions
104
Task/Set-puzzle/AutoHotkey/set-puzzle.ahk
Normal file
104
Task/Set-puzzle/AutoHotkey/set-puzzle.ahk
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
; Generate deck; card encoding from Perl6
|
||||
Loop, 81
|
||||
deck .= ToBase(A_Index-1, 3)+1111 ","
|
||||
deck := RegExReplace(deck, "3", "4")
|
||||
|
||||
; Shuffle
|
||||
deck := shuffle(deck)
|
||||
|
||||
msgbox % clipboard := allValidSets(9, 4, deck)
|
||||
msgbox % clipboard := allValidSets(12, 6, deck)
|
||||
|
||||
; Render a hand (or any list) of cards
|
||||
PrettyHand(hand) {
|
||||
Color1:="red",Color2:="green",Color4:="purple"
|
||||
,Symbl1:="oval",Symbl2:="squiggle",Symbl4:="diamond"
|
||||
,Numbr1:="one",Numbr2:="two",Numbr4:="three"
|
||||
,Shape1:="solid",Shape2:="open",Shape4:="striped"
|
||||
Loop, Parse, hand, `,
|
||||
{
|
||||
StringSplit, i, A_LoopField
|
||||
s .= "`t" Color%i1% "`t" Symbl%i2% "`t" Numbr%i3% "`t" Shape%i4% "`n"
|
||||
}
|
||||
Return s
|
||||
}
|
||||
|
||||
; Get all unique valid sets of three cards in a hand.
|
||||
allValidSets(n, m, deck) {
|
||||
While j != m
|
||||
{
|
||||
j := 0
|
||||
,hand := draw(n, deck)
|
||||
,s := "Dealt " n " cards:`n" . prettyhand(hand)
|
||||
StringSplit, set, hand, `,
|
||||
comb := comb(n,3)
|
||||
Loop, Parse, comb, `n
|
||||
{
|
||||
StringSplit, i, A_LoopField, %A_Space%
|
||||
If isValidSet(set%i1%, set%i2%, set%i3%)
|
||||
s .= "`nSet " ++j ":`n" . prettyhand(set%i1% "," set%i2% "," set%i3%)
|
||||
}
|
||||
}
|
||||
Return s
|
||||
}
|
||||
|
||||
; Convert n to arbitrary base using recursion
|
||||
toBase(n,b) { ; n >= 0, 1 < b < StrLen(t), t = digits
|
||||
Static t := "0123456789ABCDEF"
|
||||
Return (n < b ? "" : ToBase(n//b,b)) . SubStr(t,mod(n,b)+1,1)
|
||||
}
|
||||
|
||||
; Knuth shuffle from http://rosettacode.org/wiki/Knuth_Shuffle#AutoHotkey
|
||||
shuffle(list) { ; shuffle comma separated list, converted to array
|
||||
StringSplit a, list, `, ; make array (length = a0)
|
||||
Loop % a0-1 {
|
||||
Random i, A_Index, a0 ; swap item 1,2... with a random item to the right of it
|
||||
t := a%i%, a%i% := a%A_Index%, a%A_Index% := t
|
||||
}
|
||||
Loop % a0 ; construct string from sorted array
|
||||
s .= "," . a%A_Index%
|
||||
Return SubStr(s,2) ; drop leading comma
|
||||
}
|
||||
|
||||
; Randomly pick a hand of cards from the deck
|
||||
draw(n, deck) {
|
||||
Loop, % n
|
||||
{
|
||||
Random, i, 1, 81
|
||||
cards := deck
|
||||
Loop, Parse, cards, `,
|
||||
(A_Index = i) ? (hand .= A_LoopField ",") : (cards .= A_LoopField ",")
|
||||
deck := cards
|
||||
}
|
||||
Return SubStr(hand, 1, -1)
|
||||
}
|
||||
|
||||
; Test if a particular group of three cards is a valid set
|
||||
isValidSet(a, b, c) {
|
||||
StringSplit, a, a
|
||||
StringSplit, b, b
|
||||
StringSplit, c, c
|
||||
Return !((a1|b1|c1 ~= "[3,5,6]") + (a2|b2|c2 ~= "[3,5,6]") + (a3|b3|c3 ~= "[3,5,6]") + (a4|b4|c4 ~= "[3,5,6]"))
|
||||
}
|
||||
|
||||
; Get all combinations, from http://rosettacode.org/wiki/Combinations#AutoHotkey
|
||||
comb(n,t) { ; Generate all n choose t combinations of 1..n, lexicographically
|
||||
IfLess n,%t%, Return
|
||||
Loop %t%
|
||||
c%A_Index% := A_Index
|
||||
i := t+1, c%i% := n+1
|
||||
|
||||
Loop {
|
||||
Loop %t%
|
||||
i := t+1-A_Index, c .= c%i% " "
|
||||
c .= "`n" ; combinations in new lines
|
||||
j := 1, i := 2
|
||||
Loop
|
||||
If (c%j%+1 = c%i%)
|
||||
c%j% := j, ++j, ++i
|
||||
Else Break
|
||||
If (j > t)
|
||||
Return c
|
||||
c%j% += 1
|
||||
}
|
||||
}
|
||||
|
|
@ -6,7 +6,10 @@ enum Style (solid => 0o1, open => 0o2, striped => 0o4);
|
|||
my @deck := (Color.enums X Count.enums X Shape.enums X Style.enums).tree;
|
||||
|
||||
sub MAIN($DRAW = 9, $GOAL = $DRAW div 2) {
|
||||
my @combinations = combine(3, [^$DRAW]);
|
||||
sub show-cards(@c) { printf " %-6s %-5s %-8s %s\n", $_».key for @c }
|
||||
|
||||
my @combinations = [^$DRAW].combinations(3);
|
||||
|
||||
my @draw;
|
||||
repeat until (my @sets) == $GOAL {
|
||||
@draw = @deck.pick($DRAW);
|
||||
|
|
@ -15,6 +18,7 @@ sub MAIN($DRAW = 9, $GOAL = $DRAW div 2) {
|
|||
take @draw[@c].item when /^ <[1247]>+ $/ given ( [+|] @bits[@c] ).base(8);
|
||||
}
|
||||
}
|
||||
|
||||
say "Drew $DRAW cards:";
|
||||
show-cards @draw;
|
||||
for @sets.kv -> $i, @cards {
|
||||
|
|
@ -22,5 +26,3 @@ sub MAIN($DRAW = 9, $GOAL = $DRAW div 2) {
|
|||
show-cards @cards;
|
||||
}
|
||||
}
|
||||
|
||||
sub show-cards(@c) { for @c -> $c { printf " %-6s %-5s %-8s %s\n", $c».key } }
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue