3 # Brute force proof that every cribbage hand with a 5 is >= 2 points
4 # See http://perlmonks.org/index.pl?node_id=458728 for details
6 # The following code will not work yet as of revision 4167
7 # There are two bugs and two unimplemented features
8 # Bug 1 - t/pugsbugs/return_with_trailing_stuff.t
9 # Bug 2 - t/pugsbugs/postincrement_in_subscripts.t
10 # Feature 1 - t/operators/hyper.t (hyper dereferencing)
11 # Feature 2 - t/statements/last.t (last <label>)
14 my $next = combo
(5, new_deck
());
16 # Skip all hands that do not contain a 5
17 # next if none( @combo.>>.<val> ) == 5;
19 # Skip all hands that have a score of at least 2
20 # next if score( @combo ) > 1;
23 # say ~@combo.>>.<suit>;
26 sub score
( @hand ) returns Int
{
31 for @hand.>>.<num
> { %ordval{$_}++ };
32 for %ordval.values { $score += $_ * $_ - 1 }
35 $score += ([eq] @hand[0..3].>>.<suit
>)
36 ??
([eq] @hand[3,4].>>.<suit
>) ??
5 !! 4
39 # Check for right-jack, @hand[*-1] is community card
40 $score++ if grep { $_<num
> == 11 && $_<suit
> eq @hand[*-1]<suit
> }, @hand[0..3];
43 my @vals = @hand>>.<val
>;
45 my $next = combo
($_, @vals);
46 while my @combo = $next() { $score += 2 if ([+] @combo) == 15 }
51 for 5, 4, 3 -> $span {
52 for (sort { $^a
<=> $^b
}, %ordval.keys) -> $start {
53 if all
( %ordval{$start .. $start + $span} ) > 1 {
54 $score += [*] %ordval{$start .. $start + $span}, $span;
62 sub combo
(Int
$by is copy
, @list is copy
) {
63 my @position = 0 .. $by - 2, $by - 2;
64 my @stop = @list.elems
- $by .. @list.end
;
68 my $cur = @position.end
;
69 while ++@position[ $cur ] > @stop[ $cur ] {
70 @position[ --$cur ]++;
71 next if @position[ $cur ] > @stop[ $cur ];
72 my $new_pos = @position[ $cur ];
73 @position[ $cur .. @position.end
] = $new_pos .. $new_pos + $by;
76 $done = 1 if @position[ 0 ] == @stop[ 0 ];
77 return @list[ @position ];
81 sub new_deck
() returns Array
{
82 return (1..13).map: -> $num {
83 <H D C S
>.map: -> $suit {
84 { num
=> $num, val
=> $num > 10 ??
10 !! $num, suit
=> $suit };